【问题标题】:Can't remove Server: Apache header无法删除服务器:Apache 标头
【发布时间】:2016-05-23 11:30:39
【问题描述】:

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

ServerSignature Off  
ServerTokens Prod
Header unset Server

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

【问题讨论】:

  • 您是否启用了mod_headers?这是取消设置标题字段所必需的。
  • 我愿意。它已启用并正常工作,但无法删除此标头
  • 好的。刚刚用我自己的网络服务器对其进行了测试,它确实不适用于这个标题字段:-(
  • 尝试标头始终未设置服务器

标签: apache centos http-headers apache2


【解决方案1】:

标题检索

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(通过重命名modsecurity.conf-recommended),而不是修改/etc/apache2/apache.conf其中seems easier (注意你可以使用任何你想要的名字,在这种情况下我只是使用了一个空格)

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

【讨论】:

    【解决方案2】:

    我不对任何原因负责!
    请确保您遵循随附的许可证文件!

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

    完全删除Server: 标头:

    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 或其他内容...并且标题将返回。再次更改为None,它消失了:)

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

    【讨论】:

    • 我很想尝试一下,但需要找到 httpd-2.4.46/server/core.c 我在 2.4.48 但路径不同:/etc/httpd - where我可以找到 core.c 吗?
    • @infiniteshi,你需要从httpd.apache.org下载源码,使用上面的答案,编译并使用。我敢肯定,它不适用于普通的 apt、yum 安装
    • 喜欢这个答案,但很难确切地看到您在“将 更改为 ”示例中所做的更改。在我看来,它们以“统一差异”格式更具可读性,即stackoverflow.com/a/29113646
    • @egherrmann,嗯...让我也补充一下,稍后
    【解决方案3】:

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

    Header set "Server" "Generic Web Server".
    

    【讨论】:

    【解决方案4】:

    Apache 不允许您完全取消设置。事实上,一些开发人员强烈反对添加这个,尽管它是一个简单的代码更改,已经被建议(甚至写过!)好几次了。请参阅herehere,了解其中一些被提出和拒绝的讨论。

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

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

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

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

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

    5. 如果代理服务器知道另一端的服务器类型,它们“可能”以不同方式处理请求。恕我直言,这是代理服务器的错误,我怀疑它已经做得很多了。

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

    他们甚至在official documentation 中添加了这个:

    不建议将 ServerTokens 设置为小于最小值,因为 它使调试互操作问题变得更加困难。还 请注意,禁用 Server: 标头根本没有任何作用 您的服务器更安全。 “通过默默无闻的安全”的想法是 神话并导致错误的安全感。

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

    在不太可能掉头之前,你只剩下:

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

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

    【讨论】:

    • 隐藏你得到的东西不仅仅是安全。它还可以向您的竞争对手隐藏您使用的技术。官方文件是明确的铺位。对此持开放态度:“它符合我们的利益,并为你暴露 apache 支付我们的账单”不要让它看起来像我需要的东西
    • 查看我的回答:stackoverflow.com/questions/35360516/… 我已经提到了如何使用源删除。
    【解决方案5】:

    你可能没有启用mod_headers

    检查是否启用:

    root@host: a2query -m headers
    

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

    如果未启用,请使用以下命令激活模块:

    a2enmod headers
    

    【讨论】:

    • 已启用,我可以通过htaccess添加其他标题,但不能删除这个
    猜你喜欢
    • 2014-11-06
    • 2021-08-07
    • 1970-01-01
    • 2017-09-18
    • 2021-06-29
    • 2014-06-19
    • 2010-11-13
    • 1970-01-01
    • 2017-07-11
    相关资源
    最近更新 更多