Apache 2.4 上的 Catch-All HTTPS Vhost

Nic*_*tte 8 httpd httpd.conf virtualhost apache-2.4

是否可以在 Apache 2.4 上配置一个包罗万象的(默认)HTTPS Vhost?我目前有 4 个域,并且一个 HTTP 捕获所有域,但是一旦我尝试添加任何类型的配置,我的其他虚拟主机就会中断。这是我的配置的样子:

<VirtualHost _default_:80>
    # Default catch-all virtual host.
    Redirect permanent / https://example-prod.com
</VirtualHost>

<VirtualHost _default_:80>
    ServerName example-prod.com
    ServerName www.example-prod.com
    Include conf/sites/example-prod.com.conf
</VirtualHost>

<VirtualHost _default_:80>
    ServerName example-dev.com
    Include conf/sites/example-dev.com.conf
</VirtualHost>

#
# This is the virtual host I'm missing and that I cannot get to work.
#
#<VirtualHost _default_:443>
#   # Default catch-all virtual host.
#   ServerAlias *
#   SSLEngine on
#   SSLCertificateFile "C:/prod/hosts.crt.pem"
#   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
#   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
#   Redirect permanent / https://example-prod.com
#</VirtualHost>

<VirtualHost _default_:443>
    ServerName example-prod.com
    ServerName www.example-prod.com
    SSLEngine on
    SSLCertificateFile "C:/prod/hosts.crt.pem"
    SSLCertificateKeyFile "C:/prod/hosts.key.pem"
    SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
    Include conf/sites/example-prod.com.conf
</VirtualHost>

<VirtualHost _default_:443>
    ServerName example-dev.com
    SSLEngine on
    SSLCertificateFile "C:/dev/hosts.crt.pem"
    SSLCertificateKeyFile "C:/dev/hosts.key.pem"
    SSLCertificateChainFile "C:/dev/intermediate.crt.pem"   
    Include conf/sites/example-dev.com.conf
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

我的 httpd.conf 没有了DocumentRoot- 一切都在 vhost 中并包含在内。这也是专用服务器和IP。

我怎样才能解决这个问题?

Esa*_*nen 5

问题解决了,但有一些误解。确实存在 HTTPS 需要匹配证书的要求,但由此引起的问题是,如果主机名与证书Common Name不匹配或在Subject Alternative Name 中列出,则不会信任该连接:

  • 即使使用RewriteRule另一个答案中给出的解决方案,同样的不匹配仍然存在。

  • 如果“全能”主机名都是 的子域,example.com并且您有 的通配符证书*.example.com,它将匹配。

  • 另一方面,大多数人在尝试访问时something.example.com,将其输入到浏览器地址栏而不带http://https://前缀,浏览器默认为 HTTP。因此,即使证书不匹配,在 HTTPS 上进行“全能”重定向通常不会导致任何实际问题:只有少数人会看到SSL_ERROR_BAD_CERT_DOMAIN错误。

使用或不使用 TLS ,虚拟主机匹配的工作方式相同。

如果您没有SNI

给定IP:port对的配置文件中的第一个基于名称的 vhost 很重要,因为它用于在该地址和端口上收到的所有请求,而该IP:port对的其他 vhost 没有 匹配的ServerNameServerAlias。如果服务器不支持Server Name Indication ,它也用于所有 SSL 连接 。

没有 SNI,第一个证书VirtualHost用于握手:

实际上,Apache 将允许您配置基于名称的 SSL 虚拟主机,但它始终会使用第一个列出的虚拟主机(在选定的 IP 地址和端口上)的配置来设置加密层。

您最初尝试的主要问题是有ServerAlias *和没有任何ServerName. 对于“包罗万象”的主机,它可以与除了ServerName来自其他VirtualHosts的其他s 之外的任何其他s 一起使用。如果没有其他匹配项,Apache 会回退到默认VirtualHost部分;以第一部分为准(当基于名称的查找失败时,匹配基于 IP 的查找)。

最佳匹配组的基于名称的虚拟主机<virtualhost>按照它们在配置中出现的顺序进行处理。第一个匹配的ServerNameorServerAlias被使用,通配符的优先级没有不同(ServerNamevs.也没有ServerAlias)。

一定有一些,ServerName因为:

ServerName指令可以出现在服务器定义中的任何地方。但是,每个外观都会覆盖先前的外观(在该服务器内)。

如果没有ServerName指定,服务器会尝试通过首先向操作系统询问系统主机名来推断客户端可见的主机名,如果失败,则对系统上存在的 IP 地址执行反向查找。

这将导致这样的配置:

<VirtualHost *:443>
    # Default catch-all (everything that won't match the following VirtualHosts)
    ServerName catch-all.example.com
    ServerAlias www.example.com
    SSLEngine on
    SSLCertificateFile "C:/prod/hosts.crt.pem"
    SSLCertificateKeyFile "C:/prod/hosts.key.pem"
    SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
    Redirect permanent / https://example.com
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile "C:/prod/hosts.crt.pem"
    SSLCertificateKeyFile "C:/prod/hosts.key.pem"
    SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
    Include conf/sites/example.com.conf
</VirtualHost>

<VirtualHost *:443>
    ServerName dev.example.com
    SSLEngine on
    SSLCertificateFile "C:/prod/hosts.crt.pem"
    SSLCertificateKeyFile "C:/prod/hosts.key.pem"
    SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
    Include conf/sites/dev.example.com.conf
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

请注意我更改的其他内容:

  1. dev.example.com 使用相同的证书,因为它在没有 SNI 的情况下会这样做。
  2. 使用<VirtualHost *:443>而不是_default_:443as_default_有一个特殊的目的:

    任何包含魔法_default_通配符的虚拟主机都被赋予与主服务器相同的 ServerName。

    (这也意味着可以_default_:443在您的“全能”中使用,而不是在其他人中使用。您可以尝试!)

  3. Domain 被替换为Reserved Example Domain Names

  4. 我更喜欢www.example.com作为“包罗万象”(而不是作为别名)的一部分,以便您的站点只有一个规范地址。因此我把它搬到了那里。


如果您有SNI,则处理模仿相同的行为,但在细节上略有不同:

甚至在 SSL 握手之前,Apache 就会找到与建立连接的 IP 地址和 TCP 端口的最佳匹配(基于 IP 的虚拟主机)

如果有一个NameVirtualHost指令与这个 best-matching 具有相同的文字参数VirtualHost,Apache 将改为考虑所有VirtualHost条目与匹配的 VirtualHost 具有相同的参数。否则,SNI 处理没有选择要执行。

如果客户端随其 TLS 握手请求一起发送主机名,Apache 会将此 TLS 主机名与前面步骤中确定的候选集的ServerName/进行比较。ServerAliasVirtualHost

无论在前面的基础上选择哪个 VirtualHost,都将使用其 SSL 配置来继续握手。值得注意的是,证书的内容没有用于任何比较。

使用 SNI,您可以获得dev.example.com.

如果满足 SNI 的所有先决条件,它应该error.log会自动运行并显示[warn] Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366).