1

In the past days, I was halfway successful with securing my websites. So far, I have achieved the following:

  1. Get a certificate from letsencrypt.org, securing the domains example1.com, example2.com and example3.com (RSA key size is 4096 bits, example1.com is the CN of the certificate, example2.com and example3.com are subjectAltNames)

  2. Configure Apache to use only TLSv1.2

  3. Configure Apache to use only ciphers which I am considering secure (i.e. no RC4, no SHA1, no ciphers with CBC and so on) and which provide PFS (i.e. only ciphers which offer DHE or ECDHE key exchange)

  4. Configure the virtual hosts in Apache so that there is a HTTP host and a HTTPS host for example1.com, but still only HTTP hosts for example2.com and example3.com

Please note that all three domains / virtual hosts are running on the same IP address and that I use the Apache SSL module (mod_ssl).

This configuration is working in the sense that I can view http://example1.com, http://example2.com, http://example3.com and https://example1.com exactly as intended from within the current (most recent) versions of IE 11, FF and Chrome (I am currently not interested into making things work with other browsers).

The following are the relevant snippets from my Apache configuration.

Configuration file for example1.com:

<Directory /home/www/example1>
  Require all granted
  AllowOverride none
  Options IncludesNOEXEC
  DirectoryIndex index.shtml
</Directory>    

<VirtualHost example1.com:80>

  ServerAdmin ...
  DocumentRoot /home/www/example1
  ServerName example1.com
  ServerAlias *.example1.com
  CustomLog ...
  ErrorLog ...

</VirtualHost>

<VirtualHost example1.com:443>

  ServerAdmin ...
  DocumentRoot /home/www/example1
  ServerName example1.com
  ServerAlias *.example1.com
  CustomLog ...
  ErrorLog ...

  SSLEngine on
  SSLCompression off
  SSLHonorCipherOrder on
  SSLInsecureRenegotiation off
  SSLOptions +StrictRequire

  SSLCertificateFile /etc/letsencrypt/live/example1.com/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example1.com/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/example1.com/chain.pem

  SSLProtocol TLSv1.2
  SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256

</VirtualHost>

Configuration file for example2.com (like above, but without the SSL virtual host section):

<Directory /home/www/example2>
  Require all granted
  AllowOverride none
  Options IncludesNOEXEC
  DirectoryIndex index.shtml
</Directory>    

<VirtualHost example2.com:80>

  ServerAdmin ...
  DocumentRoot /home/www/example2
  ServerName example2.com
  ServerAlias *.example2.com
  CustomLog ...
  ErrorLog ...

</VirtualHost>

The configuration file for example3.com is like that for example2.com with all occurrences of "example2" replaced by "example3".

The problem:

As soon as I add the SSL virtual host section for example2.com or / and example3.com, nor FF nor Chrome will connect to any of the HTTPS sites, i.e. this breaks https://example1.com which formerly has been working. In other words, if I change the example2.com configuration file to

<Directory /home/www/example2>
  Require all granted
  AllowOverride none
  Options IncludesNOEXEC
  DirectoryIndex index.shtml
</Directory>    

<VirtualHost example2.com:80>

  ServerAdmin ...
  DocumentRoot /home/www/example2
  ServerName example2.com
  ServerAlias *.example2.com
  CustomLog ...
  ErrorLog ...

</VirtualHost>

<VirtualHost example2.com:443>

  ServerAdmin ...
  DocumentRoot /home/www/example2
  ServerName example2.com
  ServerAlias *.example2.com
  CustomLog ...
  ErrorLog ...

  SSLEngine on
  SSLCompression off
  SSLHonorCipherOrder on
  SSLInsecureRenegotiation off
  SSLOptions +StrictRequire

  SSLCertificateFile /etc/letsencrypt/live/example1.com/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example1.com/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/example1.com/chain.pem

  SSLProtocol TLSv1.2
  SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256

</VirtualHost>

and do the same thing for example3.com, this breaks all HTTPS sites. Sometimes, IE, FF and Chrome will be able to connect to one of these HTTPS sites, but it can't be predicted to which one and under what circumstances (perhaps a cache thing - I am not completely sure).

I have sniffed the respective traffic with Wireshark, but unfortunately, that didn't lead to anything: Apache just aborts the SSL connection handshake with error code 40 / "handshake failure".

The weird thing is that all HTTPS connections (i.e. https://example1.com, https://example2.com and https://example3.com) work reliably with all three browsers if I remove the SSLCipherSuite directive from each configuration file.

I am aware that SNI would need TLSv1, but my feeling is that this is not an SNI issue. According to multiple articles, I do not need SNI even when running multiple virtual SSL hosts on the same IP address if all domain names (virtual host names) are in the same certificate, and that is exactly my situation. I'd like to stress again that using the directive

SSLCertificateFile /etc/letsencrypt/live/example1.com/cert.pem

in all three configuration files is not a typo since that one certificate carries the three domain names in it.

So, could please anybody explain what is going on there and perhaps give some hints how to achieve my goal (server side cipher suite and TLS protocol restriction like shown above, all domain names in one certificate, all virtual hosts (domains) at the same IP address)? I already have done tests with Apache 2.2 and 2.4, but to no avail.

2

You are expected to set this:

SSLCompression off
SSLHonorCipherOrder on
SSLInsecureRenegotiation off
SSLOptions +StrictRequire 

and things like that globally in /etc/apache2/mods-enabled/ssl.conf or a corresponding file in your system. I know that Apache does not like this being set up multiple times in each vhost.

And by the way, you should remove DHE-DSS ciphers, otherwise they will be disabled automatically. They rely on DSA - you do not want to have a DSA certificate to support them.

  • I didn't remove that ciphers because they would fulfill my security requirements if I had appropriate certificates, and because they don't hurt (as you have correctly stated, they are disabled automatically if there is an RSA certificate); the same is true for the ...-ECDSA-... ciphers. Nevertheless, I'll upvote your answer because you gave a valuable hint to others. But I can't accept your answer because it is wrong (indeed, I would have been very disappointed if such a massive restriction would be in Apache, let alone the fact that it is documented absolutely nowhere). – Binarus Dec 18 '15 at 18:34
0

Well, it seems that I am one of the biggest morons on the planet. The following has happened:

I have edited my Apache configuration files using the "nano" editor in Linux. I have made the configuration for the first virtual host (example1.com) by typing many things by hand or by adding small snippets via copy-and-paste piece by piece.

When creating the configuration files for the other virtual hosts, I have copied large portions from the first configuration file into the other ones. I did this using a mouse in a terminal window.

Since I had not made nano wrap the lines, it showed only the first part of every line (up to the right border of the respective window). When copying the "overflowing" lines, only that first part had been copied because the copy-and-paste via mouse is provided by the terminal and not provided by nano.

There was only one line in the files where that mattered. Could you guess which one? Of course, the longest one, i.e. the cipher suite.

That means that in the configuration files for every virtual host except the first one the cipher suite string had been cut somewhere in the middle because only the first part had been copied out of the editor window. I did not recognize that because the nano editor window was the same size every time, and thus, the cipher suite line looked the same every time (the missing part was outside the window).

Weirdly enough, Apache did not complain about the crippled cipher suite string (which in this case ended with a dash) when starting up. Since I had activated LogLevel Debug and regularly had studied all Apache log files, I really would have expected seeing some message about the malformed cipher suite string. But there was absolutely nothing.

In other words, I now have reached my goal, and the configuration which I have described above works like a charm. I apologize for the confusion.

What could we learn from that?

1) An Apache vhost may not work as expected even when its configuration is without errors, but when there are errors in the other vhost configurations.

2) ALWAYS activate line wrapping in any editor - a thing which I always do when working with Windows programs; in fact, nano / Linux is the only editor where I regularly forget to do so (although I am using other Linux editors as well).

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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