pkgbasify

I just spent the day catching up on FreeBSD email and events after a week of marshaling, and upgrading various systems to FreeBSD 15.1. Most of my various systems (servers, VMs, and jails) are still running 14.3 or 14.4 because, in my opinion, 15.0 shipped with too many unresolved warts, but now that 15.1 is out (albeit not yet announced) it is high time to not only upgrade everything to 15.1 but also make the switch to packaged base (which I was so far only using on one VM and one jail).

After a brief look at the FreeBSD Foundation’s pkgbasify script I came to the conclusion that I do not trust it to work correctly, so I developed my own method for converting a system from distribution sets to packaged base. Assuming a full install (including debug symbols, source tree, and tests) of FreeBSD 15.0-RELEASE or 15.1-RELEASE with pkg 2.7.5 recently updated to the latest patch level (if any), you can convert to packaged base with a single command:

# pkg install -r FreeBSD-base --register-only FreeBSD-set-{base,lib32,kernels}{,-dbg} FreeBSD-set-{src,tests}

(the pkg-install(8) manual page claims that you can abbreviate --register-only to -X, but you can’t, although that will be fixed in the next version)

There may be minor discrepancies between what the installer and freebsd-update(8) produced and what the packages contain, which you can usually fix with a forced upgrade:

# pkg upgrade -r FreeBSD-base -fy

If you do not have a full install, you should trim down the pkg install command line to only the sets that correspond to what you have; otherwise, the subsequent pkg upgrade will install what was missing. Particularly, you should not install FreeBSD-set-src if /usr/src is already managed by Git.

Once you’re done, you can start trimming down your system by removing sets you don’t need, then autoremoving their contents. For instance, if you’ve decided that you no longer need tests or debugging symbols:

# pkg remove -fg FreeBSD-set-\*-dbg FreeBSD-set-tests
# pkg autoremove

Note that package sets are marked vital so you must use -f when removing them.

Now is the time to enable the FreeBSD-base repository, by the way. Manually specifying it with -r FreeBSD-base temporarily enables it for the current command, but you’ll want it permanently enabled:

# mkdir -p /usr/local/etc/pkg/repos
# echo 'FreeBSD-base: { enabled: yes }' >/usr/local/etc/pkg/repos/FreeBSD-base.conf

Finally, if on bare metal or a VM, create a boot environment of your converted system:

# bectl create $(pkg query %v FreeBSD-runtime)

The only issue I’ve noticed after converting one bare-metal server and the eight jails it hosts is that pkg leaf does not take shared library dependencies into account:

# sudo pkg -j myjail leaf
FreeBSD-bluetooth-lib-15.1
FreeBSD-set-base-jail-15.1
FreeBSD-ufs-lib-15.1
FreeBSD-zfs-lib-15.1
pkg-2.7.5

Those three -lib packages provide libraries which are used by other base packages, but the dependencies are all implicit, so they show up as leaves despite not actually being removable.

I did a thing

This afternoon, I graduated from “has not yet owned an Alfa Romeo” to “currently owns an Alfa Romeo”.

Anyone who knows me will tell you I’m a car guy. And any car guy (as opposed to a Porsche guy or a Corvette guy or a Miata guy) will tell you that every car guy ought to have owned an Alfa Romeo. The problem is that in order to have owned an Alfa Romeo, you must first own an Alfa Romeo; and then, presumably, either you get rid of it or it gets rid of you, or you both get rid of each other. And until today, I had not yet owned an Alfa Romeo.

This afternoon, I graduated from “has not yet owned an Alfa Romeo” to “currently owns an Alfa Romeo”. Specifically, a 2007 Alfa Romeo 147 1.6 TS. At some point in the future, I will move on from “currently owns an Alfa Romeo” to “has owned an Alfa Romeo”, thereby completing my car guy journey; but that will take a lot of work and a bit of money, although in theory I should be able to flip it for a decent profit.

Yes, it’s red, and yes, it has little Italian flags all over.

Currently planned work:

  • Install “24h Le Mans” sticker on trunk lid for immediate 5 bhp boost
  • Change all fluids and filters
  • Replace rear wiper blade
  • Polish headlights
  • Investigate lifter tick
  • Replace clutch pump and / or follower and / or hydraulic line
  • Replace passenger side window regulator
  • Replace driver side window and mirror controls
  • Replace trunk lid lock actuator
  • Fix driver’s seat release
  • Fix or replace various bits of interior trim
  • Replace gear shift lever knob, possibly with a shorter one
  • Replace whip antenna with either bee sting or shark fin

Maybe I’ll even remember to post updates.

Update: 5 bhp boost unlocked

Close-up of the trunk lid of a red Alfa Romeo 147 1.6 TS sporting a white decal showing the outline of the Circuit de la Sarthe with the text “24h Le Mans”.

Update: of course my Italian car has electrical gremlins.

Inside view of the raised trunk lid of my Alfa Romeo 147 with the lining removed. The trunk lock is disconnected and black and red multimeter probes are inserted into the plug. I am holding the multimeter in my left hand; it is set to 20 V and the display is showing12.04.

Update 2026-03-16: I had low washer nozzle pressure and assumed the pump might need changing. Only after ordering a replacement pump from a breaker did I realize that the real issue was that the washer hose was getting pinched when I closed the hood. Cutting the cable ties that tied it to the hood strut solved the issue.

View of the front of a red Alfa Romeo 147 from right above / next to the passenger window. The hood is open and there are traces of washer fluid on it. A multimeter is propped up against the hood so that it is visible from the driver's seat. A ratchet is lying on top of the engine, which is visible through the gap between the rear edge of the open hood and the body.

Update 2026-03-19: It passed inspection today, with a slew of minor defects but little I wasn’t already aware of and nothing I can’t fix.

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.

EDIT 2024-08-07: I have yet to receive an official response from NUUG. I’ve been told out-of-band that my email has been received and my membership canceled, but I appear to still be on the mailing list. In the meantime, Norwegian magazine kode24 has written a piece on the topic, citing my tweet and this blog post, which kicked up a bit of a fuss on Twitter. Knut Yrvin chose to respond directly to my month-old tweet with a strawman and insults while Malin Bruland rode to his defense with the same strawman. I am not impressed.

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”