文章目录
- 内容简介
- 网站目录示例
- 生成SSL证书
- 单独使用Flask
- 使用WSGI服务器
- Nginx反向代理
- 参考资料
内容简介
HTTPS 是一种至关重要的网络安全协议,它通过在 HTTP 协议之上添加 SSL/TLS 层来确保数据传输的安全性和完整性。这有助于防止数据在客户端和服务器之间传输时被窃听、篡改或伪造,对于保护用户隐私、防范中间人攻击以及增强用户对网站的信任至关重要。
针对 Flask Web 应用,实现 HTTPS 加密的三种推荐方式如下:
-
直接使用 Flask 启动 HTTPS:
- 优势:配置过程简单直观,非常适合开发和测试阶段。
- 局限:在高流量的生产环境中,其性能可能不足以应对需求;自签名证书可能会触发浏览器安全警告,影响用户体验。
- 实施方法:通过 Flask 应用直接配置 SSL/TLS,并在 443 端口上监听,实现 HTTPS 加密。
-
利用 WSGI 服务器(例如 Gunicorn):
- 优势:相较于 Flask 原生运行,WSGI 服务器能更高效地处理请求,支持生产环境中所需的高级特性,如工作进程和线程的智能管理。
- 局限:配置过程相对复杂,需要对服务器进行额外的管理和配置。
- 实施方法:使用 Gunicorn 等 WSGI 服务器运行 Flask 应用,并设置 SSL/TLS,以提升性能和可扩展性。
-
部署 Nginx 作为反向代理:
- 优势:Nginx 以其高效率和稳定性而著称,特别适合处理静态内容和代理动态请求,显著增强了 Flask 应用的性能和安全性。
- 局限:需要对 Nginx 进行配置,并维护额外的服务组件。
- 实施方法:配置 Nginx 作为反向代理服务器,负责处理 SSL/TLS 加密和提供静态资源,然后将动态请求转发至由 Gunicorn 管理的 Flask 应用。
关于证书的选择:
- 在开发和测试阶段,自签名证书是一个可行的选择。然而,在生产环境中,推荐使用由受信任的证书颁发机构签发的证书,以避免浏览器安全警告并增强用户信任。
- 第三方证书可以通过多种渠道获取,包括免费证书(例如 Let’s Encrypt 提供的)和商业付费证书,选择时应根据网站的具体需求和预算进行。
总结:
选择实现 HTTPS 加密的方法应基于应用的具体需求、预期的流量规模以及维护资源。对于大多数生产环境,推荐配置 Nginx 作为反向代理,并结合 Gunicorn 来运行 Flask 应用,同时采用第三方证书以确保通信的安全性和提升用户信任度。这种配置不仅优化了性能,还强化了安全性,为用户提供了更加安全可靠的网络服务体验。
网站目录示例
构建一个 Flask 网站的目录结构,包括 SSL 自制证书、Nginx 的代理配置文件和 Gunicorn 的启动文件,Nginx 启动文件, 可以按照以下示例进行组织:
/myflaskapp
/app
__init__.py
main.py
/certs
myflaskapp.com.conf
myflaskapp.com.crt
myflaskapp.com.key
/nginx
myflaskapp.conf
gunicorn_start.sh
nginx_start.sh
这里是每个部分的详细说明:
/myflaskapp
:项目的根目录。/app
:Flask 应用的目录。__init__.py
:初始化 Flask 应用的 Python 文件。main.py
:包含 Flask 应用的代码,例如路由和视图函数。
/certs
:存放 SSL 证书和私钥的目录。myflaskapp.com.conf
: SSL配置文件myflaskapp.com.crt
:SSL 证书文件。myflaskapp.com.key
:SSL 私钥文件。
/nginx
:存放 Nginx 配置文件的目录。myflaskapp.conf
:Nginx 代理配置文件,用于设置反向代理和 SSL 配置。
gunicorn_start.sh
:启动 Gunicorn 的 shell 脚本。nginx_start.sh
:启动 Nginx的 shell 脚本。
在使用 Python 的 Flask 框架时,可以通过集成 OpenSSL 和使用 WSGI 服务器的方式来启用 HTTPS。以下是一些基本步骤来配置 Flask 应用以使用 HTTPS:
生成SSL证书
- 配置文件:
在myflaskapp/certs
下创建文件·myflaskapp.com.conf
, 增加下面配置信息[req] prompt = no default_bits = 4096 default_md = sha256 encrypt_key = no string_mask = utf8only distinguished_name = cert_distinguished_name req_extensions = req_x509v3_extensions x509_extensions = req_x509v3_extensions [ cert_distinguished_name ] C = CN ST = BJ L = BJ O = HomeLab OU = HomeLab CN = myflaskapp.com [req_x509v3_extensions] basicConstraints = critical,CA:true subjectKeyIdentifier = hash keyUsage = critical,digitalSignature,keyCertSign,cRLSign #,keyEncipherment extendedKeyUsage = critical,serverAuth,clientAuth subjectAltName = @alt_names [alt_names] DNS.1 = myflaskapp.com DNS.2 = *.myflaskapp.com
- 生成 SSL 证书和私钥:
我们还需要一个 SSL 证书和私钥, 基于配置文件,使用 OpenSSL 来生成自签名的证书, 如下所示:
这将生成一个有效期为 3600 天的自签名证书# 定义文件名称 OUTPUT_FILENAME="myflaskapp.com" # 生成证书和私钥 openssl req -x509 -newkey rsa:2048 \ -keyout $OUTPUT_FILENAME.key \ -out $OUTPUT_FILENAME.crt \ -days 3600 -nodes \ -config ${OUTPUT_FILENAME}.conf
myflaskapp.com.crt
和私钥myflaskapp.com.key
。
单独使用Flask
使用 Flask 搭建一个简单的网站并启用 HTTPS 可以通过以下步骤完成:
-
安装 Flask:
首先,确保你已经安装了Python3
,然后使用pip3
来安装Flask
库:pip3 install flask
-
创建 Flask 应用:
在myflaskapp/app
目录下创建一个名为main.py
的文件,并添加以下代码:from flask import Flask, request, redirect app = Flask(__name__) @app.before_request def before_request(): if request.scheme == 'http': return redirect(request.url.replace('http://', 'https://', 1)) @app.route('/') def index(): return 'Hello, Flask with SSL!' if __name__ == '__main__': app.run(host='0.0.0.0', port=443, ssl_context=('../certs/myflaskapp.com.crt', '../certs/myflaskapp.com.key'))
这段代码做了以下几件事情:
- 定义了一个 Flask 应用。
- 使用
before_request
装饰器来检查请求的协议,如果是 HTTP,则重定向到 HTTPS。 - 定义了一个路由
/
,当访问网站根目录时返回Hello, Flask with SSL
。 - 运行应用,监听所有公共 IP 地址上的 443 端口,并使用指定的 SSL 证书和私钥启用 HTTPS。
-
启动 Flask 应用:
在命令行中运行以下命令来启动你的 Flask 应用:python3 main.py
-
配置域名映射:
将你的 Flask 应用的宿主机IP地址
映射到域名myflaskapp.com
。对于windows用户可以在C:\Windows\System32\drivers\etc
文件夹下的host
文件增加下面内容:<your-host-ip> myflaskapp.com
-
浏览器访问:
在浏览器中输入https://myflaskapp.com
访问你的网站。请注意,使用自签名证书会在浏览器中产生安全警告,因为自签名证书不被浏览器信任。 -
安装证书:
- 对于 Windows 用户,可以从服务器导出证书
myflaskapp.com.crt
,通过双击证书文件并按照提示安装。证书安装在受信任的根证书颁发机构
目录下。
- 安装完成后,重启浏览器,能够安全访问你的网站。
- 对于 Windows 用户,可以从服务器导出证书
请注意,使用自签名证书在生产环境中是不推荐的,因为它不被浏览器信任。在实际部署时,应该使用由受信任的证书颁发机构签发的证书。此外,确保你的 SSL 证书和私钥文件路径正确无误,并且具有正确的权限设置。
使用WSGI服务器
在生产环境中部署 Flask 应用时,使用 WSGI 服务器如 Gunicorn 可以提供更好的性能和稳定性。以下是使用 Gunicorn 部署 Flask 应用的步骤,包括一些优化的描述:
-
安装 Gunicorn:
使用pip3
安装Gunicorn
,这是Python
的一个WSGI HTTP
服务器,用于生产环境, 如下:pip3 install gunicorn
-
创建启动脚本:
在myflaskapp
目录下创建一个名为start_gunicorn.sh
的启动脚本,并添加以下内容。这个脚本将配置 Gunicorn 以使用 HTTPS 运行 Flask 应用:#!/bin/bash export MYFLASKAPP_HOME='/your/path/to/myflaskapp' gunicorn -w 4 -b 0.0.0.0:443 \ --keyfile ${MYFLASKAPP_HOME}/certs/openssl/myflaskapp.com.key \ --certfile ${MYFLASKAPP_HOME}/certs/openssl/myflaskapp.com.crt \ --chdir ${MYFLASKAPP_HOME}/app main:app
-w 4
表示使用 4 个工作进程来处理请求。-b 0.0.0.0:443
表示监听所有公共 IP 的 443 端口,允许来自任何 IP 的访问。--keyfile
和--certfile
指定了 SSL 私钥和证书文件的路径,确保 HTTPS 连接的安全性。./app.main:app
是 Flask 应用的模块和应用变量的引用。
-
启动 Gunicorn 服务:
给脚本文件添加执行权限,并运行它来启动 Gunicorn 服务:chmod +x start_gunicorn.sh ./start_gunicorn.sh
这样,你的 Flask 应用就会以 Gunicorn 作为 WSGI 服务器在后台运行。
-
浏览器访问:
在浏览器中输入https://myflaskapp.com
来访问你的网站。由于使用了 SSL/TLS 证书,你的连接将是加密的,浏览器会显示安全连接。
Nginx反向代理
部署 Flask 应用到生产环境时,使用 Nginx 作为反向代理服务器不仅可以提高应用的性能,还可以增强安全性。以下是使用 Nginx 和 Gunicorn 部署 Flask 应用的步骤:
-
拉取 Nginx 镜像:
使用 Docker 拉取最新的 Nginx 镜像:docker pull nginx
-
修改 Flask 应用:
更新myflaskapp/app/main.py
文件,确保 Flask 应用默认不绑定端口和不启用 SSL,因为它将由 Nginx 处理:from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello, Flask with SSL!' if __name__ == '__main__': app.run()
-
修改 Gunicorn 启动脚本:
更新myflaskapp/start_gunicorn.sh
脚本,确保 Gunicorn 监听 5000 端口(或其他非标准端口),因为 Nginx 将转发请求到这个端口:#!/bin/bash export MYFLASKAPP_HOME='/path/to/your/myflaskapp' nohup gunicorn -w 4 -b 0.0.0.0:5000 -chdir ${MYFLASKAPP_HOME}/app main:app &
-
配置 Nginx 反向代理:
在 Nginx 配置文件myflaskapp/nginx/myflaskapp.conf
中设置反向代理规则:server { listen 80; server_name myflaskapp.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name myflaskapp.com www.myflaskapp.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; location / { proxy_pass http://<your-flask-host>:5000; # 假设 Flask 应用运行在同一个主机的 5000 端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
注意:
proxy_pass
应该指向 Gunicorn 监听的地址和端口,<your-flask-host>
替换为Flask应用服务器IP
地址。 -
创建 Nginx 启动脚本:
创建myflaskapp/start_nginx.sh
脚本来启动 Nginx 容器,并挂载配置文件和 SSL 证书:#!/bin/bash sudo docker run \ -d \ -p 443:443 \ -p 80:80 \ -v $(pwd)/nginx/myflaskapp.conf:/etc/nginx/conf.d/myflaskapp.conf \ -v $(pwd)/certs/:/etc/nginx/ssl/ \ --name https-nginx nginx:latest
-
启动服务:
首先启动 Gunicorn 服务,然后启动 Nginx 服务:./start_gunicorn.sh ./start_nginx.sh
-
浏览器访问:
在浏览器中输入https://myflaskapp.com
访问你的网站。由于 Nginx 配置了 SSL 证书,连接将是安全的,浏览器将显示安全连接。
参考资料
如何制作和使用自签名证书
自签证书让Chrome信任的方式
使用自签名SSL证书配置HTTPS,解决浏览器提示不安全警告