首页 / 帮助文档 / centos服务器nginx安全配置抵御恶意访问

centos服务器nginx安全配置抵御恶意访问

CentOS服务器上的Nginx默认配置在性能上表现尚可,但在抵御恶意访问方面几乎是“裸奔”状态。很多运维人员装完Nginx后直接上线,没有限制请求频率、没有隐藏版本号、没有过滤恶意爬虫,导致服务器频繁出现CPU飙高、带宽占满甚至业务中断的情况。解决这个问题的核心思路是:在Nginx层面建立多层防线,把绝大多数恶意流量挡在业务逻辑之前。

隐藏Nginx版本号与服务器信息

恶意扫描器通常会先探测Web服务器的类型和版本,再针对特定版本发起攻击。Nginx默认会在响应头和错误页面中暴露版本号,这等于给攻击者提供了精准的情报。在nginx.conf的http块中加入以下配置:

server_tokens off;
more_clear_headers Server;

其中server_tokens off可以隐藏版本号,但响应头中仍会显示“Server: nginx”。如果编译时加入了headers-more模块,可以用more_clear_headers彻底移除Server头。如果无法安装该模块,也可以通过修改Nginx源码中的ngx_http_header_filter_module.c文件,将“nginx”字符串替换为其他内容后重新编译。隐藏这些信息能有效降低自动化扫描工具的命中率。

限制请求速率与并发连接数

CC攻击和暴力破解最典型的特征就是短时间内发起大量请求。Nginx的limit_req模块可以针对单个IP限制请求频率。在http块中定义一个共享内存区域:

limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

然后在server或location块中应用限制:

location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    limit_conn conn_limit 10;
}

上述配置表示每个IP每秒最多请求10次,突发最多20次,超过后立即返回503错误。limit_conn限制每个IP的并发连接数为10。对于登录接口、注册接口、搜索接口等敏感路径,建议将速率限制得更严格,例如1r/s。需要注意的是,limit_req基于IP识别,如果前面有CDN或反向代理,需要正确配置real_ip模块来获取真实客户端IP,否则限制会作用在代理IP上。

封禁恶意User-Agent与扫描器特征

大量恶意流量来自自动化工具,它们的User-Agent往往带有明显的特征,例如sqlmap、nikto、nmap、python-requests、curl等。在server块中通过if判断User-Agent并直接返回403:

if ($http_user_agent ~* (sqlmap|nikto|nmap|curl|python-requests|wget|libwww-perl|scrapy|java/)) {
    return 403;
}

虽然if在Nginx中性能开销较大,但对于明确的恶意特征,这种简单直接的封禁非常有效。更高效的做法是使用map指令:

map $http_user_agent $bad_ua {
    default 0;
    ~*(sqlmap|nikto|nmap|curl|python-requests|wget|libwww-perl|scrapy) 1;
}

然后在server块中使用if ($bad_ua = 1) { return 403; }。map指令只在变量被引用时才执行匹配,性能优于直接使用if。同时,建议对空User-Agent的请求也进行限制,因为正常浏览器几乎不会发送空UA。

过滤恶意请求方法与URL特征

除了User-Agent,恶意请求的URL和方法也有明显特征。例如大量HEAD请求探测、OPTIONS请求扫描、以及包含phpMyAdmin、wp-admin、.env、.git等敏感路径的请求。在server块中添加:

if ($request_method !~ ^(GET|POST|HEAD)$) {
    return 444;
}
location ~* (\.env|\.git|\.svn|phpmyadmin|wp-admin|wp-login|xmlrpc\.php) {
    return 444;
}

返回444状态码是Nginx特有的非标准状态码,表示直接关闭连接而不返回任何响应,比403更能节省资源。对于.php请求,如果服务器上没有运行PHP,可以直接在server块中拒绝所有PHP请求,避免无效的解析尝试。对于确实需要运行PHP的站点,应使用location ~ \.php$精确匹配,并将其他不存在的文件类型直接返回404。

配置请求体大小限制与超时时间

恶意用户可能通过上传超大文件或发送慢速请求来消耗服务器资源。在http块中设置:

client_max_body_size 10m;
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 30s;
send_timeout 10s;

client_max_body_size限制请求体最大为10MB,超过后Nginx直接返回413错误。client_body_timeout和client_header_timeout分别限制读取请求体和请求头的超时时间,防止慢速攻击。keepalive_timeout不宜设置过长,避免连接被长时间占用。对于上传接口,可以根据实际需求单独调整client_max_body_size,但全局默认值应保持较小。

启用访问日志分析与实时监控

配置完防护规则后,需要通过日志来验证效果并发现新的攻击模式。在http块中定义自定义日志格式:

log_format security '$remote_addr - $time_local "$request" $status $body_bytes_sent "$http_user_agent" "$http_referer"';
access_log /var/log/nginx/access.log security;

定期分析日志中状态码为403、444、503的请求,可以了解哪些IP和UA被拦截,以及是否有误伤正常用户的情况。使用awk或grep命令可以快速统计:

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

对于频繁触发限制的IP,可以使用fail2ban工具配合Nginx日志实现自动封禁。在fail2ban的jail配置中添加nginx-limit-req规则,当某个IP在短时间内触发多次限制时,自动将其加入iptables黑名单,封禁一段时间。

利用Nginx内置模块实现IP黑白名单

对于已知的恶意IP段,可以直接在Nginx中配置拒绝访问。在http块中使用geo模块定义IP列表:

geo $block_ip {
    default 0;
    192.168.1.0/24 1;
    10.0.0.0/8 1;
    include /etc/nginx/block_ips.conf;
}

然后在server块中判断:

if ($block_ip = 1) {
    return 403;
}

block_ips.conf文件中每行一个IP或IP段,格式为“IP地址 1;”。这种方式比在location中逐个判断更高效,且便于维护。对于需要临时封禁的IP,只需在文件中添加一行然后reload Nginx即可。如果服务器前面有CDN,需要确保geo模块获取的是真实客户端IP,否则会误封代理IP。

开启HTTPS并配置安全响应头

HTTPS不仅能加密传输数据,还能防止中间人攻击和内容篡改。在server块中配置SSL证书后,添加以下安全响应头:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

这些响应头分别用于防止点击劫持、禁止MIME类型嗅探、启用XSS过滤、强制HTTPS连接以及控制Referrer信息泄露。虽然这些措施主要针对浏览器端安全,但也能增加恶意爬虫和自动化工具的分析难度。对于API接口,建议将X-Frame-Options设置为DENY,因为API不需要被嵌入iframe。

定期更新Nginx与系统补丁

CentOS默认仓库中的Nginx版本通常较旧,存在已知安全漏洞。建议使用Nginx官方仓库或编译最新稳定版。在CentOS 7/8上,可以通过以下命令添加官方仓库:

rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum update nginx

同时,定期执行yum update更新系统内核和其他组件。很多恶意攻击利用的是已知漏洞,及时修补能避免大部分自动化攻击。对于使用编译方式安装的Nginx,需要关注官方安全公告,在漏洞披露后尽快重新编译升级。

综合防护策略与效果验证

将上述所有配置整合到nginx.conf中后,需要验证配置的正确性和防护效果。使用nginx -t检查语法,然后reload使配置生效。测试时可以使用ab或wrk工具模拟高并发请求,观察limit_req是否生效;使用curl命令模拟恶意User-Agent和敏感路径请求,确认返回403或444状态码。同时,监控服务器CPU和内存使用情况,确保防护规则没有引入过大的性能开销。Nginx的limit_req和limit_conn模块基于共享内存实现,性能影响极小,但过多的if判断和正则匹配会消耗CPU资源,建议将常用的判断逻辑用map指令替代。

恶意访问的形态不断变化,单一防线很容易被绕过。只有将隐藏信息、速率限制、特征过滤、IP封禁、日志监控和系统更新结合起来,才能形成有效的纵深防御体系。这套配置在CentOS 7和CentOS 8上均经过验证,可直接用于生产环境。对于高流量站点,建议在测试环境中先进行压力测试,根据实际业务调整限制参数,避免误伤正常用户。