Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've been having some problems setting up my apache webserver to only serve pages over https. I think I nailed it earlier this week, but after some tinkering it seems like I broke it again and I don't know when exactly I broke it.

My setup produces this output, and thus my configuration syntax should be ok:

# apache2ctl -t -D DUMP_VHOSTS
VirtualHost configuration:
192.168.0.1:80         is a NameVirtualHost
default server cal.example.com (/etc/apache2/sites-enabled/99-davical:2)
port 80 namevhost cal.example.com (/etc/apache2/sites-enabled/99-davical:2)
port 80 namevhost proius.example.com (/etc/apache2/sites-enabled/proius:1)
port 80 namevhost slnew.example.com (/etc/apache2/sites-enabled/slnew:1)
port 80 namevhost webmail.example.com (/etc/apache2/sites-enabled/webmail:1)
192.168.0.1:443        is a NameVirtualHost
default server proius.example.com (/etc/apache2/sites-enabled/proius:10)
port 443 namevhost proius.example.com (/etc/apache2/sites-enabled/proius:10)
port 443 namevhost slnew.example.com (/etc/apache2/sites-enabled/slnew:10)
port 443 namevhost webmail.example.com (/etc/apache2/sites-enabled/webmail:10)
192.168.0.1:8443       is a NameVirtualHost
default server cal.example.com (/etc/apache2/sites-enabled/99-davical:11)
port 8443 namevhost cal.example.com (/etc/apache2/sites-enabled/99-davical:11)
Syntax OK

This is how all my virtualhosts are defined:

<VirtualHost slnew.example.com:80>
 ServerName      slnew.example.com
 ServerAdmin     vvh@example.com
 DocumentRoot    /var/www/slnew
 RewriteEngine   On
 RewriteLogLevel 0
 RewriteRule     ^/(.*) https://slnew.example.com:443/$1 [L,R]
</VirtualHost>
<VirtualHost slnew.example.com:443>
 ServerName      slnew.example.com
 ServerAdmin     vvh@example.com
 DocumentRoot /var/www/slnew
 <Directory /var/www/slnew>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
 </Directory>
 LogLevel info
 ErrorLog ${APACHE_LOG_DIR}/slnew_error.log
 CustomLog ${APACHE_LOG_DIR}/slnew_access.log combined
 SSLEngine               on
 SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
 SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key
 SSLProtocol             -all +SSLv3 +TLSv1
 SSLCipherSuite          SSLv3:+HIGH:+MEDIUM
 <FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
 </FilesMatch>
 <Directory /usr/lib/cgi-bin>
  SSLOptions +StdEnvVars
 </Directory>
 BrowserMatch "MSIE [2-6]" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0
 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

When I visit my sites, I get this error in Google Chrome:

Error 107 (net::ERR_SSL_PROTOCOL_ERROR): SSL protocol error.
share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

You cannot run multiple SSL name-based virtualhosts on the same IP:port combination.

Apache has no way of knowing which one you wanted, since the Host: header is not sent until the secure channel is established, and to establish the secure channel, apache has to select a certificate to use. This is a chicken-and-egg problem.

But apart from that, you are trying to access HTTP content over an SSL connection, which produces the error you reported. This is a different issue from the certificate one.

Rule #0: do not, EVER, use hostnames in a virtualhost definition. Ever.

Rule #1: DO NOT use rewrites when anything else will do.

In the case of redirecting HTTP to HTTPS, you create as many HTTP (port 80) virtualhosts as you have SSL vhosts, and then Redirect to the SSL version for each one.

You seem to have implemented 80% of this and then gave up and thought using rewrites was a proper solution :)

Instead, replace ALL of the above with:

<VirtualHost *:80>
  ServerName slnew.example.com
  Redirect Permanent / https://slnew.example.com/
</Virtualhost>

Now the SSL portion will at least stop causing errors, but you will get the certificate warning for every SSL virtualhost that is not the canonical CN for the certificate chosen (apache will always choose the certificate defined in the first SSL vhost.)

If you really want this to work properly, each vhost needs to have its own IP, which you use in the Virtualhost definition:

<Virtualhost 55.66.77.88:443>
  ServerName slnew.example.com

etc.

share|improve this answer
3  
Actually, Apache Httpd has had support for SNI for a while. The problem comes from the client side where there are still a number of browsers that don't support it (mainly IE on Win XP and some mobile clients). Alternatively, a single certificate could be used, with multiple Subject Alt. Names. –  Bruno Jan 11 '12 at 12:23
    
True, but the OP wasn't using it and probably entirely unaware of the distinction. It also isn't JUST dependent on the client - apache must have been built with the right combination of parameters and openssl versions. It is perfectly possible to build a current apache without SNI support. –  adaptr Jan 11 '12 at 12:47
    
+1 for rule #1 anyway ("DO NOT use rewrites when anything else will do"). In my opinion, HTTP->HTTPS is something that needs to be addressed at the web application level, not purely via the server config (although this is a quicker fix indeed), for the (security) reasons stated here –  Bruno Jan 11 '12 at 12:51
    
Thank you very much. Your answer was spot-on. I have read almost all of the relevant Apache docs and quite a few tutorials, but I must confess that the configuration of a webserver is not obvious at all. The webserver is running our office webapps and it needs to be as secure as possible, that's why I started reading, exploring and tinkering. The redirect was something I had thought about myself, but in the end I just copied some settings of a trusted source. Thanks again! –  zenlord Jan 11 '12 at 20:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.