简体   繁体   English

Apache 2.4 将 SSL 限制为特定子域 Vhosts

[英]Apache 2.4 Restrict SSL to specific subdomain Vhosts

I have a single digitalocean droplet, with only a single IPV4 address possible.我有一个 digitalocean droplet,只有一个 IPV4 地址。 I would like to use SNI to apply TLS (SSL) encryption onto only a specific subdomain, and not any other parts of the domain.我想使用 SNI 仅将 TLS (SSL) 加密应用于特定的子域,而不是域的任何其他部分。

Example being:例子是:

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

I'm using LetsEncrypt for the certificates, so wildcard domains are not possible.我使用 LetsEncrypt 作为证书,所以通配符域是不可能的。

domain.com.conf域名.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子域名.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 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 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>

Two things you should be aware of:你应该注意两件事:

  1. You never know which protocols users are going to use.您永远不知道用户将使用哪些协议。 They will default to http if protocol not defined and some browser extensions will try https first and use that if it exists.如果协议未定义,它们将默认为 http 并且某些浏览器扩展将首先尝试 https 并使用它(如果存在)。
  2. Apache will fallback to the first site defined for that port if there's not a better match.如果没有更好的匹配,Apache 将回退到为该端口定义的第一个站点。 In which case you might end up serving the wrong site if, for example, you don't define a sub2.domain.com site on port 443.在这种情况下,如果您没有在端口 443 上定义 sub2.domain.com 站点,那么您最终可能会为错误的站点提供服务。

So you should define all 4 domains on both port 80 and port 443 and basically have 8 vhosts defined.因此,您应该在端口 80 和端口 443 上定义所有 4 个域,并且基本上定义了 8 个虚拟主机。

This also means will need to buy (or get for free from LetsEncrypt) certificates to cover all domains and not just the two you want to serve over https.这也意味着需要购买(或从 LetsEncrypt 免费获得)证书以涵盖所有域,而不仅仅是您想通过 https 提供服务的两个域。

Then you should use redirects appropriately:那么你应该适当地使用重定向:

  1. domain.com (No TLS): Serve site on port 80. Config for port 443 should just redirect all traffic back to equivalent page on http://domain.com domain.com(无 TLS):在端口 80 上服务站点。端口 443 的配置应该只是将所有流量重定向回http://domain.com上的等效页面

  2. sub.domain.com (TLS, certificate 1): Serve site on port 443. Config for port 80 should just redirect all traffic back to equivalent page on https://sub.domain.com sub.domain.com(TLS,证书 1):在端口 443 上服务站点。端口 80 的配置应该将所有流量重定向回https://sub.domain.com上的等效页面

  3. sub1.domain.com (TLS, certificate 2): Similar to sub.domain.com setup mentioned in point 2 above. sub1.domain.com(TLS,证书 2):类似于上面第 2 点中提到的 sub.domain.com 设置。

  4. sub2.domain.com (no TLS): Similar to domain.com set up mentioned in point one above. sub2.domain.com(无 TLS):类似于上面第一点中提到的 domain.com 设置。

Example config:示例配置:

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

However if going to all this hassle then might want to rethink not serving everything over https.但是,如果要解决所有这些麻烦,那么可能要重新考虑不通过 h​​ttps 提供所有服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM