1. 设置合理的 client_max_body_size
这个指令限制客户端请求体(如文件上传)的最大大小。设置过小影响正常使用,设置过大则可能被攻击者利用,发送超大请求体来消耗服务器资源。
配置方法:
通常,这个指令可以在 http
、server
或 location
块中设置。
http { # 在http块中设置为全局默认值,例如限制为10M client_max_body_size 10m; } server { listen 80; server_name your_domain.com; # 针对这个server,可以覆盖全局设置,例如限制为20M client_max_body_size 20m; location / { # ... 其他配置 ... } location /upload { # 对于专门的上传接口,可以设置得更大一些 client_max_body_size 50m; # ... 其他上传配置 ... } location /api { # 对于API,可能不需要太大的请求体 client_max_body_size 1m; } }
- 单位:
k
(千字节),m
(兆字节),g
(千兆字节) - 建议:根据您的业务需求设置。如果网站没有文件上传功能,可以设置一个较小的值(如1M)。对于上传功能,设置一个合理的上限。
2. 限制单个 IP 的连接数和请求速率
这是应对CC攻击和扫描非常有效的手段。
A. 限制请求速率
使用 limit_req_zone
和 limit_req
指令。
http { # 定义限制参数 # $binary_remote_addr 是客户端的二进制IP地址,占用空间更小 # zone=req_per_ip:10m 定义一个名为req_per_ip的共享内存区,用来存储KEY的状态,10MB可以处理约16万个IP的状态 # rate=10r/s 表示每秒允许10个请求 limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=10r/s; server { listen 80; server_name your_domain.com; location / { # 应用限制 # zone=req_per_ip 使用上面定义的zone # burst=20 允许超过速率限制后最多有20个请求被放入队列延迟处理 # nodelay 对于burst队列中的请求,不延迟处理,立即按速率处理;如果没有nodelay,则会延迟处理,导致用户等待。 limit_req zone=req_per_ip burst=20 nodelay; # ... 其他配置(例如 proxy_pass, root等) ... } # 对于静态文件,通常可以放宽或不做限制 location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { # 不应用请求频率限制 expires 1y; add_header Cache-Control "public, immutable"; } # 对于登录页面或API,可以设置更严格的限制以防爆破 location /login { limit_req zone=req_per_ip burst=5 nodelay; # ... 其他配置 ... } } }
B. 限制连接数
使用 limit_conn_zone
和 limit_conn
指令。这对于防止单个IP占用过多连接(如下载)特别有用。
http { # 定义连接限制参数 # zone=conn_per_ip:10m 定义一个名为conn_per_ip的共享内存区 limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; server { listen 80; server_name your_domain.com; # 全局限制每个IP最多保持10个连接 limit_conn conn_per_ip 10; location / { # ... 其他配置 ... } # 对于下载区域,可以单独限制更严格的连接数 location /downloads { limit_conn conn_per_ip 2; # 每个IP同时只能下载2个文件 # ... 其他配置 ... } } }
3. 对某些敏感的 URL 路径实施严格的访问控制
通过 location
块对管理后台、API接口等敏感路径进行加固。
A. IP 白名单(最安全)
只允许受信任的IP访问。
server { listen 80; server_name your_domain.com; # 正常网站内容 location / { # ... 其他配置 ... } # 保护 WordPress 后台 location /wp-admin { allow 192.168.1.100; # 替换为您的办公室或家庭IP allow 203.0.113.50; # 替换为另一个信任的IP deny all; # 拒绝所有其他IP # 同时可以加上请求速率限制 limit_req zone=req_per_ip burst=5 nodelay; # ... 其他配置(例如 try_files 或 proxy_pass)... } # 保护 PHPMyAdmin 或其他数据库管理工具 location /phpmyadmin { allow 192.168.1.100; deny all; auth_basic "Admin Login"; # 额外增加一层HTTP基础认证 auth_basic_user_file /etc/nginx/.htpasswd; } # 保护 API 接口 location /api/v1/admin { allow 192.168.1.0/24; # 允许整个内网网段 deny all; limit_req zone=req_per_ip burst=10 nodelay; } }
B. 密码认证
即使IP泄露,也多一层防护。
生成密码文件:
# 首次创建,-c 参数表示创建文件,后续添加用户不要再使用 -c,否则会覆盖 sudo sh -c "echo -n 'username:' >> /etc/nginx/.htpasswd" sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd" # 然后输入密码 # 或者使用 apache2-utils 包中的 htpasswd 命令 sudo apt-get install apache2-utils sudo htpasswd -c /etc/nginx/.htpasswd username
Nginx 配置:
location /secret-area { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; }
综合配置示例
一个结合了以上多种措施的 server 块可能看起来像这样:
http { limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; client_max_body_size 10m; } server { listen 80; server_name your_domain.com; # 全局连接限制 limit_conn conn_per_ip 10; # 根目录,应用请求频率限制 location / { limit_req zone=req_per_ip burst=20 nodelay; try_files $uri $uri/ /index.php?$query_string; } # 静态资源,不限制频率,利用缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } # 严格保护后台 location /admin { allow 192.168.1.100; # 你的IP deny all; limit_req zone=req_per_ip burst=5 nodelay; auth_basic "Admin Panel"; auth_basic_user_file /etc/nginx/.htpasswd; try_files $uri $uri/ /index.php?$query_string; } # 保护上传接口,限制文件大小 location /api/upload { client_max_body_size 20m; limit_req zone=req_per_ip burst=5 nodelay; # ... 处理上传的逻辑 ... } }
重要提醒:
- 测试:在应用这些配置到生产环境之前,请在测试环境中充分验证,确保不会误伤正常用户。
-
重载配置:每次修改 Nginx 配置后,使用
sudo nginx -t
测试配置语法是否正确,然后使用sudo systemctl reload nginx
重载配置使其生效。 - 根据业务调整:所有数字(如速率、连接数、文件大小)都需要根据您网站的实际流量和业务需求进行调整。
通过这些 Nginx 层面的防护,您可以大大降低被恶意扫描和攻击的风险,与 Fail2ban 形成互补的防御体系。