An OpenBSD Workstation
I first posted my notes on using OpenBSD as my workstation in July of 2013, but I probably switched in about 2005. The following categories cover some of long-term customizations I have made as well as some hints for using more modern features.
Terminal
The most important feature of any workstation is good terminal. By default
most terminals render text with a heavier weight than I would like. To solve
this select a font with a
light
or
book
variation. Here is my invocation for the
simple terminal
st -f 'Hermit:light:pixelsize=14:antialias=true:autohint=true'
My st port includes
- The solarized color scheme
-
A modification to render
boldfonts with the weightnormal
The really compelling feature of
st
is that it automatically substitutes glyphs from the default font if the one
you've selected does not contain them. This enables me to use the really
excellent
Hermit font
while retaining the extended character set of DejaVu Sans.
To ensure you get full Unicode support from applications such as
mutt
or
tmux
set your language type using
LC_CTYPE=en_US.UTF-8 export LC_CTYPE
Resource Limits
The default process limits on OpenBSD are not nearly generous enough to run
applications such as Gimp or Chromium Be sure to raise the limits for memory
by modifying
/etc/login.conf
staff:\ :datasize-cur=16384M:\ :openfiles=16384:\
Terminate your X session with
Ctrl+Alt+Backspace
to ensure settings have taken effect.
Suspend & Resume
zzz
and
ZZZ
are shortcuts for suspend and hibernate if
apmd
is run at startup.
The
-A
flag will automatically scale the CPU frequency to save power.
Another feature of
apmd(8)
is to react to a low battery by hibernating or sleeping. This change to
rc.conf.local
reacts to a battery level of 8% or less
apmd_flags="-A -Z 8"
X Configuration: .xsession
xset -b while true; do batt="$(sysctl -n hw.sensors.acpibat0.watthour3 | cut -f1,2 -d" ")" xsetroot -name "$batt" sleep 60 done & xsetroot -solid gray40 exec dwm
xset -b
disables the annoying beep that terminals sometimes make.
I run a loop in the background that read the available battery life (Wh) and updates the window manager's display area. Any sensor data can be included in such output.
Finally set the background color and start your favorite window manager.
X Configuration: scaling
If
xenodm_flags=
is set in
rc.conf.local
then you can set the initial X display DPI at startup by modifying
/etc/X11/xenodm/Xservers
:0 local /usr/X11R6/bin/X :0 vt05 -dpi 144
After your window manager is started you can change the DPI for
X applications that are started using
xrandr
xrandr --dpi 144
Switch to an External Monitor
As far as I know, OpenBSD does not have a native way of reacting to display plug events. When connecting an external monitor I run a little script to adjust the display
#!/bin/sh xrandr --output DP-1 --auto --primary xrandr --output eDP-1 --off xrandr --output HDMI-1 --off
Where
eDP-1
is the LCD pannel on my laptop.
tmux
There's only a few tweaks I make to my terminal multiplexor's configuration. I frequently run entr in a smaller pane on the bottom
bind-key C-t split-window -p 25
I don't know of a terminal color picker, but they can be printed with a shell loop.
for i in `jot 255`; do printf "\033[38;5;${i}mcolour${i}\n" done printf "\033[0m" # reset
Then I set status background and active border to bright green
set -g status-bg colour118 set -g pane-active-border-fg colour118 set -g pane-border-fg colour30
Most importantly, clean up the status bar so that only the window names are displayed:
# remove status debris set -g status-left '' set -g status-right ''
Using Disk Encryption
OpenBSD provides software RAID by way of a virtual host bus adapter called
softraid0.
This HBA is also used for setting up disk encryption. To set use a disklabel
(in my case for
sd0g /home
set the partition type to
RAID
# disklabel -E /dev/sd0c Label editor (enter '?' for help at any prompt) /dev/sd0c> m partition to modify: [] l offset: [141362304] size: [358755776] FS type: [4.2BSD] RAID /dev/sd0c*> q Write new label?: [y]
Now configure it for crypto using
-c C
# bioctl -c C -l /dev/sd0j softraid0 New passphrase: Re-type passphrase: softraid0: CRYPTO volume attached as sd1
Mount it using the same command. The kernel log will show a new virtual device appear
sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006> sd1: 175173MB, 512 bytes/sector, 358755248 sectors
Now add a disklabel and format the encrypted volume
$ doas disklabel -E /dev/sd1c $ doas newfs /dev/rsd1a
Devices in OpenBSD may be mounted by device name or by disklabel UID which is a random id generated when the label is created.
$ disklabel /dev/sd1c | grep uid duid: 5005bf4c398ff7b9
It's this ID that we'll to mount the volume, in this way plugging in other
drives won't confuse
mount
after we prompt the user for a password on
boot. Adding the following to
rc.local
will ask for a password four times before giving up
#/etc/rc.local for attept in 1 2 3 4; do bioctl -c C -l 6bce88736e499a49.j softraid0 && break sleep 1 done fsck -y 5005bf4c398ff7b9.a mount -o nodev,nosuid,softdep,wxallowed 5005bf4c398ff7b9.a /home
That last mount parameter
wxallowed
is important because it will allow you to run certain interpreters such as
Python from a
virtualenv
in your home directory.
If you would like to enable crypto on the entire boot volume see this post by Ted Unangst.
Screen Lock
Add the following to your
.xsession
to automatically lock the screen after 5 minutes of activity
xidle -ne -delay 1 -timeout 7200 -program /usr/local/bin/slock &
To trigger this action when the system is suspended, create
/etc/apm/suspend
with an instruction to signal
xidle to run the lock program
#!/bin/sh pkill -USR1 xidle
Kerberos
If your workplace uses Kerberos there is a good chance that they provide the list of KDC servers via DNS SRV records
$ host -t srv _kerberos._udp.eradman.com
Heimdal Kerberos will do this lookup automatically. A basic configuration for
/etc/heimdal/krb5.conf
appears as such
[libdefaults] ignore_acceptor_hostname = true rdns = false default_realm = ERADMAN.COM [realms] ERADMAN.COM = { default_domain = ERADMAN.COM } [domain_realm] .ERADMAN.COM = ERADMAN.COM ERADMAN.COM = ERADMAN.COM
Now get a ticket
$ kinit
radman@ERADMAN.COM's Password: *********
$ klist
Credentials cache: FILE:/tmp/krb5cc_1000
Principal: eradman@ERADMAN.COM
Issued Expires Principal
Oct 31 10:02:30 2017 Oct 31 20:02:30 2017 krbtgt/ERADMAN.COM@ERADMAN.COM
Firefox
To enable Firefox to pick use Kerberos we need to point it to the GSSAPI library from the
heimdal
package. For automated configuration this means installing
/usr/local/lib/firefox/browser/defaults/preferences/openbsd.js
pref("network.negotiate-auth.allow-non-fqdn", true); pref("network.negotiate-auth.gsslib", "/usr/local/heimdal/lib/libgssapi.so.9.0"); pref("network.negotiate-auth.trusted-uris", "eradman.com"); pref("network.negotiate-auth.using-native-gsslib", false);
Since the OpenBSD build of Firefox is patched to use
unveil(2),
add an entry to
/etc/firefox/unveil.main
for allowing read of the Heimdal shared libraries
# kerberos /usr/lib r /usr/local/heimdal/lib r # home directory ~/ rwc
Chromium
Chromium is not built with Kerberos support on OpenBSD, but it can be added by
modifying
/usr/ports/www/chromium/Makefile
120c120 < use_kerberos=false \ - > use_kerberos=true \ 131 < extra_cppflags=\"-idirafter ... \" - > extra_cppflags=\"-idirafter /usr/local/heimdal/include ... \"
Run
make install
and a mere 24 hours later the build should be complete. A
policy file can be applied for installing the file
/etc/chromium/policies/managed/openbsd.json
{ "AuthServerWhitelist": "*.eradman.com", "GSSAPILibraryName": "/usr/local/heimdal/lib/libgssapi.so.9.0" }
The OpenBSD build of Chromium is patched to use
unveil(2),
add an entry to
/etc/chromium/unveil.main
# kerberos /usr/local/heimdal/lib r /usr/lib r # home directory ~/ rwc
As well as
/etc/chromium/unveil.utility_network
# kerberos
/usr/local/heimdal/lib r
/usr/local/lib r
/usr/lib r
After installing this file, navigate to chrome://policy to see if all settings applied.
Printers
The magic behind printing is not widely understood or documented. I always
opt for a network printer that supports PostScript. The following example is
from
/etc/printcap
lp|mfc-9340cdw:\ :lp=:rm=192.168.0.4:rp=lp:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs: office-printer:\ :lp=:rm=10.240.20.10:rp=office-printer:sd=/var/spool/output/office-printer:lf=/var/log/lpd-errs:
Be sure also to create spool directories
install -o root:daemon -m 775 /var/spool/output/office-printer
Now I can print from Firefox and other applications using
lpr -Poffice-printer
or just
lpr
at home.
Wireless/Wired
Since 6.9 dhcpleased(8) handles route updates based on DHCP offers, enabling automatic transition between wired and wireless networks
# /etc/hostname.iwm0
join radnet2 mode 11g
join Verizon-MiFi8800L wpa wpakey **********
inet autoconf
# /etc/hostname.em0
inet autoconf
Multiple default routes may be installed in this way, but link-layer protocols use the route with the highest priority.
Corporate VPN
Since 7.0 updates to
/etc/resolv.conf
are handled by
resolvd(8).
If you use a custom vpnc script use
route(8)
to make changes to routes and to nameservers
#!/bin/sh #/etc/vpnc-script case "$action" in pre-init) ;; connect) route nameserver $TUNDEV $INTERNAL_IP4_DNS $INTERNAL_IP6_DNS ifconfig $TUNDEV inet $INTERNAL_IP4_ADDRESS/$INTERNAL_IP4_NETMASKLEN route add -inet 10.0.0.0/8 $INTERNAL_IP4_ADDRESS ;; disconnect) route nameserver $TUNDEV ;; reconnect) ;; *) echo "unknown action '$action'" exit 1 ;; esac