What year is it, NUUG?

The Norwegian Unix User Group is celebrating its 40th anniversary on August 10. I was invited to speak at the event and initially accepted, but after learning of the schedule for the event, which was not communicated to me at the time, I have decided to withdraw.

The Norwegian Unix User Group was founded in 1984, and is celebrating its 40th anniversary on August 10. A short while ago, I was approached by a member of the organizing team (whom I shall not name) and asked to speak at the event as a representative of the Norwegian BSD community. I was given no information about the event beyond what was expected of me (a 30-minute presentation on the topic of my choice) and the names of some of the other speakers. After some hesitation, as I was having a hard time coming up with a topic that I felt would fit the occasion, I initially accepted.

One thing I found odd was that NUUG’s own event calendar (archive) has no information about the event beyond a time and a place. I get that the list of speakers is not yet finalized, even though there’s less than a month to go, but there is literally nothing beyond “more information to come”. All the links just point back to the same page.

Screenshot of NUUG’s event calendar as of 2024-07-12

This morning, someone pointed out to me that there is a registration page (archive) for the event (which, again, NUUG’s own website does not link to or even mention!) with extensive information about the event. And that information… is not good.

Screenshot of a portion of the registration page for NUUG's 40th anniversary celebration, which includes the finale of Miss Norway 2024 and an opportunity to take photos with the contestants.
Screenshot of a portion of the registration page as of 2024-07-12

tl;dr: the event is collocated with the Miss Norway 2024 finals and attendees are promised opportunities to have their pictures taken with the winners and runners-up.

WHAT THE EVERLOVING FUCK, NUUG?

It goes without saying that I will not be speaking at this event. I will try to turn my presentation (which I’d only outlined, not written yet) into a blog post, but no promises. It would have been a reflection on what “Unix” actually means (beyond the simple fact of the trademark) and how that has changed over the years.

If you’re a member (and perhaps even if you’re not), I encourage you to contact NUUG and let them know your thoughts on this matter.

EDIT: I have written to NUUG to ask them to either change their plans for the event, in which case I will be happy to attend and speak, or cancel my membership. I will update this post again when (if) they respond.

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_enable="yes"
local_unbound_tls="yes"
local_unbound_forwarders="9.9.9.9@853#dns.quad9.net 149.112.112.112@853#dns.quad9.net 2620:fe::fe@853#dns.quad9.net 2620:fe::9@853#dns.quad9.net"
EOF
# 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
  </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