# 安全加固 ## 概述 生产环境的安全加固是防止数据泄露和服务被攻击的关键措施。本文从应用配置、传输安全、访问控制、数据保护等维度介绍安全加固实践。 :::tip 安全原则 - 最小权限:只开放必要的端口和权限 - 纵深防御:多层安全措施叠加 - 默认安全:配置默认值应为安全选项 ::: ## 应用层安全 ### 关闭 DEBUG 模式 ```bash # .env 生产环境配置 FASTAPI_DEBUG=False ``` :::warning 重要 DEBUG 模式会暴露详细的错误堆栈、SQL 查询等敏感信息,生产环境必须关闭。 ::: ### JWT 安全 ```bash # .env 配置 JWT_SALT=<随机生成的64位强密码> JWT_EXPIRE_MINUTES=720 ``` ```bash # 生成强密码 python -c "import secrets; print(secrets.token_urlsafe(48))" ``` :::tip JWT 安全要点 1. `JWT_SALT` 必须使用随机强密码,禁止使用默认值 2. 不同环境使用不同的 `JWT_SALT` 3. 定期轮换 `JWT_SALT`(需同时使所有已发 token 失效) 4. token 过期时间不宜过长,建议 12 小时以内 ::: ### 演示模式 ```bash # 演示环境:禁止写操作 FASTAPI_DEMO=True ``` 演示模式下所有写操作(新增/编辑/删除/状态变更/导入/导出)都会被 `@check_demo` 装饰器拦截。 ## CORS 配置 ```python # core/config/app.py 中配置 CORS_ORIGINS = [ "https://www.example.com", "https://admin.example.com", ] ``` :::warning CORS 安全 - 生产环境禁止使用 `allow_origins=["*"]`(允许任意来源) - 仅列出信任的前端域名 - 如需支持多子域,使用正则匹配而非通配符 ::: ## .env 文件安全 ### 文件权限 ```bash # 设置 .env 文件权限(仅运行用户可读写) chmod 600 .env # 查看权限 ls -la .env # -rw------- 1 app app 1024 Sep 5 10:00 .env ``` ### 敏感信息管理 ```bash # .env 中的敏感字段 DB_PASS=<数据库密码> REDIS_PASSWORD= JWT_SALT= ``` :::tip 安全建议 1. `.env` 文件禁止提交到 Git(已在 `.gitignore` 中排除) 2. 不同环境的 `.env` 独立管理,禁止共用 3. 生产环境密码至少 16 位,包含大小写字母、数字、特殊字符 4. 定期轮换数据库密码和 JWT 密钥 ::: ## 数据库安全 ### MySQL 安全配置 ```sql -- 创建专用数据库用户(禁止使用 root) CREATE USER 'djangoadmin'@'%' IDENTIFIED BY '<强密码>'; GRANT SELECT, INSERT, UPDATE, DELETE ON djangoadmin_prod.* TO 'djangoadmin'@'%'; FLUSH PRIVILEGES; -- 禁止远程 root 登录 DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1'); FLUSH PRIVILEGES; ``` :::tip 最小权限原则 应用数据库用户只需 SELECT/INSERT/UPDATE/DELETE 权限,禁止 GRANT/CREATE/DROP 等管理权限。 ::: ### Redis 安全 ```bash # redis.conf 安全配置 # 设置密码 requirepass <强密码> # 禁止危险命令 rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command CONFIG "" rename-command DEBUG "" # 绑定地址 bind 127.0.0.1 # 禁用 protected-mode(设置了密码后) protected-mode no ``` ## 防火墙配置 ### iptables 基础规则 ```bash # 仅开放必要端口 iptables -A INPUT -p tcp --dport 22 -j ACCEPT # SSH iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS iptables -A INPUT -p tcp --dport 8031 -j ACCEPT # FastAPI(如不走 Nginx) iptables -A INPUT -i lo -j ACCEPT # 本地回环 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -P INPUT DROP # 默认拒绝 # 保存规则 iptables-save > /etc/iptables/rules.v4 ``` :::tip 端口规划 | 端口 | 服务 | 是否对外 | 备注 | |------|------|---------|------| | 22 | SSH | 是(限制 IP) | 建议修改默认端口 | | 80 | Nginx HTTP | 是 | 跳转 HTTPS | | 443 | Nginx HTTPS | 是 | 主入口 | | 8031 | FastAPI | 否 | 仅 Nginx 可访问 | | 3306 | MySQL | 否 | 仅应用可访问 | | 6379 | Redis | 否 | 仅应用可访问 | ::: ## 上传文件安全 ```python # 文件类型白名单 ALLOWED_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.pdf', '.doc', '.docx', '.xls', '.xlsx'} # 文件大小限制 MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB ``` :::tip 文件安全措施 1. 上传文件重命名为 UUID,防止路径遍历攻击 2. 验证文件类型(检查文件头,不依赖扩展名) 3. 上传目录禁止执行权限 4. 图片文件重新编码(防止嵌入恶意代码) ::: ## 安全检查清单 - [ ] `FASTAPI_DEBUG=False` - [ ] `JWT_SALT` 使用随机强密码 - [ ] `.env` 文件权限 `600` - [ ] CORS 不使用 `*` 通配符 - [ ] 数据库用户非 root 且最小权限 - [ ] Redis 设置密码并禁用危险命令 - [ ] 防火墙仅开放必要端口 - [ ] 上传文件类型白名单验证 - [ ] 日志不记录敏感信息(密码、token) - [ ] HTTPS 启用且禁用 TLSv1.0/1.1 ## 总结 安全加固的核心是纵深防御:应用层关闭 DEBUG、配置强 JWT 密钥、限制 CORS;数据层数据库最小权限、Redis 密码保护;网络层防火墙仅开放必要端口;文件层上传白名单验证。生产环境务必逐项检查安全清单,定期审计。