一、Nginx安全概述
1.1 为什么需要Nginx安全配置
Nginx作为Web服务器和反向代理,处于应用架构的最前端,直接面对互联网的各种攻击和扫描。安全配置Nginx可以有效防御以下威胁:
-
信息泄露:版本号暴露、目录遍历等
-
拒绝服务攻击:CC攻击、慢速攻击等
-
恶意扫描:自动化工具扫描漏洞
-
权限滥用:越权访问敏感文件
-
中间人攻击:数据窃听和篡改
1.2 安全设计原则
| 原则 | 说明 |
|---|---|
| 最小权限 | 只授予必要的权限,不运行多余功能 |
| 纵深防御 | 多层安全防护,单点失效不影响整体 |
| 默认安全 | 默认配置应是最安全的 |
| 完整审计 | 记录所有重要操作 |
二、基础安全配置
2.1 隐藏Nginx版本号
nginx
# 在http块中配置
http {
# 隐藏版本号
server_tokens off;
}
验证效果:
bash
curl -I http://your-server.com
# 原返回:Server: nginx/1.18.0 (Ubuntu)
# 现返回:Server: nginx
2.2 禁止显示Nginx签名
nginx
# 更彻底的隐藏,自定义服务器标识(需编译第三方模块)
# 或通过更底层方式修改源码,通常server_tokens off已足够
2.3 移除默认页面和示例文件
bash
# 删除默认首页
sudo rm /var/www/html/index.nginx-debian.html
# 创建自定义404页面
sudo mkdir -p /var/www/errors
echo "404 - Page Not Found" | sudo tee /var/www/errors/404.html
nginx
# 配置自定义错误页面
server {
error_page 404 /404.html;
location = /404.html {
root /var/www/errors;
internal; # 只能内部访问,不能直接通过URL访问
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/errors;
internal;
}
}
三、访问控制
3.1 IP地址访问控制
nginx
# 限制特定目录只能内网访问
location /admin/ {
# 允许内网IP
allow 192.168.1.0/24;
allow 10.0.0.0/8;
allow 127.0.0.1;
# 拒绝其他所有IP
deny all;
# 如果同时需要密码认证
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend;
}
# 限制API只能特定IP访问
location /api/internal/ {
allow 203.0.113.0/24;
allow 198.51.100.0/24;
deny all;
proxy_pass http://api-backend;
}
3.2 国家/地区访问控制
使用GeoIP2模块(需安装):
nginx
# 安装GeoIP2模块(Ubuntu)
sudo apt install libnginx-mod-http-geoip2
# 配置GeoIP2
load_module modules/ngx_http_geoip2_module.so;
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
# 定义允许的国家
geo $allow_country {
default 0;
CN 1; # 允许中国
US 1; # 允许美国
JP 1; # 允许日本
}
server {
location / {
if ($allow_country = 0) {
return 403;
}
proxy_pass http://backend;
}
}
}
3.3 User-Agent过滤
nginx
# 禁止恶意爬虫
location / {
# 方法1:if语句
if ($http_user_agent ~* (bot|crawler|spider|scrape|python|curl|wget)) {
return 403;
}
proxy_pass http://backend;
}
# 方法2:map方式(更高效)
http {
map $http_user_agent $bad_bot {
default 0;
~*(bot|crawler|spider|scrape) 1;
~*(python|curl|wget) 1;
~*(nikto|nmap|sqlmap) 1;
}
server {
location / {
if ($bad_bot) {
return 403;
}
proxy_pass http://backend;
}
}
}
# 只允许特定浏览器
location / {
if ($http_user_agent !~* (Chrome|Firefox|Safari|Edge)) {
return 403;
}
}
3.4 HTTP方法限制
nginx
# 只允许GET、HEAD、POST方法
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
# 更精细的控制
location /api/ {
limit_except GET POST {
deny all;
}
proxy_pass http://api-backend;
}
# 禁用TRACE方法(防止XST攻击)
if ($request_method = TRACE) {
return 405;
}
四、防攻击配置
4.1 限制请求速率
nginx
# 定义请求限制区域
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=static:10m rate=1000r/s;
server {
# 登录接口严格限制
location /login/ {
limit_req zone=login burst=3 nodelay;
limit_req_status 429;
proxy_pass http://auth-backend;
}
# API接口中等限制
location /api/ {
limit_req zone=api burst=50 nodelay;
limit_req_status 429;
add_header X-RateLimit-Limit 100;
add_header X-RateLimit-Remaining $limit_req_remaining;
proxy_pass http://api-backend;
}
# 静态资源宽松限制
location /static/ {
limit_req zone=static burst=200;
alias /var/www/static;
}
}
4.2 限制连接数
nginx
# 定义连接限制区域
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $server_name zone=server:10m;
server {
# 每个IP最多10个连接
limit_conn addr 10;
# 下载目录更严格的限制
location /downloads/ {
limit_conn addr 3;
limit_rate 200k; # 限制下载速度
alias /var/www/downloads;
}
# API连接限制
location /api/ {
limit_conn addr 20;
limit_conn_status 503;
proxy_pass http://api-backend;
}
}
4.3 限制带宽
nginx
location /video/ {
# 限制单个连接速度
limit_rate 500k;
# 前10MB不限速
limit_rate_after 10m;
alias /var/www/videos;
}
location /downloads/ {
# 根据文件类型限制速度
if ($request_filename ~* \.(zip|tar|gz)$) {
set $limit_rate 200k;
}
if ($request_filename ~* \.(pdf|doc)$) {
set $limit_rate 500k;
}
alias /var/www/downloads;
}
4.4 防止慢速攻击
nginx
http {
# 客户端超时设置
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 5s 5s;
send_timeout 10s;
# 限制请求头大小
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 限制请求体大小
client_max_body_size 10m;
client_body_buffer_size 128k;
}
server {
# 更严格的超时设置
location / {
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
}
}
4.5 防DDoS配置
nginx
# 综合DDoS防护配置
http {
# 连接数限制
limit_conn_zone $binary_remote_addr zone=ddos_conn:10m;
# 请求速率限制
limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=50r/s;
# 根据URI限制
limit_req_zone $request_uri zone=uri_req:10m rate=30r/s;
server {
# 全局连接限制
limit_conn ddos_conn 20;
# 全局速率限制
limit_req zone=ddos_req burst=100 nodelay;
# 特定URI更严格限制
location /search/ {
limit_req zone=uri_req burst=20;
limit_conn ddos_conn 5;
# 缓存搜索结果
proxy_cache search_cache;
proxy_cache_valid 200 10s;
proxy_pass http://search-backend;
}
# 白名单(不限制)
location /health {
limit_req off;
limit_conn off;
access_log off;
return 200 "healthy\n";
}
}
}