Apache 2.4 将 SSL 限制到特定的子域虚拟主机

Apache 2.4 Restrict SSL to specific subdomain Vhosts

我有一个 digitalocean droplet,可能只有一个 IPV4 地址。我想使用 SNI 仅将 TLS (SSL) 加密应用于特定的子域,而不是该域的任何其他部分。

例如:

我对证​​书使用 LetsEncrypt,因此无法使用通配符域。

domain.com.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

sub.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@localhost
        ServerName sub.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile  /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    </VirtualHost>
</IfModule>

sub1.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@localhost
        ServerName sub1.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile  /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    </VirtualHost>
</IfModule>

sub2.domain.com

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName sub2.domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

您应该注意两件事:

  1. 您永远不知道用户将使用哪些协议。如果未定义协议,它们将默认为 http,并且一些浏览器扩展将首先尝试 https,如果存在则使用它。
  2. 如果没有更好的匹配,Apache 将回退到为该端口定义的第一个站点。在这种情况下,例如,如果您没有在端口 443 上定义 sub2.domain.com 站点,您最终可能会服务于错误的站点。

因此您应该在端口 80 和端口 443 上定义所有 4 个域,并且基本上定义了 8 个虚拟主机。

这也意味着需要购买(或从 LetsEncrypt 免费获得)证书以涵盖所有域,而不仅仅是您希望通过 https 提供服务的两个域。

那么你应该适当地使用重定向:

  1. domain.com(无 TLS): 在端口 80 上提供站点服务。端口 443 的配置应该将所有流量重定向回等效页面http://domain.com

  2. sub.domain.com(TLS,证书 1): 在端口 443 上提供站点服务。端口 80 的配置应该只是将所有流量重定向回来到 https://sub.domain.com

  3. 上的等效页面
  4. sub1.domain.com(TLS,证书 2): 类似于上面第 2 点中提到的 sub.domain.com 设置。

  5. sub2.domain.com(无 TLS): 类似于上面第一点中提到的 domain.com 设置。

示例配置:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
sub.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName sub.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{SERVER_NAME}/% [R,L]

    </VirtualHost>
</IfModule>
sub1.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName sub1.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{SERVER_NAME}/% [R,L]

    </VirtualHost>
</IfModule>
sub2.domain.com

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName sub2.domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    SSLEngine on
    SSLCertificateFile  /etc/ssl/certs/ssl-cert-domain.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-domain.key

     RewriteEngine On
     RewriteRule (.*) http://%{SERVER_NAME}/% [R,L]

</VirtualHost>
sub.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@localhost
        ServerName sub.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile  /etc/ssl/certs/ssl-cert-subdomain.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-subdomain.key
    </VirtualHost>
</IfModule>
sub1.domain.com

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@localhost
        ServerName sub1.domain.com
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile  /etc/ssl/certs/ssl-cert-subdomain1.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-subdomain1.key
    </VirtualHost>
</IfModule>
sub2.domain.com

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName sub2.domain.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
     SSLEngine on
     SSLCertificateFile  /etc/ssl/certs/ssl-cert-subdomain2.pem
     SSLCertificateKeyFile /etc/ssl/private/ssl-cert-subdomain2.key

     RewriteEngine On
     RewriteRule (.*) http://%{SERVER_NAME}/% [R,L]

</VirtualHost>

但是,如果遇到所有这些麻烦,那么可能需要重新考虑不通过 h​​ttps 提供所有服务。