目录
一. 核心安全配置
1. 隐藏版本号
在生产环境中,需要隐藏 Nginx 的版本号,以避免泄漏 Nginx 的版本,使攻击者不能针对特定版本进行攻击。
在 Nginx 全局配置中添加:
server_tokens off; # 关闭版本号显示
2. 限制危险请求方法
禁用 PUT、DELETE、OPTIONS 等非必要 HTTP 方法,减少恶意文件上传 / 删除风险。
修改配置文件
if ($request_method ~* "^(PUT|DELETE|TRACE|OPTIONS)$") { return 405; # 返回Method Not Allowed状态码 }
或针对特定路径限制(如仅允许 GET/POST):
location /api/ { allow_methods GET POST; # 显式允许的方法 deny all; }
3. 请求限制(CC 攻击防御)
CC 攻击(Challenge Collapsar 攻击)是一种常见的网络攻击方式,通过大量合法或伪造的小流量请求来耗尽服务器资源,导致正常用户无法访问网站。要在 Nginx 中有效防止 CC 攻击,可以采用多种策略和方法。
CC 攻击,也称为连接数攻击或请求速率限制攻击,通过模拟大量用户访问来消耗服务器资源,从而使得正常用户无法正常访问网站。
(1)使用 Nginx 的 limit_req 模块限制请求速率
通过令牌桶算法限制单 IP 请求速率,防止高频次恶意请求。
编辑配置文件
定义速率限制区域(在
http
块中):http { limit_req_zone $binary_remote_addr zone=cc_limit:10m rate=10r/s; # 单IP每秒10请求,内存区10MB }
$binary_remote_addr
:二进制格式存储 IP(节省内存)rate=10r/s
:平均速率限制(突发请求可通过burst
参数允许)应用限制(在
server
或location
块中):location / { limit_req zone=cc_limit burst=20 nodelay; # 允许突发20个请求,无延迟排队 }
burst
:突发请求缓冲区大小nodelay
:超过平均速率时立即拒绝(非排队等待)
(2) 压力测试验证
使用ab
(Apache Benchmark)或wrk
模拟高频请求
ab -n 1000 -c 50 -k http://your-domain/ # 1000请求,50并发,长连接
验证目标:
- 检查 Nginx 日志(
error.log
)是否有503 Service Temporarily Unavailable
(触发限流)- 通过
curl -I
确认响应状态码,确保正常请求速率被限制在预期范围内(如单 IP 每秒≤10 请求)。
4. 防盗链
防盗链是一种重要的安全设置,旨在防止未经授权的用户盗用网站(静态)资源。盗链行为不仅侵犯了内容创作者的版权,还可能导致原网站带宽和资源的过度消耗,影响正常用户的访问速度和体验。
一般来说,用户浏览一个完整的页面并不是一次性全部传送到客户端的。如果所请求的页面带有图片或其他信息,那么第一个 HTTP 请求传送的是这个页面的文本,然后通过客户端的浏览器对这段文本进行解释执行。如果发现其中还有图片,那么客户端的浏览器会再次发送一条 HTTP请求,当这个请求被处理后这个图片文件才会被传送到客户端,最后浏览器会将图片安放到页面的正确位置,就这样一个完整的页面要经过多次发送 HTTP请求才能够被完整的显示。基于这样的机制,就会产生盗链问题:如果一个网站中没有其页面中所说图片信息,那么它完全可以链接到其他网站的图片信息上。这样,没有任何资源的网站利用了其他网站的资源来展示给浏览者,提高了自己的访问量,而大部分浏览者又不会很容易地发现。一些不良网站为了不增加成本而扩充自己站点内容,经常盗用其他网站的链接。一方面损害了原网站的合法利益,另一方面又加重了服务器的负扭。
二. 高级防护
1. 动态黑名单
动态黑名单是 Nginx 中一种实时拦截恶意请求的安全机制,它允许在不重启服务的情况下,动态更新需要封禁的 IP地址或网段。相比静态配置的 allow/deny指令,动态黑名单更灵活高效,适用于高并发、多变的攻击防护场景。
(1)编辑黑名单配置文件
创建黑名单文件
# 手动添加的固定封禁 IP(每行一个 IP 或 CIDR 段) blacklist 192.168.1.100; blacklist 10.0.0.0/8;
动态生成黑名单(通过脚本提取日志中高频攻击 IP,如每天凌晨更新):
# 示例:从 error.log 中提取触发 403/429 的 IP,频次 > 100 次则加入黑名单 awk '{print $1}' /var/log/nginx/error.log | sort | uniq -c | awk '$1>100 {print "blacklist " $2 ";"}' > /etc/nginx/blacklist.d/dynamic.conf
(2) 编辑主配置文件
在 http
块中引入黑名单,并在 server
块中应用:
http { # 加载黑名单模块 blacklist_file /etc/nginx/blacklist.conf; # 固定黑名单 blacklist_file /etc/nginx/blacklist.d/*.conf; # 动态生成的黑名单(支持通配符) server { listen 80; server_name mydomain.com; # 在请求处理前检查黑名单 if ($blacklisted) { # 模块内置变量,命中黑名单时为 "1" return 403; # 拒绝访问 } # 其他配置... } }
(3) 使用封禁 ip 测试访问
添加测试 IP 到黑名单
# 在 blacklist.conf 中临时添加 blacklist 192.168.1.200;
重启 Nginx 使配置生效:
nginx -s reload
使用封禁 IP 访问站点
curl -H "X-Forwarded-For: 192.168.1.200" http://mydomain.com # 预期返回 403 Forbidden(需根据实际代理配置调整请求头)
2. nginx https 配置
2.1 https 概念
HTTPS,全称HyperText Transfer Protocol over Secure Socket Layer,设计初衷是为了保证数据传输安全。http(超文本传输协议)是客户端浏览器与web 服务器之间的通信协议,而 https 协议可以认为是 HTTP + SSL/TLS,在 http 之下 tcp 之上加了ss1一层,用于对应用层数据的加解密。
2.1.1 https 为什么不安全
HTTP 由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险
窃听风险
中间人可以获取到通信内容,由于内容是明文,所以获取明文后有安全风险
篡改风险
中间人可以篡改报文内容后再发送给对方,风险极大
冒充风险
比如你以为是在和某宝通信,但实际上是在和一个钓鱼网站通信。
2.1.2 安全通信的四大原则
HTTPS 就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证和不可否认。
- 机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文;
- 完整性:指数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从来判定接收报文不合法;
- 身份认证:确认对方的真实身份,即证明“你妈是你妈”的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题:
- 不可否认:即不可否认已发生的行为,比如小明向小红借了 1000元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失。
2.1.3 HTTPS 通信原理概述
(1)TLS 握手阶段:
- 客户端发送支持的加密套件列表。
- 服务器选择加密套件,返回证书(含公钥)。
- 客户端验证证书,生成随机预主密钥(用服务器公钥加密)。
- 双方计算生成对称密钥(用于后续数据加密)。
(2) 数据传输阶段:使用对称加密传输数据,哈希算法校验完整性。
2.2 nginx 配置 https 证书
2.2.1 使用 openssl 生成证书和私钥
生成私钥
openssl genrsa -out server.key 2048 # 2048位RSA私钥
生成证书签名请求(CSR)
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=Example/CN=your-domain.com"
生成自签名证书(有效期 1 年)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
2.2.2 nginx 启用 https
在server
块中添加 HTTPS 配置(替换为实际证书路径):
server { listen 443 ssl http2; # 监听443端口,启用HTTP/2 server_name your-domain.com; # 证书配置 ssl_certificate /path/to/server.crt; # 证书文件 ssl_certificate_key /path/to/server.key; # 私钥文件 # 安全增强配置(推荐) ssl_protocols TLSv1.3 TLSv1.2; # 禁用旧版协议(TLS 1.0/1.1) ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; # 强加密套件 ssl_prefer_server_ciphers on; # 服务器优先选择加密套件 ssl_session_cache shared:SSL:10m; # 会话缓存(减少握手次数) ssl_session_timeout 10m; # 其他配置(如重定向HTTP到HTTPS) return 301 https://$host$request_uri; # 如需单独配置HTTP站点,可移除此行 }
2.2.3 通过浏览器验证
访问https://your-domain.com
,浏览器地址栏应显示安全锁图标。