Files
djangoadmin-wiki/DjangoAdmin_Django_NaiveVue/zh/volume6/security-hardening.md
T
2026-09-12 23:12:15 +08:00

199 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安全加固
## 概述
生产环境的安全加固是防止数据泄露和服务被攻击的关键措施。本文从应用配置、传输安全、访问控制、数据保护等维度介绍安全加固实践。
:::tip 安全原则
- 最小权限:只开放必要的端口和权限
- 纵深防御:多层安全措施叠加
- 默认安全:配置默认值应为安全选项
:::
## 应用层安全
### 关闭 DEBUG 模式
```python
# application/settings.py
DEBUG = False
```
或通过 `.env` 配置:
```bash
DJANGO_DEBUG=False
```
:::warning 重要
DEBUG 模式会暴露详细的错误堆栈、SQL 查询等敏感信息,生产环境必须关闭。
:::
### SECRET_KEY 安全
```python
# application/settings.py
import secrets
SECRET_KEY = secrets.token_urlsafe(48)
```
:::tip SECRET_KEY 安全要点
1. `SECRET_KEY` 必须使用随机强密码,禁止使用默认值
2. 不同环境使用不同的 `SECRET_KEY`
3. 定期轮换 `SECRET_KEY`(需同时使所有已发 token 失效)
4. 通过环境变量注入,不要硬编码在代码中
:::
### 演示模式
```bash
# .env 配置
DJANGO_DEMO=True
```
演示模式下所有写操作(新增/编辑/删除/状态变更)都会被视图层拦截,返回"演示环境,暂无操作权限"。
## CORS 配置
```python
# application/settings.py
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOWED_ORIGINS = [
"https://www.example.com",
"https://admin.example.com",
]
```
:::warning CORS 安全
- 生产环境禁止使用 `CORS_ORIGIN_ALLOW_ALL = True`(允许任意来源)
- 仅列出信任的前端域名
- 如需支持多子域,使用 `CORS_ALLOWED_ORIGINS_REGEXES` 正则匹配
:::
## .env 文件安全
### 文件权限
```bash
# 设置 .env 文件权限(仅运行用户可读写)
chmod 600 .env
# 查看权限
ls -la .env
# -rw------- 1 app app 1024 Sep 5 10:00 .env
```
### 敏感信息管理
```bash
# .env 中的敏感字段
DATABASE_PASSWORD=<数据库密码>
REDIS_PASSWORD=<Redis密码>
SECRET_KEY=<Django密钥>
```
:::tip 安全建议
1. `.env` 文件禁止提交到 Git(已在 `.gitignore` 中排除)
2. 不同环境的 `.env` 独立管理,禁止共用
3. 生产环境密码至少 16 位,包含大小写字母、数字、特殊字符
4. 定期轮换数据库密码和 SECRET_KEY
:::
## 数据库安全
### 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
```
## 防火墙配置
### 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 8000 -j ACCEPT # Django(如不走 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 | 是 | 主入口 |
| 8000 | Django | 否 | 仅 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. 图片文件重新编码(防止嵌入恶意代码)
:::
## 安全检查清单
- [ ] `DEBUG = False`
- [ ] `SECRET_KEY` 使用随机强密码
- [ ] `.env` 文件权限 `600`
- [ ] CORS 不使用 `*` 通配符
- [ ] 数据库用户非 root 且最小权限
- [ ] Redis 设置密码并禁用危险命令
- [ ] 防火墙仅开放必要端口
- [ ] 上传文件类型白名单验证
- [ ] 日志不记录敏感信息(密码、token)
- [ ] HTTPS 启用且禁用 TLSv1.0/1.1
## 总结
安全加固的核心是纵深防御:应用层关闭 DEBUG、配置强 SECRET_KEY、限制 CORS;数据层数据库最小权限、Redis 密码保护;网络层防火墙仅开放必要端口;文件层上传白名单验证。生产环境务必逐项检查安全清单,定期审计。