Title: Some OpenBSD features that aren't widely known
       Author: Solène
       Date: 20 February 2024
       Tags: openbsd unix
       Description: In this article, you will learn about some OpenBSD
       features you may not know about
       
       # 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 :)
       
 (HTM) OpenBSD official project website
       
       # 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.
       
       ## 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.
       
 (HTM) OpenBSD manual pages: securelevel
 (HTM) OpenBSD manual pages: chflags
       
       This feature exists in other BSD systems.
       
       ## 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 ;-) ).
       
 (HTM) OpenBSD manual pages: malloc (search for MALLOC OPTIONS)
       
       ## 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
       ```
       
 (HTM) OpenBSD manual pages: chflags
       
       ## 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.
       
 (HTM) OpenBSD manual pages: crontab
       
       ## 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.
       
 (HTM) GitHub project page: upobsd
 (HTM) OpenBSD manual pages: autoinstall
       
       ## 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.
       
 (HTM) 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:
       
       ```shell
       # mkdir -p /etc/apm
       # vi /etc/apm/powerup
       ```
       
       You need to write a regular script:
       
       ```shell
       #!/bin/sh
       
       /usr/local/bin/my_backup_script
       ```
       
       Then, make it executable
       
       ```shell
       # 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.
       
 (HTM) OpenBSD manual page: apmd (section FILES)
       
       ## 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.
       
 (HTM) OpenBSD manual page: hotplugd
       
       ## 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...
       
 (HTM) OpenBSD manual pages: hier (hier stands for file system hierarchy)
 (HTM) OpenBSD manual pages: daily
 (HTM) OpenBSD FAQ: Root partition backup
       
       ## 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:
       
       ```shell
       # 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.
       
       # 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!