必须写在http块里才能全局生效,因该指令具层级继承性:http块配置自动下放至所有server和location;若仅置于某server块,则其余虚拟主机仍暴露版本号。

直接加 server_tokens off; 到 http 块里,reload 后必须用真实请求验证,否则大概率没生效。
为什么必须写在 http 块里而不是 server 块
这个指令是继承式生效的:http 块里的设置会自动下放到所有 server 和 location;如果只写在某个 server 块里,其他虚拟主机(比如 include /etc/nginx/sites-enabled/* 里的配置)仍会暴露 Server: nginx/1.24.0。
常见错误写法:server { server_tokens off; } → 只关掉这一个站点,其余全漏。
正确位置:在 /etc/nginx/nginx.conf 的 http { ... } 大括号内,紧贴 include mime.types; 下方即可。
reload 后怎么验证才算真正生效
别信命令行输出“reload successful”,得测两个地方:
-
curl -I http://your-domain.com→ 响应头中Server字段应为Server: nginx,不能含斜杠和数字 -
curl -I http://your-domain.com/xxx-nonexistent-path→ 查看返回的 404 页面源码,搜索nginx/,确认无残留字符串
注意绕过中间层:Cloudflare、CDN 或反向代理可能覆盖原始 Server 头,务必直连 Nginx 的 IP 测试。
若仍看到版本号,运行 nginx -T | grep server_tokens 查看最终合并配置,确认是否被子配置文件覆盖。
错误页里的版本号为什么还在?
server_tokens off 只控制响应头和默认错误页的渲染逻辑,不修改 HTML 模板本身。404 页面底部的 nginx/1.24.0 文字依然存在,除非你自定义 error_page 并替换 HTML 文件。
例如,把 /usr/share/nginx/html/404.html 里所有 nginx/ 相关文字手动删掉或替换成空白。
编译时改源码(如 src/core/nginx.h)能彻底移除,但二进制包安装无法这么做,且升级后会被覆盖,运维成本高,不推荐日常使用。
别用 more_set_headers 覆盖 Server 头
有人试过 more_set_headers "Server: web-server";,这不可靠:
Nginx 内部对 Server 头有特殊处理逻辑,第三方模块无法稳定覆盖;而且该模块本身已多年未维护,容易引发兼容性问题。
唯一可靠路径就是 server_tokens off + 手动清理错误页 HTML + 直连验证。











