做nginx安全配置,核心原则只有一个:默认拒绝,按需放行,只要把这八个字落实到位,你的服务器就比大多数同行更抗打。
很多人装完nginx就直接上线,连最基本的端口扫描和访问来源都没管过,真正等到被刷流量、被拖库、被挂马的时候,才发现nginx配置里全是敞开的门,别慌,下面这套配置思路按优先级排序,你照着做就行。
nginx安全配置教程:先做这四件事
很多人问nginx安全配置教程到底该从哪里入手,我的建议是别一上来就搞WAF、搞复杂规则,先把最基础的四件事落地,已经能挡住相当一部分攻击。
隐藏版本号,别把家底亮给对手
nginx默认会在响应头里带一个 Server: nginx/1.24.0 这样的标识,可别小看这串字符,它直接告诉攻击者你用的具体版本,攻击者拿着CVE列表一比,就知道有没有现成的洞可以打。
很多新手问nginx隐藏版本号怎么配置,其实就一句话:
server_tokens off;
加在 http 块里就行,改完 nginx -t 检查配置,reload,完了之后你再看一眼响应头,版本号已经没了,就剩个 nginx 字样。
限制请求体大小和超时时间
不限制 client_max_body_size 的nginx就像一个不设门槛的仓库,别人往里塞什么都行,攻击者可以构造超大的POST包,把你的带宽和内存活活打满。
生产环境里,按你的业务场景来定:
client_max_body_size 4m; client_body_timeout 10s; client_header_timeout 10s; send_timeout 10s;
从几十兆缩到几兆,连接数撑爆的概率会明显下降,这些数字别拍脑袋,先看你的业务有没有上传功能,只是接口交互,4M绰绰有余。
停用危险HTTP方法
默认情况下,nginx对 PUT、DELETE、TRACE 这些方法是有响应逻辑的,但你的业务大概率只用 GET 和 POST,多出来的方法就是攻击面。
在 server 块里加一段,直接挡掉:
if ($request_method !~ ^(GET|POST)$) {
return 405;
}
别看这个方法土,配上后面的安全配置,它能把绝大多数自动化扫描脚本挡在门外。
访问日志必须开,别裸奔

有些朋友为了省磁盘空间把访问日志关了,这是典型的因小失大,被攻击之后想溯源,连个日志都没有,只能干瞪眼。
access_log /var/log/nginx/access.log combined;
再加一个json格式,方便后续接日志分析平台,日志文件本身要有轮转策略,logrotate 是标配,别让日志把磁盘写满。
nginx HTTPS配置证书怎么选?免费还是付费
nginx HTTPS配置证书是安全配置里争议最多的话题,免费的够用吗?付费的一定安全吗?答案是看你面对什么威胁。
免费证书:Let’s Encrypt 够用
Certbot一键申请,三个月续期一次,全自动搞定,加密强度和付费证书没有任何区别,因为用的都是同一套公钥加密算法体系,据近年的行业统计,相当比例的中小站点都在用免费证书,没有出过由此引发的安全事故。
网上有些教程说免费证书“不安全”,属于没搞懂技术原理,证书只是身份凭证,加密强度由算法的密钥长度决定,跟花没花钱没关系。
付费证书:多一些信任背书
付费证书的好处在于:
- 延长验证周期,不用三个月折腾一次
- 自带组织信息验证(OV/EV),访问者能看网站归属单位
- 部分浏览器有独立的安全标识
但要说真防护住什么攻击,付费和免费的差异并不大,如果你的站点涉及敏感数据交互,选付费带企业身份验证的证书更稳妥;如果只是内容展示类网站,免费证书完全够用。
TLS版本和加密套件必须锁死
上了HTTPS不算完,关键是别用老掉牙的TLS版本。
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;
TLSv1和TLSv1.1早该退场了,继续开就意味着你的加密通道还有十年前的老旧漏洞,具体配置差别你看下面这个表:
| 配置项 | 推荐值 | 不推荐值 |
|---|---|---|
| TLS版本 | TLSv1.2 + TLSv1.3 | TLSv1、TLSv1.1 |
| 加密套件 | 限定ECDHE+GCM系列 | 支持CBC模式套件 |
| Session缓存 | 共享缓存10m | 关闭或不配置 |
行业共识认为,TLSv1.3普及之前,把TLSv1.2配好是安全基线。

nginx防盗链配置方法与业务流程结合
图片和静态资源被别家网站直接引用,等于你花钱买带宽给别人做嫁衣。nginx防盗链配置方法很简单,难的是和业务场景结合。
一句话防盗链配置
location ~ .(gif|jpg|jpeg|png|webp|svg)$ {
valid_referers none blocked yourdomain.com .yourdomain.com;
if ($invalid_referer) {
return 403;
}
}
这里 none 表示允许直接访问(地址栏输地址的场景),blocked 表示允许无Referer头的请求,千万别把 none 去掉,否则你自己站内跳转引用图片都会被拦。
防盗链的边界场景
业务里经常有这种情况:App客户端请求图片,Referer头是空的,你在nginx层面直接按无来源放行,就会导致防盗链失效,这时候可以在 valid_referers 后面加一层判断,区分真正的客户端请求和爬虫抓取。
严格一点的方案是配合签名URL,但这就牵扯到业务侧传参了,nginx只做纬度校验,业务侧做授权校验,两层加起来才靠谱。
nginx安全配置最佳实践:防扫描、防暴力破解
做运维的都清楚,服务器暴露在公网后,每十分钟就能收到一堆扫描请求。nginx安全配置最佳实践里,防扫描和防暴力破解是绝对的重头戏。
limit_req限制请求频率
对付CC攻击最直接的手段就是频率限制,你正常用户1秒访问一次页面,攻击者1秒请求上百次,把频率锁死:
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=5r/s;
location / {
limit_req zone=req_limit burst=10 nodelay;
}
这个配置对单个IP每秒最多放行5个请求,超出部分直接503。burst=10 允许短暂突刺,不会误伤正常用户。
注意一个坑:很多攻击用分布式IP池,单IP频率限制会失效,这时候就得配合业务层的用户行为分析,nginx这一层只解决部分问题。
屏蔽恶意User-Agent
大量扫描工具会在请求头里带特征明显的UA,sqlmap、python-requests、curl 的某些变体,直接在nginx层过滤:
if ($http_user_agent ~ (sqlmap|nikto|masscan|python-requests) ) {
return 403;
}
这个方案虽然粗暴,但确实能拦下相当一部分新手攻击者的自动化工具。

fail2ban动态封禁
nginx做静态规则,fail2ban做动态联动,一旦日志里出现连续多次401或者403,fail2ban自动向防火墙下发封禁指令。
[nginx-limit-log]
enabled = true
filter = nginx-limit-log
action = iptables-multiport[name=nginx, port="80,443"]
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 600
这套组合拳打下来,暴力破解的脚本基本没戏,密码复杂点、登录限流做起来,安全性会在一个比较高的水平。
nginx安全配置内容合集与常见问题
每次聊到nginx安全配置,总有人反复问几个同样的点,这里统一列一下,都是实操里真会踩的坑。
核心配置片段放哪个文件好
别把所有配置堆在 nginx.conf 里。conf.d 目录按业务拆分配置文件,每个站点一个文件,安全规则独立定义,排错和回滚都方便。
测试环境的配置文件为什么同样重要
不少人只在生产环境做了加固,测试环境裸奔,攻击者扫描到测试环境,照样能通过跳板打到生产网段,测试环境的nginx配置应该和生产保持一致,密级低的项目至少也得把基础加固做了。
nginx安全配置常见问题解答
nginx隐藏版本号怎么配置才彻底?
server_tokens off 只能去掉版本号字面显示,响应头里仍然有 nginx 字样,要做到完全隐藏,需要编译时修改源码里的 ngx_http_header_filter_module.c,把默认Server头改成其他字符,但多数场景只需关闭版本号暴露就够用,没必要改源码。
nginx HTTPS配置证书免费的和付费的差距大吗?
加密强度上没有差别,付费主要买的是组织身份验证和售后服务,个人博客、企业展示站用免费证书完全没问题;涉及在线交易的平台,建议用企业验证级(OV/EV)证书提升访问者信任度。
nginx防盗链配置后为什么自己的手机App访问不了图片?
App请求通常不带Referer头,valid_referers 里的域名规则覆盖不了,解决方式是在防盗链规则中放行空Referer,或者直接让App端在请求头里携带自定义token,nginx通过 $http_custom_token 校验来源合法性。
nginx安全配置的本质是做减法关掉不需要的功能,限制过大的范围,拒绝不明的来源,先把基础项落地,再做深度加固,每一层都能挡住一类攻击,你的nginx越“小气”,你的服务器越安全。
