简体   繁体   中英

Apache 2.4 Restrict SSL to specific subdomain Vhosts

I have a single digitalocean droplet, with only a single IPV4 address possible. I would like to use SNI to apply TLS (SSL) encryption onto only a specific subdomain, and not any other parts of the domain.

Example being:

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

I'm using LetsEncrypt for the certificates, so wildcard domains are not possible.

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>

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.
  2. Apache will fallback to the first site defined for that port if there's not a better match. 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.

So you should define all 4 domains on both port 80 and port 443 and basically have 8 vhosts defined.

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.

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

  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

  3. sub1.domain.com (TLS, certificate 2): Similar to sub.domain.com setup mentioned in point 2 above.

  4. sub2.domain.com (no TLS): Similar to domain.com set up mentioned in point one above.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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