Nginx 安全加固
Nginx 暴露在公网,默认配置只保证"能跑"谈不上安全。本章做一轮低成本加固:藏版本、去默认站、挡敏感路径、禁多余 PHP 解析、补安全响应头、封恶意 UA,最后收紧运行权限。
隐藏版本号与默认站点
server_tokens off 让错误页不再泄露 nginx/1.24.0 这类版本信息;同时移除自带的欢迎页与默认 server(参考虚拟主机章的 default_server 改成直接拒绝):
http {
server_tokens off; # 错误页只显示 nginx,不显示版本号
server {
listen 80 default_server;
server_name _;
return 444; # 无匹配域名的请求直接断连
}
}
拒绝敏感路径与点开头文件
.git/.svn/.env/.htaccess 一旦泄露就是源码与密钥事故,统一拒绝:
server {
location ~ /\.(git|svn|env|hg|htaccess) { deny all; } # 版本库与配置文件
location ~ /\. { deny all; } # 所有点开头文件
location ~* \.(sql|log|bak|swp|old)$ { deny all; } # 备份/日志类后缀
}
禁止无关目录解析 PHP
上传目录若还能执行 PHP,等于给攻击者送 webshell。只存静态文件的目录一律禁止 PHP 解析,PHP 只在专门的 location 交给 FastCGI:
server {
location /upload/ {
location ~* \.php$ { deny all; } # 上传目录禁止执行任何 PHP
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock; # 仅此一处交给 PHP-FPM
include fastcgi_params;
}
}
安全响应头
给所有响应加浏览器侧防护(覆盖错误响应需加 always,并留意 add_header 的继承规则):
server {
add_header X-Frame-Options "SAMEORIGIN" always; # 禁止被 iframe 嵌套,防点击劫持
add_header X-Content-Type-Options "nosniff" always; # 禁止 MIME 类型嗅探
add_header Referrer-Policy "strict-origin-when-cross-origin" always; # 控制来源信息外泄
}
注意:location 一旦自带 add_header,server 层的这些头在该 location 内会失效,需要补写。
封恶意 UA 与注入关键字
对采集脚本按 UA 拦截;SQL 注入与 XSS 特征在入口先挡一道(纵深防御,业务层参数校验才是根本):
map $http_user_agent $bad_bot {
default 0;
"~*(curl|wget|python-requests|sqlmap|SemrushBot)" 1; # 匹配恶意 UA
}
server {
if ($bad_bot) { return 403; }
if ($query_string ~* "(union[[:space:]]+select|insert[[:space:]]+into|<script|sleep\()") {
return 403;
}
}
日志注入提醒:$request 等原始变量按原样落盘,恶意请求可夹带换行与控制字符伪造日志条目,重要系统应转义后记录或交由日志采集端清洗。
运行权限与目录权限
- 以非 root 账号运行 worker(user nginx;),即使被攻破也无法直接拿到系统权限。
- 站点文件收紧权限:目录 755、文件 644,上传/写入目录单独授权给对应账号,杜绝 777。
小结
安全加固按清单过一遍:server_tokens off、删默认站、deny 敏感路径与点文件、上传目录禁 PHP、补 X-Frame-Options 等响应头、封恶意 UA、以非 root 运行。每一条都只是几行配置,却能挡掉绝大多数"顺手攻击"。