在当今数字化时代,保障网站数据传输的安全性至关重要。HTTPS 协议通过使用 SSL/TLS 加密技术,能够有效防止数据在传输过程中被窃取或篡改。本教程将详细介绍如何在 Ubuntu 22.04 系统上,使用 Python 3.11 和 FastAPI 框架搭建一个带有免费 SSL 证书的 HTTPS 服务器。
准备工作
在开始之前,你需要确保满足以下条件:
- 拥有一台运行 Ubuntu 22.04 的服务器。
- 具备一个有效的域名,并将其 DNS 解析指向你的服务器 IP 地址。因为 Let's Encrypt 不支持为 IP 地址颁发证书,所以域名是必需的。
- 服务器已经连接到互联网,并且能够正常访问外部网络。
步骤 1:安装必要的软件包
首先,我们需要更新系统的软件包列表,并安装 Python 3.11、pip(Python 包管理工具)、Certbot(用于获取免费 SSL 证书)和 Nginx(作为反向代理服务器)。
- # 更新系统软件包列表
- sudo apt update
- # 安装 Python 3.11 和 pip
- sudo apt install python3.11 python3.11-venv python3-pip
- # 安装 Certbot 和 Nginx
- sudo apt install certbot python3-certbot-nginx nginx
解释
sudo apt update
:该命令用于更新系统软件包列表,确保我们能够获取到最新的软件包信息。sudo apt install python3.11 python3.11-venv python3-pip
:安装 Python 3.11 及其虚拟环境创建工具venv
和包管理工具pip
。虚拟环境可以帮助我们隔离不同项目的依赖,避免版本冲突。sudo apt install certbot python3-certbot-nginx nginx
:安装 Certbot 及其 Nginx 插件,用于获取和管理 Let's Encrypt 免费 SSL 证书,同时安装 Nginx 服务器。
步骤 2:创建 Python 虚拟环境并安装 FastAPI
为了避免全局 Python 环境的污染,我们将创建一个虚拟环境,并在其中安装 FastAPI 和 Uvicorn(一个用于运行 FastAPI 应用的 ASGI 服务器)。
注意:也可以用conda来创建pyhton的虚拟环境。以下代码用的python3的source来创建的建议虚拟环境,也够用。
- # 创建虚拟环境
- python3.11 -m venv fastapi_env
- # 激活虚拟环境
- source fastapi_env/bin/activate
- # 安装 FastAPI 和 Uvicorn
- pip install fastapi uvicorn
解释
python3.11 -m venv fastapi_env
:使用 Python 3.11 的venv
模块创建一个名为fastapi_env
的虚拟环境。source fastapi_env/bin/activate
:激活虚拟环境,激活后,我们在该终端中执行的所有 Python 命令都将使用该虚拟环境中的 Python 和相关包。pip install fastapi uvicorn
:在虚拟环境中安装 FastAPI 和 Uvicorn。
步骤 3:编写 FastAPI 应用
创建一个名为 main.py
的 Python 文件,并编写一个简单的 FastAPI 应用。
- from fastapi import FastAPI
-
- app = FastAPI()
-
- @app.get("/")
- def read_root():
- return {"..."}
解释
from fastapi import FastAPI
:导入 FastAPI 类。app = FastAPI()
:创建一个 FastAPI 应用实例。@app.get("/")
:定义一个 HTTP GET 请求处理函数,当用户访问根路径/
时,将返回一个包含{"..."}
的 JSON 响应。
步骤 4:配置 Nginx 作为反向代理
Nginx 可以作为反向代理服务器,将客户端的请求转发到我们的 FastAPI 应用。
4.1 创建 Nginx 配置文件
创建一个新的 Nginx 配置文件 /etc/nginx/sites-available/fastapi_app
。
sudo nano /etc/nginx/sites-available/fastapi_app
在文件中添加以下内容:
- server {
- listen 80;
- server_name your_domain; # 替换为你的实际域名
-
- location / {
- proxy_pass http://127.0.0.1:8000;
- 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;
- }
- }
解释
listen 80;
:指定 Nginx 监听 HTTP 端口 80。server_name your_domain;
:指定服务器的域名,需要将your_domain
替换为你自己的域名。proxy_pass http://127.0.0.1:8000;
:将客户端的请求转发到本地的 8000 端口,即我们的 FastAPI 应用运行的端口。proxy_set_header
:设置一些代理请求头,确保 FastAPI 应用能够获取到客户端的真实信息。
4.2 创建符号链接并测试配置
将配置文件链接到 sites-enabled
目录,并测试 Nginx 配置是否正确。
- # 创建符号链接到 sites-enabled 目录
- sudo ln -s /etc/nginx/sites-available/fastapi_app /etc/nginx/sites-enabled/
- # 测试 Nginx 配置
- sudo nginx -t
- # 重启 Nginx 服务
- sudo systemctl restart nginx
步骤 5:获取免费 SSL 证书
使用 Certbot 工具获取 Let's Encrypt 免费 SSL 证书。
sudo certbot --nginx -d your_domain # 替换为你的实际域名
多个域名时,申请方法如下:
sudo certbot --nginx -d your_domain.com -d www.your_domain.com
详细提示和输入说明
5.1 邮箱地址输入
- Saving debug log to /var/log/letsencrypt/letsencrypt.log
- Plugins selected: Authenticator nginx, Installer nginx
- Enter email address (used for urgent renewal and security notices) (Enter 'c' to
- cancel):
Let's Encrypt 需要一个有效的邮箱地址,用于在证书即将到期或有安全通知时联系你。输入你的常用邮箱地址,然后按回车键。
5.2 协议条款确认
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Please read the Terms of Service at
- https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
- agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- (Y)es/(N)o:
你需要同意 Let's Encrypt 的服务条款才能继续注册并获取证书。输入 Y
然后按回车键表示同意。
5.3 订阅邮件选项
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Would you be willing to share your email address with the Electronic Frontier
- Foundation, a founding partner of the Let's Encrypt project and the non-profit
- organization that develops Certbot? We'd like to send you email about our work
- encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- (Y)es/(N)o:
这是一个可选的订阅选项,询问你是否愿意与电子前沿基金会(EFF)共享你的邮箱地址,以便接收他们的相关新闻和活动信息。如果你愿意接收相关邮件,输入 Y
并回车;如果不愿意,输入 N
并回车。
5.4 域名验证与证书安装确认
- Obtaining a new certificate
- Performing the following challenges:
- http-01 challenge for your_domain
- Waiting for verification...
- Cleaning up challenges
- Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/fastapi_app
-
- Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 1: No redirect - Make no further changes to the webserver configuration.
- 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
- new sites, or if you're confident your site works on HTTPS. You can undo this
- change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Certbot 会验证你的域名所有权,并在验证通过后部署证书。这里会询问你是否要将所有 HTTP 请求重定向到 HTTPS。
- 如果你希望将所有 HTTP 请求重定向到 HTTPS,输入
2
并回车。 - 如果你暂时不想进行重定向,输入
1
并回车。
5.5 完成提示
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Please read the Terms of Service at
- https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf. You must
- agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- (Y)es/(N)o: Y
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Would you be willing, once your first certificate is successfully issued, to
- share your email address with the Electronic Frontier Foundation, a founding
- partner of the Let's Encrypt project and the non-profit organization that
- develops Certbot? We'd like to send you email about our work encrypting the web,
- EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- (Y)es/(N)o: Y
- Account registered.
- Requesting a certificate for ftpeak.com
-
- Successfully received certificate.
- Certificate is saved at: /etc/letsencrypt/live/ftpeak.com/fullchain.pem
- Key is saved at: /etc/letsencrypt/live/ftpeak.com/privkey.pem
- This certificate expires on 2025-06-15.
- These files will be updated when the certificate renews.
- Certbot has set up a scheduled task to automatically renew this certificate in the background.
-
- Deploying certificate
- Successfully deployed certificate for ftpeak.com to /etc/nginx/sites-enabled/fastapi_app
- Congratulations! You have successfully enabled HTTPS on https://ftpeak.com
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- If you like Certbot, please consider supporting our work by:
- * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
- * Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
这表示证书已经成功获取并安装,同时会显示证书和私钥的保存路径以及证书的到期日期等重要信息。
步骤 6:在配置中增加SSL
6.1 编辑配置文件
打开配置文件进入编辑状态:
sudo nano /etc/nginx/sites-available/fastapi_app
代码修改如下:
- # HTTP 服务器块,用于将所有 HTTP 请求重定向到 HTTPS
- server {
- listen 80;
- server_name ftpeak.com;
- # 永久重定向 HTTP 请求到 HTTPS
- return 301 https://$host$request_uri;
- }
-
- # HTTPS 服务器块,处理实际的 HTTPS 请求
- server {
- listen 443 ssl;
- server_name ftpeak.com;
-
- # SSL 证书和私钥配置
- ssl_certificate /etc/letsencrypt/live/ftpeak.com/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/ftpeak.com/privkey.pem;
-
- # 包含 Certbot 提供的 SSL 配置选项
- include /etc/letsencrypt/options-ssl-nginx.conf;
- # SSL Diffie-Hellman 参数配置
- ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
-
- # 反向代理配置,将请求转发到本地的 FastAPI 应用
- location / {
- proxy_pass http://127.0.0.1:8000;
- 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;
- }
- }
6.1 启动 FastAPI 应用
在激活的虚拟环境中启动 FastAPI 应用。
uvicorn main:app --host 127.0.0.1 --port 8000
解释
uvicorn main:app
:指定要运行的 FastAPI 应用,main
是 Python 文件名,app
是 FastAPI 应用实例的名称。--host 127.0.0.1
:指定应用监听的 IP 地址为本地回环地址。--port 8000
:指定应用监听的端口为 8000。
步骤 7:验证 HTTPS 访问
现在,你可以通过浏览器访问 https://your_domain
(替换为你的实际域名)来验证 HTTPS 服务器是否正常工作。如果一切正常,你应该能看到 {"..."}
的响应。
注意事项
- 确保服务器的防火墙允许 HTTP(端口 80)和 HTTPS(端口 443)流量。可以使用以下命令开放端口:
- sudo ufw allow 80
- sudo ufw allow 443
sudo ufw allow 443
步骤8:自动更新证书
自动更新测试
Let's Encrypt 证书的有效期为 90 天,为了避免证书过期导致服务中断,建议设置定期自动更新证书。可以使用以下命令测试自动更新:
sudo certbot renew --dry-run
测试结果如果通过如下:
- Saving debug log to /var/log/letsencrypt/letsencrypt.log
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Processing /etc/letsencrypt/renewal/ftpeak.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Account registered.
- Simulating renewal of an existing certificate for ftpeak.com
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Congratulations, all simulated renewals succeeded:
- /etc/letsencrypt/live/ftpeak.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
可以使用系统的定时任务(如 crontab -e
)来定期执行 certbot renew
命令。
crontab -e
如果你是第一次使用该命令,系统可能会提示你选择一个文本编辑器,你可以根据自己的喜好选择,例如选择 nano
编辑器,输入对应的数字并回车即可。
添加定时任务
在打开的 crontab
文件中,添加如下一行内容:
0 2 * * 1 /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
代码解释
-
时间设置部分(
0 2 * * 1
):0
表示分钟,即每小时的第 0 分钟(整点)。2
表示小时,即凌晨 2 点。*
表示任意值,这里前两个*
分别表示每月的任意天和每年的任意月。1
表示星期,即星期一。
综合起来,
0 2 * * 1
表示每周一凌晨 2 点执行该任务。你可以根据自己的需求调整时间,例如你也可以设置为每月执行一次,将时间设置为0 2 1 * *
,表示每月 1 号凌晨 2 点执行。 -
命令部分(
/usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
):/usr/bin/certbot renew
:这是执行 Certbot 证书更新的命令。--quiet
:表示以安静模式运行,避免在更新过程中输出过多的信息,减少不必要的干扰。--deploy-hook "systemctl reload nginx"
:这是一个部署钩子选项,当 Certbot 成功更新证书后,会执行双引号内的命令。这里的systemctl reload nginx
表示重新加载 Nginx 服务,使新的证书配置生效。
保存并退出
在 nano
编辑器中,按下 Ctrl + X
组合键,然后输入 Y
确认保存修改,最后按下回车键退出编辑器。
列出你设置的定时任务
你可以使用以下命令查看当前用户的 crontab
任务列表,确认刚才添加的任务是否已经正确保存:
crontab -l
如果输出中包含你添加的定时任务,说明配置成功。之后,系统会按照你设置的时间定期执行证书更新操作。
注意事项
- 确保
certbot
命令的路径/usr/bin/certbot
是正确的。你可以使用which certbot
命令来确认其实际路径。 - 在使用
systemctl reload nginx
之前,要确保当前用户有足够的权限来执行该命令。如果遇到权限问题,可能需要调整sudo
配置或使用其他方式来重新加载 Nginx 服务。
评论记录:
回复评论: