357 lines
7.4 KiB
Markdown
357 lines
7.4 KiB
Markdown
# HTTPS 配置指南
|
||
|
||
## 📋 概述
|
||
|
||
HTTPS 是生产环境必需的安全配置。本指南将帮助您配置 SSL/TLS 加密,确保数据传输安全。
|
||
|
||
## 🎯 配置方案
|
||
|
||
### 方案 1: Let's Encrypt 免费证书(推荐)
|
||
|
||
**优点**:
|
||
- ✅ 完全免费
|
||
- ✅ 自动续期
|
||
- ✅ 浏览器信任
|
||
- ✅ 简单易用
|
||
|
||
**适用场景**:生产环境,有公网域名
|
||
|
||
#### 1.1 安装 Certbot
|
||
|
||
```bash
|
||
# Ubuntu/Debian
|
||
sudo apt-get update
|
||
sudo apt-get install certbot python3-certbot-nginx
|
||
|
||
# CentOS/RHEL
|
||
sudo yum install certbot python3-certbot-nginx
|
||
|
||
# macOS
|
||
brew install certbot
|
||
```
|
||
|
||
#### 1.2 申请证书
|
||
|
||
```bash
|
||
# 自动配置 Nginx
|
||
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
||
|
||
# 或使用手动模式
|
||
sudo certbot certonly --webroot -w /var/www/html -d your-domain.com
|
||
```
|
||
|
||
#### 1.3 自动续期
|
||
|
||
```bash
|
||
# 测试续期
|
||
sudo certbot renew --dry-run
|
||
|
||
# 添加到 crontab
|
||
echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -
|
||
```
|
||
|
||
### 方案 2: 自签名证书
|
||
|
||
**优点**:
|
||
- ✅ 快速配置
|
||
- ✅ 无需域名
|
||
- ✅ 免费
|
||
|
||
**缺点**:
|
||
- ❌ 浏览器不信任(需要手动添加信任)
|
||
- ❌ 适用于内部系统
|
||
|
||
**适用场景**:开发环境、内部测试
|
||
|
||
#### 2.1 生成证书
|
||
|
||
```bash
|
||
# 使用脚本生成
|
||
python3 scripts/generate_ssl.py
|
||
|
||
# 或手动生成
|
||
mkdir certs
|
||
openssl genrsa -out certs/localhost.key 2048
|
||
openssl req -new -x509 -key certs/localhost.key -out certs/localhost.crt -days 365 -subj "/C=CN/ST=Beijing/L=Beijing/O=KaMiXiTong/CN=localhost"
|
||
```
|
||
|
||
#### 2.2 浏览器信任证书
|
||
|
||
1. 打开浏览器设置
|
||
2. 搜索"证书"或"Certificates"
|
||
3. 导入证书(certs/localhost.crt)
|
||
4. 信任该证书
|
||
|
||
### 方案 3: 商业 SSL 证书
|
||
|
||
**优点**:
|
||
- ✅ 最高级别的信任
|
||
- ✅ 提供保险
|
||
- ✅ 专业支持
|
||
|
||
**适用场景**:大型企业、电商平台
|
||
|
||
## 🔧 Nginx 配置
|
||
|
||
### 3.1 复制配置
|
||
|
||
```bash
|
||
# 复制示例配置
|
||
sudo cp nginx.conf.example /etc/nginx/sites-available/kamaxitong
|
||
|
||
# 编辑配置
|
||
sudo nano /etc/nginx/sites-available/kamaxitong
|
||
```
|
||
|
||
### 3.2 修改配置
|
||
|
||
```nginx
|
||
# 修改域名
|
||
server_name your-domain.com www.your-domain.com;
|
||
|
||
# 修改证书路径(Let's Encrypt)
|
||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||
|
||
# 或使用自签名证书
|
||
ssl_certificate /var/www/kamaxitong/certs/your-domain.com.crt;
|
||
ssl_certificate_key /var/www/kamaxitong/certs/your-domain.com.key;
|
||
```
|
||
|
||
### 3.3 启用站点
|
||
|
||
```bash
|
||
# 启用站点
|
||
sudo ln -s /etc/nginx/sites-available/kamaxitong /etc/nginx/sites-enabled/
|
||
|
||
# 测试配置
|
||
sudo nginx -t
|
||
|
||
# 重启 Nginx
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
### 3.4 配置防火墙
|
||
|
||
```bash
|
||
# 允许 HTTP 和 HTTPS
|
||
sudo ufw allow 80
|
||
sudo ufw allow 443
|
||
|
||
# 或使用 iptables
|
||
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||
```
|
||
|
||
## 🐍 Flask 应用配置
|
||
|
||
### 4.1 环境变量配置
|
||
|
||
在 `.env` 文件中设置:
|
||
|
||
```bash
|
||
# 强制 HTTPS(生产环境)
|
||
SESSION_COOKIE_SECURE=true
|
||
REMEMBER_COOKIE_SECURE=true
|
||
|
||
# 域名配置
|
||
FRONTEND_DOMAIN=your-domain.com
|
||
|
||
# 启用 HTTPS 重定向(可选)
|
||
FORCE_HTTPS=true
|
||
```
|
||
|
||
### 4.2 Flask 强制 HTTPS
|
||
|
||
在 `app/__init__.py` 中添加:
|
||
|
||
```python
|
||
from flask import request, redirect, url_for
|
||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||
|
||
def create_app():
|
||
app = Flask(__name__)
|
||
# ... 其他配置 ...
|
||
|
||
# 启用 ProxyFix(如果使用反向代理)
|
||
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1, x_prefix=1)
|
||
|
||
# 强制 HTTPS(生产环境)
|
||
@app.before_request
|
||
def force_https():
|
||
if app.config.get('FORCE_HTTPS') and not request.is_secure:
|
||
url = request.url.replace('http://', 'https://', 1)
|
||
return redirect(url, code=301)
|
||
|
||
return app
|
||
```
|
||
|
||
### 4.3 安全响应头
|
||
|
||
在 `app/__init__.py` 中添加:
|
||
|
||
```python
|
||
from flask import make_response
|
||
|
||
def add_security_headers(response):
|
||
"""添加安全响应头"""
|
||
# HSTS
|
||
response.headers['Strict-Transport-Security'] = 'max-age=63072000; includeSubDomains; preload'
|
||
|
||
# X-Frame-Options
|
||
response.headers['X-Frame-Options'] = 'DENY'
|
||
|
||
# X-Content-Type-Options
|
||
response.headers['X-Content-Type-Options'] = 'nosniff'
|
||
|
||
# X-XSS-Protection
|
||
response.headers['X-XSS-Protection'] = '1; mode=block'
|
||
|
||
# Referrer-Policy
|
||
response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
|
||
|
||
return response
|
||
|
||
# 注册响应处理器
|
||
@app.after_request
|
||
def after_request(response):
|
||
return add_security_headers(response)
|
||
```
|
||
|
||
## 🔍 验证配置
|
||
|
||
### 5.1 测试 HTTPS 访问
|
||
|
||
```bash
|
||
# 检查证书
|
||
openssl s_client -connect your-domain.com:443 -servername your-domain.com
|
||
|
||
# 或使用 curl
|
||
curl -I https://your-domain.com
|
||
|
||
# 检查健康检查端点
|
||
curl -I https://your-domain.com/api/v1/health
|
||
```
|
||
|
||
### 5.2 在线测试
|
||
|
||
使用以下工具测试 SSL 配置:
|
||
|
||
1. **SSL Labs**: https://www.ssllabs.com/ssltest/
|
||
2. **Why No Padlock**: https://www.whynopadlock.com/
|
||
3. **Mozilla SSL Configuration Generator**: https://ssl-config.mozilla.org/
|
||
|
||
### 5.3 检查安全评级
|
||
|
||
在 SSL Labs 测试中,应达到:
|
||
|
||
- ✅ **A+ 评级**
|
||
- ✅ **TLS 1.2 和 1.3**
|
||
- ✅ **HSTS 启用**
|
||
- ✅ **无弱密码**
|
||
|
||
## 🚨 常见问题
|
||
|
||
### Q1: 证书过期怎么办?
|
||
|
||
```bash
|
||
# 手动续期
|
||
sudo certbot renew
|
||
|
||
# 检查过期时间
|
||
openssl x509 -in /etc/letsencrypt/live/your-domain.com/cert.pem -noout -dates
|
||
```
|
||
|
||
### Q2: 自签名证书不被信任?
|
||
|
||
1. 在浏览器中访问网站
|
||
2. 点击"高级" → "继续访问"
|
||
3. 导入证书到受信任存储
|
||
|
||
### Q3: 混合内容警告?
|
||
|
||
确保所有资源(CSS、JS、图片)都使用 HTTPS:
|
||
|
||
```html
|
||
<!-- 正确 -->
|
||
<link rel="stylesheet" href="https://your-domain.com/static/css/style.css">
|
||
|
||
<!-- 错误 -->
|
||
<link rel="stylesheet" href="http://your-domain.com/static/css/style.css">
|
||
```
|
||
|
||
### Q4: 如何强制重定向到 HTTPS?
|
||
|
||
在 Nginx 配置中添加:
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name your-domain.com;
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
```
|
||
|
||
## 📊 性能优化
|
||
|
||
### 6.1 启用 HTTP/2
|
||
|
||
```nginx
|
||
server {
|
||
listen 443 ssl http2;
|
||
# ...
|
||
}
|
||
```
|
||
|
||
### 6.2 启用 Gzip 压缩
|
||
|
||
```nginx
|
||
gzip on;
|
||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
||
```
|
||
|
||
### 6.3 配置缓存
|
||
|
||
```nginx
|
||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||
expires 1y;
|
||
add_header Cache-Control "public, immutable";
|
||
}
|
||
```
|
||
|
||
## 📝 部署清单
|
||
|
||
- [ ] 申请 SSL 证书
|
||
- [ ] 配置 Nginx
|
||
- [ ] 启用 HTTPS 重定向
|
||
- [ ] 配置防火墙规则
|
||
- [ ] 设置自动续期(Let's Encrypt)
|
||
- [ ] 测试 HTTPS 访问
|
||
- [ ] 检查 SSL 评级
|
||
- [ ] 配置安全响应头
|
||
- [ ] 测试混合内容
|
||
- [ ] 验证证书过期时间
|
||
|
||
## 🔗 相关资源
|
||
|
||
- [Let's Encrypt 官网](https://letsencrypt.org/)
|
||
- [Mozilla SSL 配置生成器](https://ssl-config.mozilla.org/)
|
||
- [SSL Labs 测试工具](https://www.ssllabs.com/ssltest/)
|
||
- [Nginx SSL 配置指南](https://nginx.org/en/docs/http/configuring_https_servers.html)
|
||
|
||
## ✅ 完成检查
|
||
|
||
完成 HTTPS 配置后,访问以下 URL 验证:
|
||
|
||
1. **HTTPS 首页**: `https://your-domain.com`
|
||
2. **API 健康检查**: `https://your-domain.com/api/v1/health`
|
||
3. **SSL 评级**: 使用 SSL Labs 测试
|
||
|
||
如果一切正常,您应该看到:
|
||
|
||
- ✅ 浏览器显示绿色锁图标
|
||
- ✅ 健康检查返回 200 状态码
|
||
- ✅ SSL 评级为 A 或 A+
|
||
|
||
**🎉 恭喜!您的网站已启用 HTTPS!**
|