Frantisek
Frantisek

Reputation: 7703

How do I properly handle multiple VirtualHosts on one server with only one having SSL?

I have the following apache2 VirtualHost config:

<VirtualHost {my_server_ip}:443>
 ServerName securesite.com
 ServerAlias www.securesite.com
 DocumentRoot /data/web/securesite.com/
 Options -Indexes
 SSLEngine On
 SSLCertificateFile /etc/ssl/securesite.com/securesite.com.crt
 SSLCertificateKeyFile /etc/ssl/securesite.com/server.key
 SSLCertificateChainFile /etc/ssl/securesite.com/gd_bundle.crt
</VirtualHost>

<VirtualHost *:80>
 DocumentRoot /data/web/unsecuresite.com/
 ServerName unsecuresite.com
 ServerAlias www.unsecuresite.com
</VirtualHost>

The problem is that I can access https://unsecuresite.com/ and the server returns the data for securesite.com and the browser complains.

Why does this happen? Why does ServerName for 443 matches other server names?

Can I somehow handle this? Maybe catch the request, handle it with regex and redirect it to its proper place?

EDIT

ports.conf says:

NameVirtualHost *:80
Listen 80

<IfModule mod_ssl.c>
    NameVirtualHost {my_server_ip}:443
    Listen 443
</IfModule>

Upvotes: 0

Views: 55

Answers (2)

Frantisek
Frantisek

Reputation: 7703

I solved it with the following method:

<VirtualHost {my_server_ip}:443>
 ServerName securesite.com
 ServerAlias www.securesite.com
 DocumentRoot /data/web/securesite.com/
 Options -Indexes
 SSLEngine On
 SSLCertificateFile /etc/ssl/securesite.com/securesite.com.crt
 SSLCertificateKeyFile /etc/ssl/securesite.com/server.key
 SSLCertificateChainFile /etc/ssl/securesite.com/gd_bundle.crt
 RewriteEngine on
 RewriteCond %{HTTP_HOST} !^(www\.)?(securesite\.com){1}$ [NC]
 RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [R=301]
</VirtualHost>

Upvotes: 0

Lekensteyn
Lekensteyn

Reputation: 66485

When you connect to https://securesite.com/, then you are actually connecting to port 443. Since there is only one site listening on port 443, the first match is returned (even though the ServerName does not match.

Your configuration basically boils down to:

<VirtualHost {my_server_ip}:443>
 ServerName securesite.com
 # ...
</VirtualHost>

<VirtualHost *:80>
 ServerName unsecuresite.com
 # ...
</VirtualHost>

This means that any request to port 80 (http) will be served by unsecuresite.com and requests to port 443 (https) are served by securesite.com.

Even if you add a <VirtualHost *:443> ServerName unsecuresite.com, you can still not simply trick the user to redirect without having a valid certificate for unsecuresite.com. (That would result in a ugly certificate warning.)

If your unsecuresite.com vhost is not supposed to handle HTTPS, then just ignore it. With nginx you could reset a connection if the hostname does not match, I don't know if something similar exists for Apache.

Upvotes: 1

Related Questions