从零开始搭建HTTPS服务
off999 2025-01-06 14:49 16 浏览 0 评论
搭建 HTTPS 服务的最初目的是为了开发微信小程序,因为 wx.request 只允许发起 HTTPS 请求,并且还必须和指定的域名进行网络通信。要从零开始搭建一个 HTTPS 的服务需要下面 4 个要素:域名,备案,云服务器,服务搭建。本文将分别介绍这四要素的具体要求。
简介
HTTPS (Hyper Text Transfer Protocol over SecureSocket Layer)叫超文本传输安全协议,是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。这个协议由网景公司(Netscape)在 1994 年首次提出,随后扩展到互联网上,目前基本上所有的网站都使用了 HTTPS 协议。下面就围绕域名,备案,云服务器,服务搭建这 4 个方面来从零搭建 HTTPS 服务。
域名
域名[1](Domain Name)又叫网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。例如, blog.haojunyu.com 是一个域名,可以通过域名名称系统(Domain Name System)将该域名映射成对应的 IP 地址。该操作可以通过域名解析来实现。
域名注册和解析
域名注册前,可以通过WHOIS[2] 来查询该域名是否被注册过。目前 BAT 都提供域名注册,如阿里的万网[3],百度的域名服务[4],腾讯的Dnspod[5]。我的域名 haojunyu.com 是在阿里的万网注册的,之前注册域名的初衷是为了给 github 上面的个人博客作个性化的域名。并在其中的域名解析中作了设置,这里并不需要做太多的改动,只需要添加如下图的解析记录:
设置完成后,当我们向 https://api.haojunyu.com/* 发送请求时,DNS 会自动将其解析为映射的 IP 地址(上图中涂鸦的部分),并向目标服务器请求对应服务。
备案
这里的备案是针对像个人博客这类非经营性网站所做的备案,其目的是为了方便网站的管理。因为只有守法的网站才会对促进信息共享、文化繁荣和社会进步产生积极的作用。
目前网站域名的备案 BAT 都能提供,不过备案这个流程很长,大概要一个月,我的域名 haojunyu.com 是在百度云备案的,当时是先提交的资料(主要是身份证正反面照片),然后等百度快递来背景墙,再拍照片上传核实后才可以备案成功。
云服务器
服务器就是一台可以运行的电脑,可以是自己家里的电脑,也可以到 BAT 上买云服务。这里因为腾讯云上面有免费8天的试用,所以就试着在云服务上面搭建个 https 的服务,以方便微信小程序能成功发起 request 请求。如果试用体验还不错的话,可以续费(74元/月)。新建云主机时要选一个操作系统,鉴于对 Ubutnu 的熟悉以及服务器的需要,所以选择了 Ubuntu Server 16.04.1 LTS 64 的镜像做系统。当新建一个云主机后,百度云会提供一个对外的 IP 地址,这个 IP 地址就是域名解析中要填入的记录值。
服务搭建
服务器的配置主要有三步个,第一步是应用程序的布置,第二步是Nginx服务器的配置,第三步是 http 升级为 https 。前两步的配置是参考这篇博文在Ubuntu上使用Nginx部署Flask应用[6],第三步是参考腾讯云上Nginx证书安装[7]。
应用程序
考虑到微信小程序主要是用 json 的数据,所以就想服务器能够提供 restful 服务,又因为对 python 语言比较喜欢,所以就挑了 python 里的 Flask 这个轻量级的 Web 框架。服务器选择的是 Nginx ,而连接服务器和应用程序的是 uWSGI。具体的安装步骤如下:
1.环境配置
sudo apt-get update && sudo apt-get upgrade # 更新所有软件
sudo apt-get install build-essential # 安装编译环境
sudo apt-get install python python-dev python-setuptools # 安装python环境
sudo easy_install pip
sudo apt-get install nginx # 安装Nginx
sudo apt-get install uwsgi uwsgi-plugin-python # 安装uwsgi及其插件
sudo apt-get install supervisor # 安装进程管理软件
2.应用配置
sudo mkdir -p /var/www/flaskApp # 创建应用程序文件夹
sudo chown -R ubuntu:ubuntu /var/www/flaskApp # 更改应用程序文件夹所有权
sudo pip install virtualenv # 安装python虚拟环境
# 创建python虚拟环境
cd /var/www/flaskApp
virtualenv venv
. venv/bin/activate # 激活python虚拟环境venv
pip install flask flask-restful # 在虚拟环境中安装flask Web框架
3.创建api.py代码
#!flask/bin/python
from flask import Flask, jsonify
app = Flask(__name__)
tasks = [
{
'id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'id': 2,
'title': u'Learn Python',
'description': u'Need to find a good Python tutorial on the web',
'done': False
}
]
@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
return jsonify({'tasks': tasks})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
执行脚本python api.py后可以通过浏览器来访问 http://主机IP:8080/todo/api/v1.0/tasks,以此来获取 tasks 数据。
服务配置
Nginx配置
1.删除nginx默认配置文件
sudo rm /etc/nginx/sites-enabled/default
2.创建新的配置文件/var/www/flaskApp/config/flaskApp_nginx.conf
server {
listen 80;
server_name api.haojunyu.com; #此时域名已经映射到主机IP
charset utf-8;
client_max_body_size 75M;
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/var/www/flaskApp/config/flaskApp_uwsgi.sock;
}
}
3.创建配置文件服务,重启服务
sudo ln -s /var/www/flaskApp/config/nginx.conf /etc/nginx/conf.d/ #将应用文件夹里的配置文件链接到nginx配置文件处
sudo nginx -t # 检验nginx配置是否有误
sudo nginx -s reload # 重新加载nginx配置
sudo /etc/init.d/nginx restart # 重启nginx
4.验证
现在通过浏览器来访问 http://api.haojunyu.com/todo/api/v1.0/tasks ,无法获取到数据,因为 flaskApp_uwsgi.sock 尚未生成,无法让 uwsgi 在 Nginx 和 python 应用程序之间构建一座桥。
uWSGI配置
1.创建新的配置文件/var/www/flaskApp/config/flaskApp_uwsgi.ini
[uwsgi]
#application's base folder
base = /var/www/flaskApp
#python module to import
app = api
module = %(app)
home = %(base)/venv
pythonpath = %(base)
## 使用virtualenvwrapper管理virtualenv后用下面的两个参数取代home和pythonpath
#chdir = %(base)
#virtualenvs = %HOME/.virtualenvs/flaskEnv
#socket file's location
socket = /var/www/flaskApp/%n.sock
#permissions for the socket file
chmod-socket = 666
#the variable that holds a flask application inside the module imported at line #6
callable = app
#location of log files
logto = /var/log/uwsgi/%n.log
2.创建uWSGI日志文件夹,并更改文件所有权
sudo mkdir -p /var/log/uwsgi # uWSGI日志文件夹
sudo chown -R ubuntu:ubuntu /var/log/uwsgi # 更改uWSGI日志文件夹所有权
uwsgi --ini /var/www/flaskApp/config/flaskApp_uwsgi.ini --plugin python & # 后台启动uwsgi
supervisor配置
supervisor 是为了方便管理进程而存在的,因为每次开机后,都得重新执行 uwsgi --ini /var/www/flaskApp/config/flaskApp_uwsgi.ini 命令来启动 uwsgi ,这个很费神,因为你不可能永远记得清楚这么个应用,这么个配置。所以使用 supervisor 来管理,而我们只需要在开发这个应用时创建一个 flaskApp_supervisor.conf 配置文件,而重启机器后启动 supervisor 服务,即执行 sudo service supervisor start。
1.安装 supervisor
sudo apt install supervisor
2.创建配置文件:
[program:flaskApp]
# 启动命令入口
command=/usr/local/bin/uwsgi --ini /var/www/flaskApp/flaskApp_uwsgi.ini
# 运行命令的用户名
user=ubuntu
autostart=true
autorestat=true
#日志地址
stdout_logfile=/var/log/supervisor/flaskApp_supervisor.log
3.创建配置文件副本并重启服务
sudo ln -s /var/www/flaskApp/flaskApp_supervisor.conf /etc/supervisor/conf.d/
sudo service supervisor restart
HTTP 升级 HTTPS
升级 HTTP 需要证书的支持,这里 BAT 都提供这样的服务,都有相对应的配置安装说明。我这里是按照 腾讯云上Nginx证书安装[8],主要就是将申请的证书保存到 config 目录中,并将 flaskApp_nginx.conf 修改如下:
server {
listen 80;
server_name api.haojunyu.com;
return 301 https://api.haojunyu.com$request_uri;
}
server {
listen 443 ssl;
server_name api.haojunyu.com; #此时域名已经映射到主机IP
ssl on;
ssl_certificate /var/www/flaskApp/1_haojunyu.com_bundle.crt;
ssl_certificate_key /var/www/flaskApp/2_haojunyu.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
ssl_prefer_server_ciphers on;
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/var/www/flaskApp/config/flaskApp_uwsgi.sock;
}
}
当时 SSL 的证书有免费的可以用,限制就是一个证书只能帮忙一个二级域名或子域名。如果愿意折腾,可以使用 certbot[9] 来自动化来配置 SSL 证书和定时更新。
详细的安装配置步骤可以参考官网(需要选择代理软件 nginx/apache 等和操作系统 Ubuntu/CentOS/MacOS 等)。
# 安装命令
sudo apt install certbot python-certbot-nginx # cerbot及其插件
# 配置域名
sudo certbot certonly --nginx --cert-name haojunyu.com -d api.haojunyu.com
# 删除配置的域名
sudo certbot delete --cert-name haojunyu.com
# 查看配置的域名
sudo certbot certificates
# 更新证书
sudo certbot renew --dry-run
最终效果如下图所示, 访问 https://api.haojunyu.com/todo/api/v1.0/tasks 可以获得对应的数据。
参考文献
1.wiki-域名[10]
2.whois域名查询[11]
3.万网[12]
4.百度域名服务[13]
5.Dnspod[14]
6.在Ubuntu上使用Nginx部署Flask应用[15]
7.腾讯云上Nginx证书安装[16]
8.certbot[17]
References
[1] 域名: https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D
[2] WHOIS: https://who.is/
[3] 万网: https://wanwang.aliyun.com/?spm=5176.8142029.388261.26.C75xLA
[4] 域名服务: https://cloud.baidu.com/product/bcd.html
[5] Dnspod: https://dnspod.qcloud.com/?from=console
[6] 在Ubuntu上使用Nginx部署Flask应用: https://www.oschina.net/translate/serving-flask-with-nginx-on-ubuntu
[7] 腾讯云上Nginx证书安装: https://www.qcloud.com/document/product/400/4143#2.-nginx-.E8.AF.81.E4.B9.A6.E9.83.A8.E7.BD.B2
[8] 腾讯云上Nginx证书安装: https://www.qcloud.com/document/product/400/4143#2.-nginx-.E8.AF.81.E4.B9.A6.E9.83.A8.E7.BD.B2
[9] certbot: https://certbot.eff.org/
[10] wiki-域名: https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D
[11] whois域名查询: https://who.is/
[12] 万网: https://wanwang.aliyun.com/?spm=5176.8142029.388261.26.C75xLA
[13] 百度域名服务: https://cloud.baidu.com/product/bcd.html
[14] Dnspod: https://dnspod.qcloud.com/?from=console
[15] 在Ubuntu上使用Nginx部署Flask应用: https://www.oschina.net/translate/serving-flask-with-nginx-on-ubuntu
[16] 腾讯云上Nginx证书安装: https://www.qcloud.com/document/product/400/4143#2.-nginx-.E8.AF.81.E4.B9.A6.E9.83.A8.E7.BD.B2
[17] certbot: https://certbot.eff.org/
如果该文章对您产生了帮助,或者您对技术文章感兴趣,可以关注微信公众号: 技术茶话会, 能够第一时间收到相关的技术文章,谢谢!
- 上一篇:我的Python_WEB服务器简单配置
- 下一篇:Nginx反向代理
相关推荐
- 如何理解python中面向对象的类属性和实例属性?
-
类属性和实例属性类属性就是给类对象中定义的属性通常用来记录与这个类相关的特征类属性不会用于记录具体对象的特征类属性的理解:类属性是与类自身相关联的变量,而不是与类的实例关联。它们通...
- Java程序员,一周Python入门:面向对象(OOP) 对比学习
-
Java和Python都是**面向对象编程(OOP)**语言,无非是类、对象、继承、封装、多态。下面我们来一一对比两者的OOP特性。1.类和对象Java和Python都支持面向对象...
- 松勤技术精选:Python面向对象魔术方法
-
什么是魔术方法相信大家在使用python的过程中经常会看到一些双下划线开头,双下划线结尾的方法,我们把它统称为魔术方法魔术方法的特征魔术方法都是双下划线开头,双下划线结尾的方法魔术方法都是pytho...
- [2]Python面向对象-【3】方法(python3 面向对象)
-
方法的概念在Python中,方法是与对象相关联的函数。方法可以访问对象的属性,并且可以通过修改对象的属性来改变对象的状态。方法定义在类中,可以被该类的所有对象共享。方法也可以被继承并重载。方法的语法如...
- 一文带你理解python的面向对象编程(OOP)
-
面向对象编程(OOP,Object-OrientedProgramming)是一个较难掌握的概念,而Python作为一门面向对象的语言,在学习其OOP特性时,许多人都会对“继承”和“多态”等...
- 简单学Python——面向对象1(编写一个简单的类)
-
Python是一种面向对象的编程语言(ObjectOrientedProgramming),在Python中所有的数据类型都是对象。在Python中,也可以自创对象。什么是类呢?类(Class)是...
- python进阶突破面向对象——四大支柱
-
面向对象编程(OOP)有四大基本特性,通常被称为"四大支柱":封装(Encapsulation)、继承(Inheritance)、多态(Polymorphism)和抽象(Abstrac...
- Python学不会来打我(51)面向对象编程“封装”思想详解
-
在面向对象编程(Object-OrientedProgramming,简称OOP)中,“封装(Encapsulation)”是四大核心特性之一(另外三个是继承、多态和抽象),它通过将数据(属性)和...
- Python之面向对象:对象属性解析:MRO不够用,补充3个方法
-
引言在前面的文章中,我们谈及Python在继承关系,尤其是多继承中,一个对象的属性的查找解析顺序。由于当时的语境聚焦于继承关系,所以只是简要提及了属性解析顺序同方法的解析顺序,而方法的解析顺序,在Py...
- Python之面向对象:通过property兼顾属性的动态保护与兼容性
-
引言前面的文章中我们简要提及过关于Python中私有属性的使用与内部“名称混淆”的实现机制,所以,访问私有属性的方法至少有3种做法:1、使用实例对象点操作符的方式,直接访问名称混淆后的真实属性名。2、...
- Python之面向对象:私有属性是掩耳盗铃还是恰到好处
-
引言声明,今天的文章中没有一行Python代码,更多的是对编程语言设计理念的思考。上一篇文章中介绍了关于Python面向对象封装特性的私有属性的相关内容,提到了Python中关于私有属性的实现是通过“...
- Python中的私有属性与方法:解锁面向对象编程的秘密
-
Python中的私有属性与方法:解锁面向对象编程的秘密在Python的广阔世界里,面向对象编程(OOP)是一种强大而灵活的方法论,它帮助我们更好地组织代码、管理状态,并构建可复用的软件组件。而在这个框...
- Python 面向对象:掌握类的继承与组合,让你的代码更高效!
-
引言:构建高效代码的基石Python以其简洁强大的特性,成为众多开发者首选的编程语言。而在Python的面向对象编程(OOP)范畴中,类的继承和组合无疑是两大核心概念。它们不仅能帮助我们实现代码复用,...
- python进阶-Day2: 面向对象编程 (OOP)
-
以下是为Python进阶Day2设计的学习任务,专注于面向对象编程(OOP)的核心概念和高阶特性。代码中包含详细注释,帮助理解每个部分的实现和目的。任务目标:复习OOP基础:类、对象、继...
- 外婆都能学会的Python教程(二十八):Python面向对象编程(二)
-
前言Python是一个非常容易上手的编程语言,它的语法简单,而且功能强大,非常适合初学者学习,它的语法规则非常简单,只要按照规则写出代码,Python解释器就可以执行。下面是Python的入门教程介绍...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python重命名文件 (54)
- python面向对象编程 (60)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)