Configuring strict SNI with Apache httpd 2.4

Imagine the following scenario:

  1. Your web server hosts both www.example.com and www.example.net using Apache httpd with name-based virtual hosts, and the configuration is structured such that httpd sees the former before the latter. Each vhost has its own non-wildcard certificate.
  2. A user tries to access www.example.net using an old browser which does not support SNI.
  3. Since httpd cannot see the Host header without first performing a TLS handshake, and cannot perform a TLS handshake without a key and certificate, it needs to pick one blindly. In accordance with its virtual host matching algorithm, it defaults to the first configured vhost, i.e. www.example.com.
  4. The browser receives a certificate wit a CN which does not match the name of the host it is trying to access, and either throws up a scary warning or simply refuses to connect.

You might say that this acceptable — after all, it only affects a minuscule proportion of users using very old clients — but TLS validators such as Qualys SSL labs have started testing non-SNI requests, and while they don’t yet penalize servers for this issue, they might very well start doing so soon.

Apache httpd has an option called SSLStrictSNIVHostCheck which, in theory, should take care of this. But I haven’t had much luck with it (to put it bluntly: it does not seem to have any effect at all), and it appears from various discussions on Reddit, StackExchange, etc. that I am not alone. The solution I have found is to create a dummy vhost with a dummy, self-signed certificate, and ensure that it is loaded first.

The first step is to create a dummy certificate for localhost with a 100-year lifespan (unless you feel like setting up a cron job that regenerates a 90-day certificate every 30 days or so):

$ openssl genrsa -out localhost.key 2048
$ openssl req -new -key localhost.key -subj /CN=localhost -out localhost.csr
$ echo subjectAltName=DNS:localhost | openssl x509 \
    -in localhost.csr -out localhost.crt -req -signkey localhost.key -days 36525 -extfile -

Next, create a vhost configuration which uses that certificate:

<VirtualHost *:443>
  ServerName localhost
  SSLEngine On
  SSLStrictSNIVHostCheck On
  SSLCertificateKeyFile /path/to/localhost.key
  SSLCertificateFile /path/to/localhost.crt
  <Location />
    Require all denied
  </Location>
</VirtualHost>

This must be placed in a location where it will be read before any other vhost configuration, e.g. 00localhost.conf in your server’s Includes directory.

TLS connections without a server name will now be directed to your dummy vhost and fail, and Qualys will report that any site hosted on your server “works only in browsers with SNI support”.

As a footnote, my TLS configuration (derived from the Mozilla project’s recommendations) looks like this:

SSLProtocol +TLSv1.3 +TLSv1.2
SSLCipherSuite TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLCompression off

Between that, strict SNI, HSTS, and CAA, you will easily achieve an A+ score.

wtf, zsh

wtf, zsh

wtf, zsh

% uname -sr
FreeBSD 12.1-RELEASE-p10
% for sh in sh csh bash zsh ; do printf "%-8s" $sh ; $sh -c 'echo \\x21' ; done 
sh      \x21
csh     \x21
bash    \x21
zsh     !
% cowsay wtf, zsh       
 __________ 
< wtf, zsh >
 ---------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

I mean. Bruh. I know it’s intentional & documented & can be turned off, but every other shell defaults to POSIX semantics…

BTW:

% ln -s =zsh /tmp/sh
% /tmp/sh -c 'echo \x21'
\x21

Netlink, auditing, and counting bytes

In which we find bugs in both the kernel and userspace parts of the Linux audit subsystem.

I’ve been messing around with Linux auditing lately, because of reasons, and ended up having to replicate most of libaudit, because of other reasons, and in the process I found bugs in both the kernel and userspace parts of the Linux audit subsystem.

Continue reading “Netlink, auditing, and counting bytes” »

On dinosaurs and context

Some of you may know that the 2020 Hugo Award ceremony was held last night¹ and that it was hosted by George R. R. Martin. Some of you may have heard that it did not go well. Some of you may already know what happened, more or less. I watched it live, and unsurprisingly, I have opinions.

This post is not a blow-by-blow account of events or any sort of clever analysis or deep thoughts on how to move forward. Better minds than mine have already taken care of that; see for instance Natalie Luhrs’s take on the affair. Instead, I would like to offer a little bit of context for those who heard what happened (or watched it happen) and have a vague idea that it was bad but do not understand why everybody is so upset and do not want to jump down the rabbit hole of SFF fandom drama.

Continue reading “On dinosaurs and context” »

Bump

Time for my annual “oh shit, I forgot to bump the copyright year again” round-up!

In the F/OSS community, there are two different philosophies when it comes to applying copyright statements to a project. If the code base consists exclusively (or almost exclusively) of code developed for that specific project by the project’s author or co-authors, many projects will have a single file (usually named LICENSE) containing the license, a list of copyright holders, and the copyright dates or ranges. However, if the code base incorporates a significant body of code taken from other projects or contributed by parties outside the project, it is customary to include the copyright statements and either the complete license or a reference to it in each individual file. In my experience, projects that use the BSD, ISC, MIT, adjacent licenses tend to use the latter model regardless.

Continue reading “Bump” »