DNS over TLS in FreeBSD with Quad9

It has come to my attention that Quad9 have a blog post providing incorrect instructions for how to set up a FreeBSD system to use their service. I have attempted to get in touch with the author and get him to correct it but have received no response. So here, for the benefit of the Great Search Engine Gods, is the correct procedure; see my earlier post on the topic for more details on how it works.

# cat >/etc/rc.conf.d/local_unbound <<EOF
local_unbound_forwarders=" 2620:fe::fe@853#dns.quad9.net 2620:fe::9@853#dns.quad9.net"
# service local_unbound setup
# service local_unbound restart

No need to reboot.

Note that if you only have IPv4, you may experience slightly degraded performance unless you leave out the IPv6 addresses from the local_unbound_forwarders line (and vice versa in the unlikely scenario where you only have IPv6).

Automatic Let’s Encrypt certificates in Apache with mod_md

Since 2.4.30, Apache comes with experimental support for ACME certificates (Let’s Encrypt et al.) in the form of mod_md (short for “managed domains”). It’s kind of a pain but it’s still better than what I had before, i.e. a mess of shell and Perl scripts based on Crypt::LE, and if your use case is limited to Apache, it appears to be simpler than Certbot as well. Unfortunately for me, it’s not very well documented and I wasted a considerable amount of time figuring out how to use it. Fortunately for you, I then decided to blog about it so you don’t have to repeat my mistakes.

Edit: the author of mod_md, Stefan Eissing, got in touch and pointed me to his own documentation, which is far superior to the one available from Apache.

Continue reading “Automatic Let’s Encrypt certificates in Apache with mod_md”

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

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
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…


% ln -s =zsh /tmp/sh
% /tmp/sh -c 'echo \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”