我的 HTTP 响应头中有 "Server: Apache",我想要将其移除。
我按照指示进行操作,例如添加下面的内容到 httpd.conf
:
ServerSignature Off
ServerTokens Prod
Header unset Server
但是最后一行没有任何效果。前两行已经更改了标题的内容(之前它还包含操作系统和PHP的信息),但我需要将其完全删除。如何做到这一点?
我的 HTTP 响应头中有 "Server: Apache",我想要将其移除。
我按照指示进行操作,例如添加下面的内容到 httpd.conf
:
ServerSignature Off
ServerTokens Prod
Header unset Server
但是最后一行没有任何效果。前两行已经更改了标题的内容(之前它还包含操作系统和PHP的信息),但我需要将其完全删除。如何做到这一点?
Apache不允许您完全取消设置此选项。实际上,尽管多次建议(甚至编写!),其中一些开发人员强烈反对添加它。请参见此处和此处的一些讨论。
他们给出了各种原因,包括:
这可能会使在野外计算Apache安装数量更加困难。我认为这是主要原因。Web服务器使用率竞争激烈,Apache的一些竞争对手(可能以N开头)经常发布它正在赶超Apache的消息,并且大多数扫描将基于HTTP标头,因此我可以理解不愿意让其更容易隐藏的不情愿。
模糊性安全是一种谎言,并且会给出错误的安全感,因为很容易通过指纹识别服务器来查看它可能是哪种软件,基于它如何响应某些请求。虽然这里有一点真相,但默认情况下将ServerTokens指定为Full绝对是一个安全问题,泄露了过多的信息,不应该在公共网站上显示。
可能违反了HTTP规范不提供服务器标头。这似乎存在争议,并且仍然无法回答为什么他们不允许您更改为某个随机字符串而不是Apache。
这使得调试问题变得困难,但您会认为需要调试的任何人都要知道或能够找出确切的版本。
如果代理服务器知道另一端的服务器类型,则“可能”会以不同方式处理请求。在我看来,这是代理服务器的错误之处,而且我怀疑现在已经很少这样做了。
如果人们真的想修改或隐藏此标题,他们可以编辑源代码。说实话,这是一个危险的建议,因为没有编程经验的人这么做可能会导致其他安全问题,尤其是如果他们运行的是非打包版本。
他们甚至在官方文档中加入了以下内容:
将ServerTokens设置为小于minimal是不推荐的,因为它会使调试互操作问题更加困难。同时要注意,禁用Server: 标题根本无法增强服务器的安全性。 "安全通过混淆"的想法是一种谬论,会导致虚假的安全感。
在我看来,这种推理是荒谬的。如果这是不允许它的主要原因,那么我不明白他们为什么不改变自己的立场。最坏的情况下,它不会增加任何内容,正如他们所说,它会阻止这个问题不时被提出,但我个人认为你给出的无关信息越少越好,因此希望能够关闭它。
在这种情况下,您可以选择以下方法:
需要注意的是,就点4和点5而言,大多数其他网络服务器也不允许你关闭这个功能,因此这不是Apache特有的问题。例如,Nginx在没有同样编辑源代码的情况下也不允许关闭它。
要获取头部信息,如果在服务器上(所有测试都在Ubuntu 14.04 Trusty Tahr上完成),似乎可以适当地使用以下方法:
curl -v http://localhost:80/ | head
这会产生类似于:
< HTTP/1.1 200 OK
< Date: Mon, 25 Jan 2021 09:17:51 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
要移除版本号,请编辑文件/etc/apache2/conf-enabled/security.conf
并修改以下行:
ServerTokens OS
改为ServerTokens Prod
ServerSignature On
改为ServerSignature Off
然后重新启动Apache:
sudo service apache2 restart
现在你应该得到类似下面的响应:
< HTTP/1.1 200 OK
< Date: Mon, 25 Jan 2021 09:20:03 GMT
* Server Apache is not blacklisted
< Server: Apache
要完全移除“Apache”这个词,首先安装ModSecurity:
sudo apt-get install libapache2-mod-security2
以下几行代码看起来好像不需要(启用该模块并重新启动Apache),但供参考:
sudo a2enmod security2
sudo service apache2 restart
检查模块是否已启用:
apachectl -M | grep security
应该显示:
security2_module (shared)
/etc/modsecurity/modsecurity.conf
(通过将modsecurity.conf-recommended
重命名),但最好修改/etc/apache2/apache.conf
,这样看起来更容易(请注意,您可以使用任何名称,在此示例中我仅使用了一个空格):<IfModule security2_module>
SecRuleEngine on
ServerTokens Min
SecServerSignature " "
</IfModule>
使用Min
而不是Full
还可以防止诸如mod_fastcgi
之类的模块出现在空白服务器名称之后。
然后重新启动Apache:
sudo service apache2 restart
现在当您运行以下命令时:
curl -v http://localhost:80/ | head
你应该得到:
< HTTP/1.1 200 OK
< Date: Mon, 25 Jan 2021 09:31:11 GMT
* Server is not blacklisted
< Server:
Header always set "Server" "Generic Web Server"
仅适用于2XX响应。如果您具有带有重定向的重写规则,则会忽略它并返回由ServerTokens选项设置的值。
最后,我修改了定义产品名称的变量,位于include/ap_release.h中。更简单,可以使用单个sed完成:
sed 's/AP_SERVER_BASEPRODUCT\ "Apache"/AP_SERVER_BASEPRODUCT\ "Generic Web Server"/' include/ap_release.h
要完全删除Server:
头信息:
Download the Apache source from https://httpd.apache.org, extract it, and edit it.
Edit the file httpd-2.4.46/server/core.c
, and change the following lines:
enum server_token_type {
SrvTk_MAJOR, /* eg: Apache/2 */
SrvTk_MINOR, /* eg. Apache/2.0 */
SrvTk_MINIMAL, /* eg: Apache/2.0.41 */
SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */
SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */
SrvTk_PRODUCT_ONLY /* eg: Apache */
};
TO:
enum server_token_type {
SrvTk_MAJOR, /* eg: Apache/2 */
SrvTk_MINOR, /* eg. Apache/2.0 */
SrvTk_MINIMAL, /* eg: Apache/2.0.41 */
SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */
SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */
SrvTk_PRODUCT_ONLY, /* eg: Apache */
SrvTk_NONE /* removes Server: header */
};
Change this other line:
if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
}
else if (ap_server_tokens == SrvTk_MINIMAL) {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION);
}
else if (ap_server_tokens == SrvTk_MINOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION);
}
else if (ap_server_tokens == SrvTk_MAJOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION);
}
else {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
}
TO:
if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
}
else if (ap_server_tokens == SrvTk_MINIMAL) {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION);
}
else if (ap_server_tokens == SrvTk_MINOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION);
}
else if (ap_server_tokens == SrvTk_MAJOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION);
}
else if (ap_server_tokens == SrvTk_NONE) {
ap_add_version_component(pconf, "");
}
else {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
}
And change this:
if (!strcasecmp(arg, "OS")) {
ap_server_tokens = SrvTk_OS;
}
else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) {
ap_server_tokens = SrvTk_MINIMAL;
}
else if (!strcasecmp(arg, "Major")) {
ap_server_tokens = SrvTk_MAJOR;
}
else if (!strcasecmp(arg, "Minor") ) {
ap_server_tokens = SrvTk_MINOR;
}
else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) {
ap_server_tokens = SrvTk_PRODUCT_ONLY;
}
else if (!strcasecmp(arg, "Full")) {
ap_server_tokens = SrvTk_FULL;
}
else {
return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'";
}
TO:
if (!strcasecmp(arg, "OS")) {
ap_server_tokens = SrvTk_OS;
}
else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) {
ap_server_tokens = SrvTk_MINIMAL;
}
else if (!strcasecmp(arg, "Major")) {
ap_server_tokens = SrvTk_MAJOR;
}
else if (!strcasecmp(arg, "Minor") ) {
ap_server_tokens = SrvTk_MINOR;
}
else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) {
ap_server_tokens = SrvTk_PRODUCT_ONLY;
}
else if (!strcasecmp(arg, "Full")) {
ap_server_tokens = SrvTk_FULL;
}
else if (!strcasecmp(arg, "None")) {
ap_server_tokens = SrvTk_NONE;
}
else {
return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', 'Full' or 'None'";
}
Compile Apache from the source you have modified. See: http://httpd.apache.org/docs/current/install.html
Set the following in httpd.conf
:
ServerSignature Off
ServerTokens None
或者:
httpd-2.4.46/server/core.c
, and change the following:
if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
}
else if (ap_server_tokens == SrvTk_MINIMAL) {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION);
}
else if (ap_server_tokens == SrvTk_MINOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION);
}
else if (ap_server_tokens == SrvTk_MAJOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION);
}
else {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
}
TO:
if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
}
else if (ap_server_tokens == SrvTk_MINIMAL) {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION);
}
else if (ap_server_tokens == SrvTk_MINOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION);
}
else if (ap_server_tokens == SrvTk_MAJOR) {
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION);
}
else {
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
}
ap_add_version_component(pconf, "");
ServerTokens
设置为Prod
或其他内容...然后头部就会回来了。再次改为None
,它就消失了 :) 我知道这是一个晚回答,但是它仍然可以帮助很多人!Header set "Server" "Generic Web Server".
你可能还没有启用mod_headers
模块。
请检查是否已启用:
root@host: a2query -m headers
mod headers
,输出应该类似于headers(已启用...)
。a2enmod headers
mod_headers
模块?这是取消标题字段所必需的。 - maxhb