OpenBSD Journal

t2k19 Hackathon Report: unwinding in Taipei

Contributed by Peter N. M. Hansteen on from the the long unwinding road dept.

Fresh from the recent t2k19 hackathon in Taipei, Florian Obser (florian@) writes in with this report:
unwind(8) is weird. It is the first daemon I wrote without having a constant use for most of its features. slowcgi(8), slaacd(8) and rad(8) are different, I use them every day and I will notice when I break stuff.

Not so much for unwind(8). It is sitting on my laptop, which is most of the year stationary on my desk, running without any configuration. I don't use DNS over TLS (DoT) and I don't need to get past captive portals at home.

I do get reports on how well unwind(8) works when traveling and moving between networks. But there is also the odd problem. It is always a bit difficult to blindly fix these issues.

Them: So I was at this airport lounge where the captive portal did some weird things.
Me: Hmmm, right. This diff should fix it, can you try?
Them: Uhm, no, I'm now 5000km away.

So shortly before t2k19 started I figured out a way on how to test 5 captive portals for less than 2 euros:

Go to train station and use wifi there (1), take tram to next train station, use wifi there (2). Take metro for 10 minutes, use wifi in metro (3). Get out at station and use wifi there (4). Take another metro back and use wifi on that one (5).

It took me two trips (on two days) to shake out all the issues. One trip to collect data and one trip to confirm that everything works now.

With that I'm ready for the real field test and I'm happy to report that unwind got me past all encountered airport captive portals!

I managed to time my sleeping and awake time on the plane just right so that when Jasper Lievisse Adriaanse (jasper@) and I arrived at the hotel in Taipei at about 2300 local time I was sleepy again.

The next morning I ran into a few fellow developers at breakfast who had been at the hackroom the day before. I followed them and I was very curious about the hackroom since google street view showed a beauty parlor at the address. In the end it turned out that it was next door and our hackroom was in a community center. A nicely laid-out room and reasonably spacious for the number of attendees.

I started the hackathon with committing a prepared nsd(8) upgrade to 4.1.27 and bringing over the libunbound changes from an unbound(8) upgrade to 1.9.1 that Stuart Henderson (sthen@) had committed before.

unwind(8) was missing two features I wanted to get in for the 6.5 release: It is susceptible to DNSSEC stripping attacks and secondly it does not validate DoT server certificates.

The DNSSEC stripping has to wait for the next release since we were out of time and the heuristics I have in mind need a lot of testing.

So I put on my swamp waders and wandered into libressl and libunbound code to figure out how to pass in the CA certificate bundle and set the domain name.

To prevent a chicken-and-egg problem DoT servers are configured by IP address. The domain name needs to be configured in an extra step. Setting the name was easy, libunbound uses a string representation of IP#NAME@PORT to configure the DoT server. I only had to extend the grammar for unwind.conf(5) and slightly change the string construction in parse.y.

The CA certificate bundle (/etc/ssl/cert.pem) turned out to be more troublesome. The priv'sep design of unwind(8) means that the resolver process that needs access to the file is chroot(2)'ed to /var/empty and pledge(2)'ed without any filesystem access whatsoever. The traditional solution for this is to have the parent process open the file and pass a file descriptor to the child process. Neither libunbound nor the underlying libressl have an API to accept an open file descriptor. They expect a file name. An alternative would be to read in the cert bundle and pass a memory buffer to libressl. Libunbound does not provide an API for this either and due to a lazy initialization design (the ssl context is only allocated when it is first needed, not when the unbound context is created) I could not find an easy way to pass a memory buffer through libunbound to libressl.

Theo de Raadt (deraadt@) and I had discussed in the past that with pledge(2) and unveil(2) we have much more elegant tools at our disposal than chroot(2). Nobody did the work though to remove chroot(2) from our priv'sep daemons. I took the first step in unwind(8). I removed chroot(2), added the "rpath" pledge(2) and unveil(2)'ed /etc/ssl/cert.pem in the resolver process. Effectively this is as good as a chroot(2) with one file (cert.pem) inside. With all that in place it comes down to a call to ub_ctx_set_option(3) and we have server certificate validation for DoT.

Since I still had a bit of time on my hands I tackled one more issue in unwind(8): the order in which it would try different resolving strategies. This was hard-coded and even worse, written in a way that it was very difficult to change the order depending on whether a configuration file was present or not.

I rewrote this to make it configurable and it also allowed me to change the default preference to something more sensible. unwind(8) used to always prefer to recursively resolve on its own, even if a DoT name server was configured. This seemed wrong, the user made their wishes clear by configuring a DoT name server, we should prefer to use it. This also paved the way for future work to make it possible to define the order depending on network location.

Taipei was an amazing location for the hackathon. Lunch and dinner were always an adventure with a lot of pointing at pictures or waiting for that one person speaking English. People where incredibly friendly and the food always very good.

Thanks to Kevin Lo (kevlo@) for showing us around the city. I only went one day to the electronic district and had great fun there.

A big shout-out to the hotel staff. They were amazing. On the 2nd evening we came in with a group of six and they knew who we were and handed us the correct room keys. They also managed to arrange a taxi for me for 4 in the morning, discussed my options, suggested that I leave a bit earlier and had take-away coffee and a sandwich waiting for me when I stumbled into the lobby. I have never experienced this kind of service at a hotel and I have stayed in many…

Thanks to Kevin Lo and the OpenBSD Foundation for making this great hackathon possible.

Thanks very much Florian!

(Comments are closed)


Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]