1. 为什么需要限制Nginx的域名访问?
上周处理服务器安全审计时,发现一个有趣的现象:某台业务服务器的Nginx虽然只配置了a.com的域名访问,但通过IP直接访问竟然也能看到默认欢迎页。更严重的是,竞争对手通过扫描IP段,把我们的测试环境接口全都爬了一遍——这就是典型的"裸奔"式配置带来的安全隐患。
Nginx作为Web服务的事实标准,默认安装后会监听所有网络接口(0.0.0.0),这意味着:
- 用户可通过IP直接访问服务
- 恶意扫描工具能轻易发现服务
- 未备案域名可能解析到你的IP
- 可能被用于钓鱼或恶意镜像
2. 核心防护方案设计
2.1 防御策略矩阵
| 攻击类型 | 防护手段 | 实现方式 |
|---|---|---|
| IP直接访问 | 默认站点拦截 | 返回444状态码 |
| 非法域名解析 | 域名白名单校验 | server_name匹配 |
| 扫描探测 | 非标准端口+证书绑定 | 修改默认端口+SSL配置 |
| 恶意爬虫 | User-Agent过滤+速率限制 | limit_req模块+map匹配 |
2.2 配置拓扑逻辑
nginx复制 +---------------------+
| 客户端请求 |
+----------+----------+
|
+---------------v------------------+
| Nginx接收请求 |
+---------------+------------------+
|
+---------------v------------------+
| 检查Host头与server_name是否匹配 |
+---------------+------------------+
|
+---------------v------------------+
| 匹配成功? | 匹配失败 |
| 正常响应 | 返回444/403 |
+----------------+-----------------+
3. 关键配置实操详解
3.1 基础域名白名单配置
nginx复制server {
listen 80 default_server;
server_name _; # 捕获所有未定义域名
return 444; # 直接关闭连接
}
server {
listen 80;
server_name a.com www.a.com;
# 正常业务配置
location / {
root /var/www/a.com;
index index.html;
}
}
关键点说明:
default_server确保捕获所有非目标域名的请求- 返回444比403更安全(不暴露任何信息)
- 需在DNS层面禁止泛解析(如*.a.com)
3.2 增强型SSL防护配置
nginx复制server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /path/to/dummy.crt;
ssl_certificate_key /path/to/dummy.key;
return 444;
}
server {
listen 443 ssl;
server_name a.com www.a.com;
ssl_certificate /path/to/real.crt;
ssl_certificate_key /path/to/real.key;
# HSTS等安全头配置
add_header Strict-Transport-Security "max-age=31536000" always;
}
避坑指南:
- 自签名证书的CN必须与业务域名不同
- 建议设置ssl_reject_handshake on(Nginx 1.19.4+)
- 禁用SSLv3/TLSv1.0等不安全协议
3.3 动态黑名单实现
nginx复制# 在http块中定义黑名单
map $remote_addr $blocked_ip {
default 0;
1.2.3.4 1; # 恶意IP示例
5.6.7.8 1;
}
server {
...
location / {
if ($blocked_ip) {
return 403;
}
# 正常业务逻辑
}
}
4. 高级防护策略
4.1 请求特征过滤
nginx复制# 拦截非常见User-Agent
map $http_user_agent $bad_ua {
default 0;
"~*(nmap|sqlmap|wget|curl|python)" 1;
}
# 拦截非常规请求方法
map $request_method $bad_method {
default 0;
"PUT|DELETE|TRACE" 1;
}
server {
...
if ($bad_ua) {
return 403;
}
if ($bad_method) {
return 405;
}
}
4.2 请求频率限制
nginx复制# 在http块定义共享内存区
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
...
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
# 业务逻辑
}
}
5. 运维监控方案
5.1 日志分析配置
nginx复制log_format security '$remote_addr - $host [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_user_agent" $http_referer';
server {
...
access_log /var/log/nginx/security.log security;
}
5.2 实时告警规则示例
bash复制# 监控非法域名访问
tail -f /var/log/nginx/security.log | grep -E '444"|403"'
# 统计高频访问IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
6. 完整配置检查清单
-
确认default_server配置生效
bash复制curl -H "Host: random.com" http://your_server_ip -
验证SSL拦截效果
bash复制
openssl s_client -connect your_ip:443 -servername fake.com -
压力测试频率限制
bash复制
ab -n 100 -c 10 http://a.com/api/test -
检查黑名单IP拦截
bash复制
curl --interface 1.2.3.4 http://a.com -
扫描残留风险项
bash复制
nmap -sV --script http-title your_ip
这套方案在我们生产环境拦截了:
- 每月约1200次恶意IP直接访问
- 阻止了30+个未授权域名解析
- 减少了80%的扫描探测请求