Apache 2.4将SSL限制为特定的子域Vhost

时间:2016-03-12 10:40:13

标签: apache ssl sni

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

示例:

  • domain.com(无TLS)
  • sub.domain.com(TLS,证书1)
  • sub1.domain.com(TLS,证书2)
  • sub2.domain.com(无TLS)

我使用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 个答案:

答案 0 :(得分:1)

你应该注意两件事:

  1. 您永远不知道用户将使用哪些协议。如果未定义协议,它们将默认为http,并且某些浏览器扩展将首先尝试https并使用它(如果存在)。
  2. 如果没有更好的匹配,Apache将回退到为该端口定义的第一个站点。在这种情况下,如果您没有在端口443上定义sub2.domain.com站点,则可能最终会提供错误的站点。
  3. 因此,您应该在端口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. sub1.domain.com(TLS,证书2):类似于上面第2点中提到的sub.domain.com设置。

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

    5. 示例配置:

      <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}/%$1 [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}/%$1 [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}/%$1 [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}/%$1 [R,L]
      
      </VirtualHost>
      

      然而,如果遇到所有这些麻烦,那么可能想重新考虑不通过https提供所有服务。