为什么当我使用 IP 地址访问时 Apache 会重定向我?

为什么当我使用 IP 地址访问时 Apache 会重定向我?

我有这个默认设置000-default.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

下面是我创建的my.conf

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    Redirect permanent / https://example.com/
</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName example.com
        DocumentRoot /var/www/html
        SSLEngine on
        ...
    </VirtualHost>
</IfModule>

如果我example.com在浏览器上尝试,我会被重定向到https://example.com/,这很好。

但如果我尝试的话123.45.67.89,也会被重定向到https://example.com/

由于两个虚拟服务器 (*:80) 都与 匹配123.45.67.89,而 不ServerName与 匹配123.45.67.89,我预计 Apache 2.4 会选择 中的那个000-default.conf。但事实并非如此。为什么?

我的参考是

如果多个虚拟主机包含最佳匹配的 IP 地址和端口,则服务器会根据请求的主机名从这些虚拟主机中选择最佳匹配。如果未找到匹配的基于名称的虚拟主机,则将使用与 IP 地址匹配的第一个列出的虚拟主机

答案1

您的默认基于名称的虚拟主机缺少ServerName

如果您ServerName从任何基于名称的虚拟主机中省略该指令,服务器将默认使用从系统主机名派生的完全限定域名 (FQDN)。这种隐式设置的服务器名称可能会导致违反直觉的虚拟主机匹配,因此不建议这样做。

派生的 FQDN 可能与第二个虚拟主机中的主机名匹配,从而导致不直观的问题虚拟主机匹配

同样的建议和解释如下有关 DNS 和 Apache HTTP 服务器的问题

为了使服务器正常运行,它绝对需要有关每个虚拟主机的两条信息:ServerName 以及服务器将绑定和响应的至少一个 IP 地址。

# This is a misconfiguration example, do not use on your server
<VirtualHost 192.0.2.1>
  ServerAdmin [email protected]
  DocumentRoot "/www/example"
</VirtualHost>

这次 httpd 需要使用反向 DNS 来查找ServerName此虚拟主机。如果反向查找失败,它将部分禁用虚拟主机。如果虚拟主机是基于名称的,那么它将被完全禁用。

添加一些东西到ServerName。任何东西。除非有其他匹配项,否则第一个<VirtualHost>仍将是默认项。它甚至可以是 IP 地址。只是不要不指定。例如使用

  • ServerName 198.51.100.10(使用你的服务器 IP)或
  • ServerName default-catch-all.example.org

答案2

第一个列出的主机取决于配置加载的顺序。不同的发行版具有不同的文件加载机制。

在 Ubuntu 上,应在 中定义站点/etc/apache2/sites-available。通过在 中创建链接来启用这些/etc/apache2/sites-enabled站点。已启用的站点将按规范顺序从该目录加载。sites-available未链接到 中的文件sites-enabled不会被加载。

配置从 加载文件/etc/apache2/mods-enabled,并etc/apache2/conf-enabled在从 加载站点之前加载sites-enabled

如果您启用了信息模块,您应该能够通过导航到 来查看配置https://www.example.com/server-info。检查此页面上的虚拟主机顺序。

还可以将重定向指令放置在.htaccess文档目录中的文件中。还可以将重定向指令放置在容器之外的容器内Virtualhost

您可能希望通过转储服务器标头来验证正在发生哪些重定向。我使用类似 的命令wget -qSO /dev/null http://192.0.2.22。这将显示每个重定向的标头。

相关内容