无法删除服务器:Apache header

Can't remove Server: Apache header

我的 HTTP 响应 header 中有“服务器:Apache”,我想将其删除。 我按照说明将其添加到 httpd.conf:

ServerSignature Off  
ServerTokens Prod
Header unset Server

但是最后一行没有效果。前两行更改了 header 的内容(之前它还包含有关 OS 和 PHP 的信息),但我需要将其完全删除。 如何做到这一点?

您可能还没有启用 mod_headers

检查是否启用:

root@host: a2query -m headers

如果启用了 mod headers,输出应该类似于 headers (enabled by ...)

如果未启用,请使用以下方式激活模块:

a2enmod headers

Apache 不允许您完全取消设置。事实上,一些开发人员强烈反对添加它,尽管它是一个简单的代码更改,已经被多次建议(甚至编写!)。请参阅 here and here 以了解提出和拒绝此问题的部分讨论。

他们给出了各种原因,包括:

  1. 这可能会使实际安装 Apache 的数量变得更加困难。我怀疑这是主要原因。 Web 服务器的使用竞争激烈,Apache 的竞争对手之一(可能以 N 开头,也可能不以 N 开头)定期发布它如何在 Apache 上取得进展,并且大多数扫描将基于 HTTP Header,所以我可以理解这种不愿让它更容易隐藏这一点。

  2. 默默无闻的安全是一个神话,并且给人一种错误的安全感,因为根据服务器对特定请求的响应方式,很容易对服务器进行指纹识别以查看它可能是哪种软件。虽然这有一点道理,但将 ServerTokens 默认指定为 Full 绝对 是一个安全问题,泄漏的信息远远超过 public 网站上默认显示的信息.

  3. 不提供服务器可能违反也可能不违反 HTTP 规范 header。这似乎存在一些争议,但仍然没有回答为什么他们不允许您将其更改为某个随机字符串而不是 Apache。

  4. 这使得调试问题变得困难,但您认为任何需要调试的人都知道或能够找到确切的版本。

  5. 代理服务器 "might" 如果知道另一端的服务器类型,它们会以不同方式处理请求。恕我直言,代理服务器有什么问题,我怀疑它已经做了很多了。

  6. 如果人们真的想修改或隐藏这个 header 他们可以编辑源代码。坦率地说,这是一个危险的建议,建议没有代码经验的人去做,如果他们 运行 从 non-packaged 版本只是为了添加这个,可能会导致其他安全问题。

他们甚至在 official documentation:

中添加了这个

Setting ServerTokens to less than minimal is not recommended because it makes it more difficult to debug interoperational problems. Also note that disabling the Server: header does nothing at all to make your server more secure. The idea of "security through obscurity" is a myth and leads to a false sense of safety.

恕我直言,这种推理很荒谬,而且正如我所说,如果这是不允许这样做的主要原因,那么我不明白他们为什么不改变立场。在更糟糕的情况下,它不会像他们所说的那样添加任何内容,并且它会阻止整个问题经常被提出,但我个人认为你提供的不必要信息越少越好,因此我希望能够将其关闭。

直到那不太可能 u-turn,你还剩下:

  1. 将其设置为最小值(因此它会显示 "Apache")- 这可能就足够了
  2. 编辑源代码 - 除了最偏执的人之外,这太过分了,并且意味着需要在每个新版本上应用相同的更改。
  3. 安装 ModSecurity - 这(至少曾经)允许您覆盖(但不能删除)这个 header 到任何您想隐藏服务器软件的地方。尽管 WAF 还有其他好处,但为此安装它可能有点矫枉过正。
  4. 在另一个允许您更改此字段的 Web 服务器后面代理 Apache。
  5. 切换到另一个网络服务器。

然而,应该注意的是,对于第 4 点和第 5 点,大多数其他 Web 服务器也不允许您将其关闭,因此这不是 Apache 独有的问题。例如,Nginx 不允许在不类似地编辑源代码的情况下关闭它。

如果需要只是隐藏有关哪个网络服务器的信息 运行,您可以尝试在配置文件中添加以下行:

Header set "Server" "Generic Web Server".

Header检索

get the headers,如果在服务器上,这似乎可以正常工作(所有测试都在 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)

删除版本号

remove the version number,编辑文件/etc/apache2/conf-enabled/security.conf并修改行:

  • ServerTokens OSServerTokens Prod
  • ServerSignature OnServerSignature 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”一词

要完全删除单词 Apache,首先 install ModSecurity:

sudo apt-get install libapache2-mod-security2

以下几行似乎不需要(启用模块并重新启动 Apache)但是 for reference:

sudo a2enmod security2
sudo service apache2 restart

检查模块是否启用:

apachectl -M | grep security

应该显示:

security2_module (shared)

那么虽然 you can amend /etc/modsecurity/modsecurity.conf (by renaming modsecurity.conf-recommended), instead amend /etc/apache2/apache.conf which seems easier (注意你可以使用任何你想要的名字,在这种情况下我只是使用了 space):

<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:

我对由此造成的任何后果概不负责!
请确保您遵循随附的许可文件!

以下当前适用于 APACHE 版本 2.4.46:

要完全删除 Server: header:

  1. https://httpd.apache.org 下载 Apache 源代码,解压并编辑它。

  2. 编辑文件 httpd-2.4.46/server/core.c,并更改以下行:

    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 */
    };
    

    收件人:

    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 */
    };
    
  3. 更改另一行:

        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 ")");
        }
    

    收件人:

        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 ")");
        }
    
  4. 并更改为:

        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'";
        }
    

    收件人:

        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'";
        }
    
  5. 从您修改的源代码编译 Apache。参见:http://httpd.apache.org/docs/current/install.html

  6. httpd.conf中设置如下:

    ServerSignature Off
    ServerTokens None
    

或:

  1. https://httpd.apache.org 下载 Apache 源代码,解压并编辑。
  2. 编辑文件 httpd-2.4.46/server/core.c,并更改以下内容:
        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 ")");
        }
    
    到:
        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 或其他...然后 header 就会回来。再改成None,就没了:)

我知道这是一个迟到的答案。但是,它仍然可以提供很多帮助!

这个方法:

Header always set "Server" "Generic Web Server"

仅适用于 2XX 回复。如果你有一个带有重定向的重写规则,它会被忽略并且 returns 由 ServerTokens 选项设置的值。

最后我修改了它在 include/ap_release.h 中定义产品名称的变量。更简单,只需一个 sed 即可完成:

sed 's/AP_SERVER_BASEPRODUCT\ "Apache"/AP_SERVER_BASEPRODUCT\ "Generic Web Server"/' include/ap_release.h