Web服务器直接暴露在公网上,面临各种安全威胁。通过Nginx的安全配置,可以有效防御CC攻击、资源盗链、恶意爬虫等常见攻击。本文介绍在搬瓦工VPS上对Nginx进行安全加固的实用方法。
限流是防止CC攻击和暴力破解的有效手段。Nginx提供两种限流模块:
基于请求速率限流(limit_req):
# 在http块中定义限流区域
http {
# 每个IP每秒最多10个请求
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
# 登录接口更严格:每个IP每秒最多2个请求
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=2r/s;
}
server {
listen 443 ssl;
server_name example.com;
# 全站限流,允许突发20个请求
location / {
limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
}
# 登录接口限流
location /api/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://127.0.0.1:3000;
}
}
参数说明:
$binary_remote_addr:以客户端IP作为限流Key(占用更少内存)zone=req_limit:10m:定义10MB共享内存区域,约可存储16万个IP状态rate=10r/s:每秒允许10个请求burst=20:允许突发20个请求排队等待nodelay:突发请求不延迟处理,超出后直接返回503基于并发连接数限流(limit_conn):
http {
# 定义连接数限流区域
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}
server {
# 每个IP最多30个并发连接
limit_conn conn_limit 30;
# 限制下载速度(每个连接)
location /download/ {
limit_conn conn_limit 2; # 每个IP最多2个下载连接
limit_rate 500k; # 每个连接限速500KB/s
}
}
自定义限流返回状态码和页面:
# 将默认503改为429(Too Many Requests)
limit_req_status 429;
limit_conn_status 429;
# 自定义429错误页面
error_page 429 /429.html;
location = /429.html {
root /var/www/error;
internal;
}
防止其他网站直接引用你的图片、视频等静态资源,节省带宽:
location ~* \.(jpg|jpeg|png|gif|webp|mp4|zip)$ {
valid_referers none blocked server_names
*.example.com
example.com
~\.google\.
~\.baidu\.;
if ($invalid_referer) {
# 返回403禁止访问
return 403;
# 或者返回一张防盗链提示图片
# rewrite ^/ /images/hotlink-denied.png break;
}
expires 30d;
}
参数说明:
none:允许没有Referer头的请求(直接访问)blocked:允许Referer头被防火墙删除的请求server_names:允许本站域名# 方式一:直接在location中限制
location /admin/ {
allow 192.168.1.0/24; # 允许内网段
allow 1.2.3.4; # 允许指定IP
deny all; # 拒绝其他所有IP
proxy_pass http://127.0.0.1:3000;
}
# 方式二:使用外部文件管理(方便维护大量IP)
# /etc/nginx/blocklist.conf
# deny 5.6.7.8;
# deny 10.0.0.0/8;
http {
include /etc/nginx/blocklist.conf;
}
# 方式三:使用geo模块
geo $blocked {
default 0;
5.6.7.8 1;
10.0.0.0/8 1;
}
server {
if ($blocked) {
return 403;
}
}
通过设置安全响应头,指示浏览器启用安全保护机制:
server {
# 防止MIME类型嗅探
add_header X-Content-Type-Options nosniff always;
# 防止页面被嵌入iframe(防止点击劫持)
add_header X-Frame-Options SAMEORIGIN always;
# 启用XSS过滤
add_header X-XSS-Protection "1; mode=block" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:" always;
# Referrer策略
add_header Referrer-Policy strict-origin-when-cross-origin always;
# 权限策略(限制浏览器API访问)
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# 隐藏Nginx版本号
server_tokens off;
}
# 通过User-Agent阻止已知恶意爬虫
map $http_user_agent $bad_bot {
default 0;
~*sqlmap 1;
~*nikto 1;
~*nmap 1;
~*masscan 1;
~*scrapy 1;
~*python-requests 1;
~*curl 1;
~*wget 1;
}
server {
if ($bad_bot) {
return 403;
}
# 禁止访问敏感文件
location ~ /\.(git|svn|env|htaccess|htpasswd) {
deny all;
return 404;
}
# 禁止访问备份文件
location ~* \.(bak|sql|log|old|swp|orig)$ {
deny all;
return 404;
}
# 禁止直接访问配置文件
location ~* \.(conf|ini|yml|yaml|toml)$ {
deny all;
return 404;
}
}
ModSecurity是开源的Web应用防火墙,可以防御SQL注入、XSS等常见攻击:
# 安装ModSecurity和Nginx连接器
sudo apt install libmodsecurity3 libmodsecurity-dev -y
# 安装Nginx ModSecurity连接器模块
# 需要编译安装,具体步骤取决于Nginx版本
# 下载OWASP核心规则集
cd /etc/nginx/
sudo git clone https://github.com/coreruleset/coreruleset.git modsec-crs
cd modsec-crs
sudo cp crs-setup.conf.example crs-setup.conf
ModSecurity配置:
# /etc/nginx/modsec/modsecurity.conf
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
# 加载OWASP规则
Include /etc/nginx/modsec-crs/crs-setup.conf
Include /etc/nginx/modsec-crs/rules/*.conf
# Nginx配置中启用
server {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
}
Tip: ModSecurity的OWASP规则可能误杀正常请求,建议先使用检测模式(SecRuleEngine DetectionOnly)观察一段时间再开启拦截。
server {
listen 443 ssl http2;
# 仅允许安全的TLS版本
ssl_protocols TLSv1.2 TLSv1.3;
# 强制HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 禁用不安全的加密套件
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
}
Tip: 更多教程请查看新手教程。