About me: My name is Solène Rapenne, pronouns she/her. I like learning and sharing knowledge. Hobbies: '(BSD OpenBSD Qubes OS Lisp cmdline gaming security QubesOS internet-stuff). I love percent and lambda characters. OpenBSD developer solene@. No AI is involved in this blog.

Contact me: solene at dataswamp dot org or @solene@bsd.network (mastodon).

I'm a freelance OpenBSD, FreeBSD, Linux and Qubes OS consultant, this includes DevOps, DevSecOps, technical writing or documentation work. If you enjoy this blog, you can sponsor my open source work financially so I can write this blog and contribute to Free Software as my daily job.

Some OpenBSD features that aren't widely known

Written by Solène, on 20 February 2024.
Tags: #openbsd #unix

Comments on Fediverse/Mastodon

1. Introduction §

In this blog post, you will learn about some OpenBSD features that can be useful, but not widespread.

They often have a niche usage, but it's important to know they exist to prevent you from reinventing the wheel :)

OpenBSD official project website

2. Features §

The following list of features are not all OpenBSD specific as some can be found on other BSD systems. Most of the knowledge will not be useful to Linux users.

2.1. Secure level §

The secure level is a sysctl named kern.securelevel, it has 4 different values from level -1 to level 2, and it's only possible to increase the level. By default, the system enters the secure level 1 when in multi-user (the default when booting a regular installation).

It's then possible to escalate to the last secure level (2), which will enable the following extra security:

  • all raw disks are read-only, so it's not possible to try to make a change to the storage devices
  • the time is almost lock, it's only possible to modify the clock slowly by small steps (maybe 1 second max every so often)
  • the PF firewall rules can't be modified, flushed or altered

This feature is mostly useful for dedicated firewall with rules that rarely change. Preventing the time to change is really useful for remote logging as it allows being sure of "when" things happened, and you can be assured the past logs weren't modified.

The default security level 1 already enable some extra security like "immutable" and "append-only" file flags can't be removed, these overlooked flags (that can be applied with chflags) can lock down files to prevent anyone from modifying them. The append-only flag is really useful for logs because you can't modify the content, but this doesn't prevent adding new content, history can't be modified this way.

OpenBSD manual pages: securelevel

OpenBSD manual pages: chflags

This feature exists in other BSD systems.

2.2. Memory allocator extra checks §

OpenBSD's memory allocator can be tweaked, system-wide or per command, to add extra checks. This could be either used for security reasons or to look for memory allocation related bugs in a program (this is VERY common...).

There are two methods to apply the changes:

  • system-wide by using the sysctl vm.malloc_conf, either immediately with the sysctl command, or at boot in /etc/sysctl.conf (make sure you quote its value there, some characters such as > will create troubles otherwise, been there...)
  • on the command line by prepending env MALLOC_OPTIONS="flags" program_to_run

The man page gives a list of flags to use as option, the easiest to use is S (for security checks). It is stated in the man page that a program misbehaving with any flag other than X is buggy, so it's not YOUR fault if you use malloc options and the program is crashing (except if you wrote the code ;-) ).

OpenBSD manual pages: malloc (search for MALLOC OPTIONS)

2.3. File flags §

You are certainly used to files attributes like permissions or ownership, but on many file systems (including OpenBSD ffs), there are flags as well!

The file flags can be altered with the command chflags, there are a couple of flags available:

  • nodump: prevent the files from being saved by the command dump (except if you use a flag in dump to bypass this)
  • sappnd: the file can only be used in writing append mode, only root can set / remove this flag
  • schg: the file can not be change, it becomes immutable, only root can alter this flag
  • uappnd: same as sappnd mode but the user can alter the flag
  • uchg: same as schg mode but the user can alter the flag

As explained in the secure level section above, in the secure level 1 (default !), the flags sappnd and schg can't be removed, you would need to boot in single user mode to remove these flags.

Tip: remove the flags on a file with chflags 0 file [...]

You can check the flags on files using ls -ol, this would look like this:

terra$ chflags uchg get_extra_users.sh
terra$ ls -lo get_extra_users.sh        
-rwxr-xr-x  1 solene  solene  uchg 749 Apr  3  2023 get_extra_users.sh

terra$ chflags 0 get_extra_users.sh     
terra$ ls -lo get_extra_users.sh     
-rwxr-xr-x  1 solene  solene  - 749 Apr  3  2023 get_extra_users.sh

OpenBSD manual pages: chflags

2.4. Crontab extra parameters §

OpenBSD crontab format received a few neat additions over the last years.

  • random number for time field: you can use ~ in a field instead of a number or * to generate a random value that will remain stable until the crontab is reloaded. Things like ~/5 work. You can force the random value within a range with 20~40 to get values between 20 and 40.
  • only send an email if the return code isn't 0 for the cron job: add -n between the time and the command, like in 0 * * * * -n /bin/something.
  • only run one instance of a job at a time: add -s between the time and the command, like in * * * * * -s /bin/something. This is incredibly useful for cron job that shouldn't be running twice in parallel, if the job duration is longer than usual, you are ensured it will never start a new instance until the previous one is done.
  • no logging: add -q between the time and the command, like in * * * * -q /bin/something, the effect will be that this cron job will not be logged in /var/cron/log.

It's possible to use a combination of flags like -ns. The random time is useful when you have multiple systems, and you don't want them to all run a command at the same time, like in a case they would trigger a huge I/O on a remote server. This was created to prevent the usual 0 * * * * sleep $(( $RANDOM % 3600 )) && something that would run a sleep command for a random time up to an hour before running a command.

OpenBSD manual pages: crontab

2.5. Auto installing media §

One cool feature on OpenBSD is the ability to easily create an installation media with pre-configured answers. This is done by injecting a specific file in the bsd.rd install kernel.

There is a simple tool named upobsd that was created by semarie@ to easily modify such bsd.rd file to include the autoinstall file, I forked the project to continue its maintenance.

In addition to automatically installing OpenBSD with users, ssh configuration, sets to install etc... it's also possible to add a site.tgz archive along with the usual sets archives that includes files you want to add to the system, this can include a script to run at first boot to trigger some automation!

These features are a must-have if you run OpenBSD in production, and you have many of them to manage, enrolling a new device to the fleet should be automated as possible.

GitHub project page: upobsd

OpenBSD manual pages: autoinstall

2.6. apmd daemon hooks §

Apmd is certainly running on most OpenBSD laptop and desktop around, but it has features that aren't related to its command line flags, so you may have missed them.

There are different file names that can contain a script to be run upon some event such as suspend, resume, hibernate etc...

A classic usage is to run xlock in one's X session on suspend, so the system will require a password on resume.

Older blog post: xlock from apmd suspend script

The man page explains all, but basically this works like this for running a backup program when you connect your laptop to the power plug:

# mkdir -p /etc/apm
# vi /etc/apm/powerup

You need to write a regular script:

#!/bin/sh

/usr/local/bin/my_backup_script

Then, make it executable

# chmod +x /etc/apm/powerup

The daemon apmd will automatically run this script when you connect a system back to AC power.

The method is the same for:

  • hibernate
  • resume
  • suspend
  • standby
  • hibernate
  • powerup
  • powerdown

This makes it very easy to schedule tasks on such events.

OpenBSD manual page: apmd (section FILES)

2.7. Using hotplugd for hooks on devices events §

A bit similar to what apmd by running a script upon events, hotplugd is a service that allow running a script when a device is added / removed.

A typical use is to automatically mount an USB memory stick when plugged in the system, or start cups daemon when powering on your USB printer.

The script receives two parameters that represents the device class and device name, so you can use them in your script to know what was connected. The example provided in the man page is a good starting point.

The scripts aren't really straightforward to write, you need to make a precise list of hardware you expect and what to run for each, and don't forget to skip unknown hardware. Don't forget to make the scripts executable, otherwise it won't work.

OpenBSD manual page: hotplugd

2.8. Altroot §

Finally, there is a feature that looks pretty cool. In the daily script, if an OpenBSD partition /altroot/ exists in /etc/fstab and the daily script environment has a variable ROOTBACKUP=1, the root partition will be duplicated to it. This permit keeping an extra root partition in sync with the main root partition. Obviously, it's more useful if the altroot partition is on another drive. The duplication is done with dd. You can look at the exact code by checking the script /etc/daily.

However, it's not clear how to boot from this partition if you didn't install a bootloader or created an EFI partition on the disk...

OpenBSD manual pages: hier (hier stands for file system hierarchy)

OpenBSD manual pages: daily

OpenBSD FAQ: Root partition backup

2.9. talk: local chat in the terminal §

OpenBSD comes with a program named "talk", this creates a 1 to 1 chat with another user, either on the local system or a remote one (setup is more complicated). This is not asynchronous, the two users must be logged in the system to use talk.

This program isn't OpenBSD specific and can be used on Linux as well, but it's so fun, effective and easy to setup I wanted to write about it.

The setup is easy:

# echo "ntalk		dgram	udp	wait	root	/usr/libexec/ntalkd	ntalkd" >> /etc/inetd.conf
# rcctl enable inetd
# rcctl start inetd

The communication happens on localhost on UDP ports 517 and 518, don't open them to the Internet! If you want to allow a remote system, use a VPN to encrypt the traffic and allow ports 517/518 only for the VPN.

The usage is simple, if you want alice and bob to talk to each other:

  • alice type talk bob, and bob must be logged in as well
  • bob receives a message in their terminal that alice wants to talk
  • bob type talk alice
  • a terminal UI appears for both users, what they write will appear on the top half of the UI, and the messages from recipient will appear on the half bottom

This is a bit archaic, but it works fine and comes with the base system. It does the job when you just want to speak to someone.

3. Conclusion §

There are interesting features on OpenBSD that I wanted to highlight a bit, maybe you will find them useful. If you know cool features that could be added to this list, please reach me!