Nginx 安全加固与服务监控体系
一、Nginx 账户认证
实验目的:为 Nginx 服务的特定路径(如 /login)启用 HTTP 基本认证,要求用户输入用户名和密码才能访问,防止未授权访问,提升网站安全性。
核心原理:HTTP 基本认证
HTTP 基本认证是一种简单的身份验证机制:
-
客户端访问受保护路径时,Nginx 返回
401 Unauthorized
响应,要求提供凭证; -
浏览器弹出认证框,用户输入用户名和密码;
-
Nginx 通过预先生成的密码文件(存储用户名和加密后的密码)校验凭证,验证通过则允许访问。
yum install httpd-tools # 生成和管理 HTTP 基本认证的密码文件
htpasswd -cm /usr/local/nginx/.htpasswd admin # 第一次添加需要加上 -c# -c:创建新密码文件# -m:使用 MD5 算法加密密码
htpasswd -m /usr/local/nginx/.htpasswd zyz # 第二次添加不要加上 -c,加上会覆盖第一次内容
cat /usr/local/nginx/.htpasswd
#######
admin:$apr1$PTZAXfxF$Rtpqre6nabdttTz9izSUP1
zyz:$apr1$/PLM11Ci$hjfgW4GJXEfOeEKbd..6T/
#######
编辑 Nginx 站点配置文件
vim /usr/local/nginx/conf.d/haha.conf
#######
server {listen 80;server_name www.haha.org;root /web/html;index index.html;
location /login {root /web/;index index.html;auth_basic "Please input username and password"; # 启用 HTTP 基本认证,提示信息auth_basic_user_file /usr/local/nginx/.htpasswd; # 指定 htpasswd 生成的密码文件位置}
}
#######
nginx -t
systemctl restart nginxcurl -uadmin:admin www.haha.org/login/ # 测试加上用户名和密码可访问内容
curl -uzyz:zyz www.haha.org/login/
为什么这样配置?核心价值
-
轻量级安全层:HTTP 基本认证无需复杂依赖,快速为特定路径添加访问控制;
-
灵活管理用户:通过 htpasswd 可随时添加 / 删除用户,无需修改 Nginx 配置;
-
场景适配:适合内部系统、测试环境等对安全性要求不极致,但需简单防护的场景(若需更高安全,建议结合 HTTPS + 更安全的认证方式,如 OAuth2)。
注意事项
-
密码文件权限:确保 Nginx 进程用户(如 nginx)可读取 .htpasswd 文件(可通过 chown nginx:nginx /usr/local/nginx/.htpasswd 调整权限);
-
加密算法选择:-m 是 MD5 加密,若需更高安全,可尝试 -B(bcrypt 加密)或结合 HTTPS 避免密码明文传输;
-
路径匹配规则:location /login 仅保护 /login 路径,若需保护整个站点,可将 auth_basic 配置到 server 或 http 块。
二、状态监控页配置
实验目的:通过启用 Nginx 内置的 stub_status 模块,创建一个实时展示服务器连接、请求等状态的监控页面,并通过身份认证保护该页面,防止未授权访问,为运维提供服务健康度的关键指标。
核心原理:stub_status 模块的作用
Nginx 内置的 stub_status 模块是轻量级的状态监控工具,无需额外安装,启用后可通过特定路径(如 /status)返回服务器的关键运行指标,包括:
-
活跃连接数(正在处理的连接);
-
累计接受 / 处理的连接数、请求数;
-
读取请求、发送响应、等待请求的连接数等。
这些指标是判断 Nginx 负载、性能瓶颈的重要依据(如 “活跃连接数突增” 可能意味着流量峰值或服务异常)。
vim /usr/local/nginx/conf.d/haha.conf
##########
server {listen 80;server_name www.haha.org;root /web/html;index index.html;
location /status {stub_status; # 启用 Nginx 内置的状态监控模块auth_basic "status page"; # 启用 HTTP 基本认证,保护状态页面不被未授权访问auth_basic_user_file /usr/local/nginx/.htpasswd; # 指定认证所需的用户名和密码文件路径}
}
##########
nginx -t
systemctl restart nginx
数据含义:
-
Active connections:当前活跃连接数(包括正在处理和等待的连接);
-
accepts:累计接受的连接总数;handled:累计处理的连接总数(通常与 accepts 相等,除非连接被拒绝);requests:累计处理的请求总数;
-
Reading:正在读取客户端请求的连接数;Writing:正在向客户端发送响应的连接数;Waiting:处于空闲状态、等待客户端请求的连接数(长连接场景下常见)。
为什么这样配置?核心价值
-
实时监控服务状态:stub_status 提供的指标是 “服务健康度仪表盘”,运维人员可通过这些数据:
-
判断服务器负载(如 Active connections 持续过高可能需要扩容);
-
发现异常请求(如 requests 突增可能是爬虫或攻击);
-
验证长连接、并发配置的有效性(如 Waiting 连接数可反映长连接复用情况)。
-
-
保护敏感信息:状态数据包含服务器运行细节(如请求量、连接数),若被公开访问:
-
可能泄露服务规模(如 “小网站却有大量请求” 可能被判断为测试环境);
-
被攻击者利用(如根据 Active connections 峰值设计 DDoS 攻击策略)。
-
通过 auth_basic 认证,仅允许授权用户(如运维人员)查看,降低信息泄露风险。
-
-
轻量高效:stub_status 模块属于 Nginx 内置功能,无需额外部署监控工具(如 Prometheus),资源占用极低,适合中小规模服务的基础监控需求。
注意事项
-
模块依赖:stub_status 需在编译 Nginx 时通过 --with-http_stub_status_module 选项启用(若之前的编译步骤未包含,需重新编译 Nginx)。
-
认证文件权限:确保 Nginx 进程可读取 auth_basic_user_file 指定的 .htpasswd 文件(权限不足会导致认证失败)。
-
扩展监控:若需更详细的监控(如按域名的请求统计、响应时间),可结合 ngx_http_reqstat_module 等第三方模块,或集成 Prometheus + Grafana 构建可视化监控平台。
三、全站加密
注意:此实验需要 nginx 支持 echo 模块功能,添加此模块可看主页文章《Nginx 功能扩展与二次开发实践》
实验目的:通过配置 SSL 证书和 HTTP 到 HTTPS 的强制重定向,实现网站 “全站加密”—— 所有客户端请求均通过 HTTPS 协议传输,确保数据在传输过程中被加密,防止窃听、篡改或伪造,提升网站安全性(尤其适用于含用户隐私、登录信息、支付数据的场景)。
HTTPS 与全站加密的核心价值
HTTP 协议传输的数据是明文的,存在被中间节点(如路由器、代理服务器)窃听或篡改的风险;而 HTTPS 基于 SSL/TLS 协议,通过 “证书认证” 和 “数据加密” 实现:
-
身份认证:通过 SSL 证书验证服务器身份,防止 “钓鱼网站” 冒充;
-
数据加密:客户端与服务器的通信内容被加密,即使被拦截也无法解析;
-
完整性校验:确保数据传输过程中未被篡改。
“全站加密” 则要求所有页面、资源(如图片、API)均通过 HTTPS 访问,避免 “混合内容”(部分 HTTP、部分 HTTPS)导致的安全警告或漏洞。
vim /usr/local/nginx/conf.d/haha.conf
##########
server {listen 80;server_name www.haha.org;root /web/html;index index.html; ssl_certificate /usr/local/nginx/certs/haha.org.crt; # 公钥证书路径(用于客户端验证服务器身份)ssl_certificate_key /usr/local/nginx/certs/haha.org.key; # 私钥路径(用于解密客户端加密的数据)ssl_session_cache shared:SSL:1m; # 共享 SSL 会话缓存,大小 1MB(复用已建立的 SSL 会话,减少握手开销)ssl_session_timeout 5m; # 会话缓存有效期 5 分钟(超时后需重新握手)ssl_ciphers HIGH:!aNULL:!MD5; # 仅使用高强度加密算法(HIGH),排除无认证(aNULL)和弱哈希(MD5)的套件
location /vars {default_type text/html;echo $scheme; # 输出当前协议(http 或 https)echo $host; # 输出当前域名(www.haha.org)}
location / {if ( $scheme = http ) { # 判断当前协议是否为 HTTPrewrite /(.*) https://$host/$1; # 重定向到 HTTPS 地址($host 为当前域名,$1 保留原路径)}}
}
##########
systemctl restart nginx
-
访问 HTTP 地址:输入 Domain For Sale,会自动跳转到 Domain For Sale(浏览器地址栏显示锁图标,表示加密连接);
-
访问 /test 路径:输入 http://www.haha.org/test,会输出 https 和 www.haha.org/test,验证协议已切换为 HTTPS。
为什么这样配置?核心安全逻辑
-
证书是基础:ssl_certificate 和 ssl_certificate_key 确保客户端能验证服务器身份并建立加密通道,无证书则无法启用 HTTPS;
-
会话缓存提升体验:SSL 握手耗时较长,缓存会话可减少重复验证的时间,避免 HTTPS 带来的性能损耗;
-
加密套件保障强度:禁用弱加密算法可防止 “降级攻击”(攻击者迫使客户端使用不安全的加密方式); 强制重定向消除漏洞:若不重定向,用户仍可通过 HTTP 访问,导致部分数据明文传输,违背 “全站加密” 初衷,可能引发浏览器 “混合内容” 警告或数据泄露。
注意事项
-
证书合法性:生产环境需使用 CA 机构签发的证书(自签证书会被浏览器标记为 “不安全”);
-
端口配置:完整的 HTTPS 配置通常需监听 443 端口(listen 443 ssl;),此处配置监听 80 端口并重定向,是简化的 “强制 HTTPS” 方案,实际建议同时配置 443 端口;
-
性能优化:可进一步启用 HTTP/2(listen 443 ssl http2;),提升 HTTPS 下的并发性能。
四、防盗链配置
注意:此实验需要 nginx 支持 echo 模块功能,添加此模块可看主页文章《Nginx 功能扩展与二次开发实践》
实验目的:通过配置 Nginx 的防盗链规则,限制外部网站(盗链网站)直接引用本网站的资源(如页面、图片、链接等),仅允许合法来源访问,避免带宽被滥用、内容被随意盗用,保护网站资源与运营成本。
防盗链的核心原理
在 HTTP 协议中,请求头包含一个 Referer 字段,用于记录 “当前请求是从哪个页面跳转过来的”(即请求的来源页面)。例如:
-
直接在浏览器输入 www.haha.org 访问,Referer 为空;
-
从 www.abc.com 的页面点击链接跳转到 www.haha.org,Referer 为 www.abc.com。
防盗链的核心逻辑是:通过检查 Referer 字段,只允许指定来源(如自身域名、信任的网站)访问资源,拒绝其他来源的请求,从而防止 “外部网站直接引用本网站资源却不带来流量” 的情况(即 “盗链”)。
创建盗链测试页面(模拟外部盗链场景)
vim /usr/share/nginx/html/index.html
##########
<html>
<head><meta http-equiv=Content-Type content="text/html;charset=utf-8"><title>盗链</title>
</head>
<body><h1 style="color:red">欢迎大家</h1><p><a href=http://www.haha.org>点击进入主页</a>www.haha.org</p></body>
</html>
##########
systemctl restart nginx
这个页面模拟 “外部盗链网站”—— 它包含指向目标网站 www.haha.org 的链接,当用户从这个页面点击链接访问 www.haha.org 时,请求的 Referer 字段会记录为该盗链页面的地址(如 http://盗链网站IP/index.html),用于测试防盗链规则是否生效。
配置 Nginx 防盗链规则
vim /usr/local/nginx/conf.d/haha.conf
##########
server {listen 80;server_name www.haha.org; # 目标网站域名(被保护的网站)root /web/html;index index.html;
location /vars {default_type text/html;echo $scheme; # 协议echo $host; # 域名echo $request_filename; # 请求文件路径}
location / {valid_referers none blocked server_names *.haha.org ~/.baidu/.; # 定义“合法的 Referer 来源”列表if ( $invalid_referer ) { return 404; # 如果 Referer 不在合法列表中($invalid_referer 为真),返回 404 拒绝访问}}
}
##########
systemctl restart nginx
-
valid_referers 合法来源列表
-
作用:定义哪些 Referer 来源被视为 “合法”,允许访问资源。参数含义:
-
none:允许 “无 Referer” 的请求(如直接在浏览器输入 URL 访问,或书签访问);
-
blocked:允许 Referer 被浏览器 / 代理隐藏(如被防火墙过滤)的请求;
-
server_names:允许来自自身域名(www.haha.org)的请求(如网站内部页面跳转);
-
*.haha.org:允许来自所有子域名(如 blog.haha.org、img.haha.org)的请求;
-
~/.baidu/:允许来自百度(baidu.com 相关域名)的请求(~ 表示正则匹配,.baidu/ 匹配含 “baidu” 的域名)。
-
测试
场景 1:合法访问(直接访问或内部跳转)
-
直接在浏览器输入 Domain For Sale,或从 www.haha.org 自身页面跳转:
-
Referer 为 none 或自身域名,属于合法来源;
-
可正常访问网站内容(符合预期)。
场景 2:盗链访问(从外部测试页面点击链接)
访问盗链测试页面(如 http://盗链网站IP/index.html),点击其中指向 www.haha.org 的链接:
请求的 Referer 为盗链页面的地址(不在 valid_referers 列表中);
Nginx 判断为 $invalid_referer,返回 404 错误,阻止访问(实现防盗链效果)。
为什么这样配置?核心价值
-
节省带宽成本:盗链会导致目标网站的带宽被外部网站消耗(如其他网站直接引用本网站的图片,加载时消耗本网站流量),防盗链可避免不必要的带宽支出;
-
保护内容权益:防止原创内容(如文章、图片、视频)被其他网站 “白嫖” 引用,维护知识产权;
-
维持网站性能:减少盗链带来的额外流量,避免服务器负载过高影响正常用户访问;
-
精准控制来源:通过 valid_referers 可灵活允许信任的来源(如搜索引擎、合作网站),既防盗链又不影响正常推广。
注意事项
-
Referer 的局限性:Referer 可被客户端伪造,因此防盗链是 “基础防护” 而非绝对安全,关键资源需结合其他措施(如签名 URL);
-
正则匹配精准性:使用 ~ 开头的正则时需谨慎(如 ~/.baidu/ 可能误匹配非百度的域名),建议精确匹配(如 ~* ^https?://.*.baidu.com/);
-
友好提示:可将 return 404 改为返回自定义页面(如 rewrite ^ /盗链提示.html;),告知用户 “此资源不允许外部引用”,提升体验。