server_tokens off必须置于http块内才全局生效,写在server或location块中无效;需修改宝塔主配置文件/nginx.conf的http段,重载配置后用curl直连ip验证响应头是否仅显示“server: nginx”。

server_tokens off 必须写在 http 块里,不是 server 或 location
很多人改了但没生效,核心原因就是位置错了。server_tokens off 放在某个站点的 server 块里,看似合理,但 Nginx 实际只认 http 块级的设置——子块不声明时才继承,一声明就覆盖。宝塔默认的主配置 /www/server/nginx/conf/nginx.conf 里,http { } 是最外层作用域,这里加才真正全局生效。
实操建议:
- 打开
/www/server/nginx/conf/nginx.conf,找到http {开头的位置,在它后面紧跟着加一行:server_tokens off; - 删掉其他地方(比如站点配置文件、
server块内)重复写的server_tokens行,避免冲突 - 别漏分号,Nginx 语法校验会失败;也别加引号或等号写成
server_tokens = off,这是错的
改完必须「重载配置」,不是重启、也不是只点保存
宝塔界面上有好几个按钮容易混淆:保存 只写入文件,重启 Nginx 会中断连接,重载 Nginx 按钮在老版本里可能不存在。唯一正确动作是点击右上角的 重载配置(图标是两个循环箭头),它等价于执行 nginx -s reload,平滑加载新配置且不丢请求。
验证是否真生效:
- 用
curl -I http://你的服务器IP直连(绕过 CDN 和域名解析),看响应头有没有Server: nginx/1.24.0这类字段 - 如果还显示版本号,立刻检查:
nginx -t看语法是否报错;grep -r "server_tokens" /www/server/nginx/conf/查有没有别的地方又写成了on - 别依赖浏览器开发者工具 Network 面板——CDN 或反向代理可能缓存旧头
关了 server_tokens 还不够:PHP、错误页、欢迎页全得动
server_tokens off 只管 HTTP 响应头里的 Server 字段,其他地方照样泄露版本。扫描器 curl 一个不存在路径(比如 /nonexistent)就能拿到完整指纹。
必须同步处理:
- PHP 的
expose_php = Off:进宝塔 → 软件管理 → PHP → 设置 → 配置修改,在php.ini里搜expose_php,改成Off,然后点重启PHP - 默认 50x 错误页含 nginx 版本文字:替换
/www/server/nginx/html/50x.html,删掉所有nginx/相关字符串,再执行nginx -t && nginx -s reload - 访问服务器 IP 时返回的默认欢迎页:在站点配置的
location /块里加return 444;,或者指向一个空 HTML,否则直接暴露nginx/1.24.0
宝塔面板自己也在发版本号,X-Powered-By 得手动干掉
很多人测完响应头干净了就以为完事,结果用 curl -I 一扫,发现还有 X-Powered-By: 宝塔-8.0.5。这不是 Nginx 配置能控制的,是宝塔后端 Python 代码硬写的。
关键两处要改:
- HTTP 头:编辑
/www/server/panel/class/webserver.py,搜索set_header("X-Powered-By",把整行注释掉(前面加#) - 登录页 DOM:打开
/www/server/panel/BTPanel/templates/default/login.html,删掉含{{version}}或panelVersion的 HTML 标签 - 每次宝塔升级都会覆盖这两个文件,务必提前备份,升级后重新处理
这些改动没法一劳永逸,server_tokens 是起点,不是终点。真正的难点在于各层服务(Nginx、PHP、宝塔自身、甚至 Linux 登录横幅)都可能独立输出版本信息,漏掉任意一层,指纹就还在。











