Creating a Hollistic Work Environment
A walkthrough of my personal OpenBSD configuration and utilized software
In this post, I provide details on my after-installation OpenBSD configuration, software I use, and details on my Firefox configuration.
afterboot(8) Extras — On Openbsd
These are some things I do after a clean installation of OpenBSD for desktop use. As the title alludes to, these are things I do after reading the afterboot man page. All of this info is in the man pages and FAQ already, but this document should lay out some other things you may want to have up and running in a dissectable manner.
Root Permissions For user
# echo "permit persist keepenv :wheel" >/etc/doas.conf
In case you did not add your user to the :wheel
group during the installation, you can do so like this:
# usermod -G wheel user
Now you can do your whole system configuration as your user provided that you use the doas
command.
WIFI
Identify your network card:
$ ifconfig
Then, scan your local networks with:
$ ifconfig iwn0 scan # change "iwn0" for your network card
Once you’ve identified your network card, edit the file /etc/hostname.iwn0
adjusting the final iwn0 with your card. Finally, add your WIFI ssid and wpakey:
join wifiname wpakey wifipassword
join anotherwifi wpakey "anotherpass$123"
# randomize mac address on untrusted networks
lladdr random join wifi-name-cool wpakey "password-cool"
# ipv4
inet autoconf
# ipv6
inet6 autoconf
up
Audio
This is not necessary, but if you have a USB audio device, this is what you would use for sndiod to recognize which audio device to use:
# echo "sndiod_flags=-f rsnd/0 -F rsnd/1" >/etc/rc.conf.local
It may come useful when you least expect it.
Firewall
The following is a sane firewall configuration for your average desktop user and it will be placed in /etc/pf.conf
:
set block-policy drop
set skip on lo
match in all scrub (no-df random-id max-mss 1440)
antispoof quick for egress
# block all traffic
block
# access ipv4 and ipv6
pass out quick inet
pass out quick inet6
# for use with mail transfer agents
pass in proto icmp
Test your config and then apply:
# pfctl -fn /etc/pf.conf && pfctl -f /etc/pf.conf
Performance Optimizations
Since OpenBSD is more security oriented, the default performance can be lacking even on newer hardware. These steps should alleviate the speed issues.
Becoming a Staff Member
Add your user to the :staff group in order to access more of your system resources:
# usermod -L staff user
# usermod -G staff user
Hyper Threading
One thing that will actually increase your performance is enabling hyper threading. It is disabled by default due to some security concerns. My laptop at the time of writing is a relatively slow computer, so I can tell the difference. If your laptop is newer, say 2016 and up, you might not need it. You can test it with:
# sysctl hw.smt=1
On a thinkpad x61, the performance is immediately noticeable. firefox
becomes usable with it enabled.
Enable it permanently on next boot:
# echo hw.smt=1 >>/etc/sysctl.conf
For further performance optimizations, watch this video.
Laptop Lid
I prefer to close the lid and work on my monitor. To close the lid without sending the laptop to sleep, you do the following:
# echo machdep.lidaction=0 >>/etc/sysctl.conf
You can always run zzz
if you enabled apmd
whenever if you want to put your device to sleep, which does not require root permission in any case.
Sending mail with OpenSMTPD
OpenBSD comes with OpenSMTPD as the smtpd server and client. The following configuration will be used to send mail to the web from any accounts you wish to configure. Note that this configuration does not handle local mail. Read smtpd.conf(5) for that info.
In /etc/mail/smtpd.conf
:
# your credentials for your accounts go in this file (the "passwd" bit can be named anything):
table passwd file:/etc/mail/passwd
# configure your accounts' email, authentication protocol, port, and credentials (which
# are held in the "passwd" table) for opensmtpd to use when sending mail:
action "outbound_user" relay host smtp+tls://user@example.com:587 auth <passwd>
action "outbound_gmail" relay host smtp+tls://gmail@smtp.gmail.com:587 auth <passwd>
# tell smtpd to use those actions when sending mail with the following emails
match mail-from "user@example.com" for any action "outbound_user"
match mail-from "username@gmail.com" for any action "outbound_gmail"
Now, to edit /etc/mail/passwd
, you need to create the file and edit its permissions.
# touch /etc/mail/passwd
# chmod 640 /etc/mail/passwd
# chown root:_smtpd /etc/mail/passwd
The credentials themselves /etc/mail/passwd
:
# the first argument matches the name you gave it: smtp+tls://user@example.com:587
# the second is the username for the mail server
# also, some email servers do not acclimate your username to the server. see example
# with the first email server, and gmail
user user@.example.com:yourpassword
gmail username:yourapppassword
Everything should be in working order now. Test the configuration and restart the daemon to load your changes:
# smtpd -n && rcctl restart smtpd
Test your configuration:
$ echo world | mail -r your@mail.org -s hello your@mail.org
Now you should have OpenSMTPD working in order to send mail even when offline!
My preferred mail client is listed in the software section.
Virtual Machines: vmd
To use software not supported in OpenBSD, Windows programs with wine
, or maybe even test software you are not sure whether you trust, you cat use virtual machines as a secondary environment. The native hyper visor has no graphical support, meaning it can only connect to the console and control it through ssh
with your private interfaces. The substitute for using graphical applications is to use ssh with X11 Forwarding enabled or vnc. The latter is not worth the trouble to setup in my opinion.
I will not go into much detail, for this you best visit the faq. To get networking working, add this to the firewall at /etc/pf.conf
:
match out on egress from 100.64.0.0/10 to any nat-to (egress)
pass in proto { udp tcp } from 100.64.0.0/10 to any port domain \
rdr-to 9.9.9.9 port domain
For our pf.conf the “9.9.9.9” part is the DNS server, Quad9’s to be specific. This could be changed to your ISPs DNS servers which are located at /etc/resolv.conf
and or any other DNS server.
Next, we modify our VM settings at /etc/vm.conf
:
vm "alpine" {
disable # don't start up at boot
memory 4096M # max that can be used
disk "/home/user/vm/alpine.qcow2" # disk
cdrom "/home/user/isos/alpine-virt-3.17.3-x86_64.iso" # this cannot be a .img
owner user:user # control vm without root privs
local interface # give networking to the vm
}
Add the following lines to /etc/sysctl.conf
to allow the VM to use the internet:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
VM Guests
For my choice of VM operating system, I use Alpine Linux as it is plenty sufficient for my needs. If you need something more feature-full, I would recommend Debian Linux.
I usually like to configure X11 Forwarding on the VM so that I can use GUI programs on the native OS via any ssh
connection. It is not instant, but it is good for basic tasks. Now, to setup X11 Forwarding on your VM’s, you need to have Xorg installed, and you must activate it in /etc/ssh/sshd_config
on the VM side. Uncomment or add the following line to the mentioned file:
X11Forwarding yes
And test on your local machine with:
$ ssh -X user@100.64.1.3 gui-program # 100.64.1.3 is the local ip your vm was given
In case it asks you that the host is missing some keys, run on your local machine:
$ ssh-keygen -R 100.64.1.3
Notes on Alpine Linux for Virtualization
Add this to /boot/extlinux.conf
:
console=ttyS0,115200
It should be placed in the following highlighted section of the /boot/extlinux.conf
file:
...
TIMEOUT 5
LABEL lts
...
APPEND root=.......... console=ttyS0,115200
...
This allows the VM’s console mode to be matched with the VM guest, making the console mode much snappier.
If you want to do X11 Forwarding, then on the VM running alpine, setup xorg:
# setup-xorg-base
Next, install some packages:
# apk add wine git
Using wine
wine
is a Windows program emulator that works well in alpine linux for 64 bit programs.
Firstly, wine
can create separate environments to store your data and Windows programs on that folder. To create these environments for you to actually run .exe programs, you will need to run an environmental variable before executing your program or installer:
$ WINEPREFIX="$HOME/.wine/program-folder-name" WINEARCH=win32 wine setup.exe
To further explain, the WINEPREFIX is where the setup will extract its files and where everything will be saved from there on (except for .desktop files), and the WINEARCH=win32 specifies that the program is 32-bit. The latter only needs to be done once to specify that the WINEPREFIX is a 32-bit Windows system per se. After that, depending on whether it is a simple .exe or a setup wizard, you can launch it in various ways. I launch the programs by finding the local .exe in the WINEPREFIX folder and creating an alias for it for easy launching.
Notes On My $HOME
I try to keep things simple and rely on defaults whenever possible. Most of my programs are installed via the OpenBSD package manager. This configuration is universal for most unix systems that can build the following programs.
From here on out, it is basically a poor man’s git server. I do not modify my system enough to justify trusting GitHub or setting up a git server. So this will do.
X Configuration
Because OpenBSD’s xorg
fork has a built-in login screen, I do not go into the console directly, so, what you might place in a .xinitrc
and .profile
I condensed here into $HOME/.xsession
:
export PATH="$PATH:$HOME/.local/bin"
# make our oksh configuration visible in our X session
export ENV=$HOME/.kshrc
# Default programs:
export EDITOR="vim"
export TERMINAL="st"
export BROWSER="firefox"
export READER="zathura"
# ~/ Clean-up:
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_CACHE_HOME="$HOME/.cache"
export PASSWORD_STORE_DIR="$XDG_DATA_HOME/passwords"
# UTF-8 everywhere
export LC_CTYPE=en_US.UTF-8
export LANG=en_US.UTF-8
# firefox
export MOZ_X11_EGL=1
export MOZ_ACCELERATED=1
export MOZ_WEBRENDER=1
export DBUS_SESSION_BUS_ADDRESS="no" # this might break stuff
# Commands go after environment variables
# Disable caps and change it to compose key.
setxkbmap -option compose:caps,compose:nocaps
# Turn off caps lock if on since there is no longer a key for it.
xset -q | grep -q "Caps Lock:\s*on" && xdotool key Caps_Lock
# Decrease key repeat delay to 300ms and increase key repeat rate to 50 per second.
xset r rate 300 50
# Blue light filter. Modify "-l" flag to your coordinates
redshift -l 1.0:-1.0 -t 4800:2700 -g 0.8 -m randr -v >/dev/null 2>&1 &
# Disable core dumps
ulimit -Sc 0 &
# no more bell sound
xset b off
# when X is loaded, check for external monitor on displayport.
# If detected, switch to it and shutdown laptop screen
xrandr | grep 'DP-2 connected' >/dev/null 2>&1 &&
xrandr --output DP-2 --auto --output LVDS-1 --off >/dev/null 2>&1
# Dwm status bar
slstatus &
# Wallpaper
xwallpaper --zoom ~/pics/bg &
# Exec WM
exec dwm
Shell: oksh
oksh
is the default shell for OpenBSD. There is a port to run on other operating systems. oksh
has a default configuration which can be found at /etc/ksh.kshrc
that has some nice aliases to manage your jobs and a nice title bar configured.
Source the file locally in $HOME/.kshrc
:
. /etc/ksh.kshrc
This is my configuration:
set -o vi
alias \
v="$EDITOR" \
dv="doas $EDITOR" \
p="nsxiv" \
z="zathura" \
news='newsraft' \
t="transmission-remote" \
mpa="mpv --no-video" \
mpb="mpv --save-position-on-quit" \
yt='yt-dlp --embed-metadata -i -f "bestvideo[height<=?1080][fps<=?60]+bestaudio/best[height<=?1080][fps<=?60]"' \
yta="yt -f bestaudio/best -x --audio-format mp3 --embed-metadata --embed-thumbnail --audio-quality 320k" \
wttr='curl wttr.in/$LOCATION' \
ipp='curl ifconfig.me' \
sdn="doas shutdown -h now"
# Bash-like syntax
PS1='$(print -n "`logname`@`hostname -s`:"; [[ "${PWD#$HOME}" != "$PWD" ]] && print -n "~${PWD#$HOME}" || print -n "$PWD"; print "$ ")'
Software
Web Browser: firefox
This browser does not truly respect your privacy until you tweak a couple of things. I go in depth in below in Working with Firefox
.
Mail Client: aerc
aerc
’s defaults are quite sensible, so most of my configuration comes from how I send and receive mail. The following account configuration example is using aerc
’s built-in mail fetching and sending protocols:
[john]
source = imaps://user:PasswordExample123@mail.example.com
outgoing = smtps://user:PasswordExample123@mail.example.com
default = INBOX
from = "John Doe" <john@example.com>
cache-headers = true
[cath]
source = imaps://cath:PasswordExample123@mail.example.com
outgoing = smtps://cath:PasswordExample123@mail.example.com
default = INBOX
from = "Cath Doe" <cath@example.com>
cache-headers = true
The passwords are encrypted by default if you follow the wizard on startup.
If you have OpenSMTPD setup, or an equivalent like Postfix, you can send mail with sendmail
linked in aerc
’s account.conf file. Just change the outgoing section to the following for one or multiple accounts. And for offline mail, use your Maildir folder to access your offline mail. Modify the source section and add your mail fetch command for aerc to run automatically:
[john]
check-mail-cmd = fdm fetch
source = maildir://~/mail
outgoing = /usr/sbin/sendmail
default = INBOX
from = "John Doe" <john@example.com>
cache-headers = true
Mail Fetcher: fdm
fdm
is easier to use than the more popular alternative mbsync/isync
and is developed by a tmux
developer which was first developed for OpenBSD.
The default config file is found in $HOME/.fdm.conf
:
# define your maildir location
action "inbox" maildir "%h/mail"
# configure which accounts to fetch mail from
account "example" imaps server "example.com" user "user@example.com" pass "yourpassword"
account "gmail" imaps server "imap.gmail.com" user "yourGmail@gmail.com" pass "yourgmailapppassword"
# every mail fetched goes to the defined maildir folder
match all action "inbox"
To set the proper permissions on the file, run:
$ chmod 600 .fdm.conf
And that should be it. Beware though, by default, fdm fetches your mail from your server onto your device, meaning mail will be deleted on your server and stored locally. You can now fetch and manage your mail with fdm and your preferred mail client. To fetch your mail:
$ fdm fetch
Video/Music Player: mpv
The configuration file can be found in $HOME/.config/mpv/mpv.conf
:
# choose english audio if available
alang=eng
# turn 5.1 surround to 2.0 stereo
audio-channels=stereo
# set the highest quality video to 1080p 60fps
ytdl-format=bestvideo[height<=?1080][fps<=?60]+bestaudio/best[height<=?1080][fps<=?60]
# sane beginning size
autofit=50%
# less output
quiet
And to change a couple of keyboard bindings, change $HOME/.config/mpv/input.conf
:
# vim bindings
l seek 5
h seek -5
j seek -60
k seek 60
Other Software
Here I will put software that I do not modify or have personal configurations as such.
Window Manager: dwm
A very small and concise window manager. I run dwm
with no patches. Just bindings and default to floating mode.
Terminal: st
A very feature-less terminal that just works. For st
, I use the scrollback patch to enable scrolling.
Dynamic Menu: dmenu
Highly versatile menu used for scripting. Look at the dmenu scripts section for inspiration.
Text Editing and Text Composer: vi and vim
vim
for composing text as it supports utf-8 and vi
for everything else.
Music/Audio Player: cmus and mpv
I use cmus
for local storage and mpv
for web based music or podcast.
Checkout SomaFM if you haven’t already. You can stream the radio stations on the terminal with mpv
.
RSS Reader: newsraft
Great tool to keep you off the browser.
Torrent Client: Transmission
There are GUI and TUI interfaces out there, but the terminal client transmission-remote
works for me.
Presentations: sent
The easiest way to make presentations; just a paragraph per page. It also supports images. I use the pdf patch in order to compile it into a pdf and be able to send it to another person.
Document/PDF Viewer: zathura
A great document reader that remembers your reading progress, shows tabs, and reloads files automatically for work with TeX. After installing some plugins you can open PDF, Postscript, DJVU, EPUB, and more!
Writing Documents: TeX
To write documents in PDF format, I use TeX, the precursor of the popular LaTeX. OpTeX is a great addition to use more advanced features with the same small footprint of TeX.
Office 365 Replacement: Libreoffice
The open source, free alternative to Office 365. I do not create content with this, but this will take care of the occasional Microsoft document you have to open.
Image Viewer: nsxiv
Simple Image viewer with a nice thumbnail mode.
Image Editing: gimp and ImageMagick
gimp
for photoshop-like image editing and magick
for simple edits in the command line.
Working with Firefox
firefox
is known to phone home back to their servers. We can mitigate the tracking by customizing our profile through a user.js file.
Note that you should be able to configure your firefox
straight from this document without having to fall back to other resources. Of course, I encourage you to read the documentation for these projects, but, if you are in a hurry, this will do fine.
user.js
For this configuration, you will need the arkenfox user.js file in your profile. Your profile is your advanced configuration for firefox
. If you do not know where your profile is stored, go to about:profiles in the url bar. Once you’re in that directory, fetch the user.js file:
$ curl -sL "https://raw.githubusercontent.com/arkenfox/user.js/master/user.js" > user.js
Read the arkenfox wiki, it details the important bits about the user.js file and what problems you might be faced with in the future. Personally, I’ve done everything with this user.js without any issues, what might break stuff is any further privacy configurations added to the user.js file, which will be explained in a bit.
Now, I append more settings to the user.js from these sources:
Here is my extra.js which you can put in the original user.js. If you do not have a router of some sort with dns blocking capabilities, uncomment the last line and change the second-to-last value to 2. This will help route your dns queries through a more trustworthy source.
If the additional user.js configurations cause some mishap on your browsing, you can do without the extra.js.
Extensions
uBlock Origin
If you could only have one extension installed to your browser, uBlock Origin would be the one. It is, as the description says, a wide-spectrum blocker.
Set up your preferred blocking mode. There are a couple of them, ranging from very easy, to hard mode. I opt for the Easy mode.
Skip Redirect
This add-on skips intermediary pages found in redirect links to go straight to the target. These type of links are solely used to track you.
If you use the web archive, you need to add an exception rule, which can be done so in the No-skip-urls-list section of the extension:
web.archive.org/
True Sight
Used to find out what content delivery network (CDN) is serving your content. This is a great tool for informational purposes.
Vimium
Adds vim-like bindings to your browsing experience. This is one of the most minimal and functional vim keybinding add-on for firefox
.
Privacy-Oriented Origin Policy
This add-on replaces disabling Referrer Headers in the user.js allowing you to whitelist affected pages. I run it in aggressive mode with rare site breakage. The P.O.O.P website explains it clearly, though.
Flagfox
Another great informational add-on that shows you a flag in the url bar with the country of origin of where the server is being hosted. It can also pipe the current url to many services.
LocalCDN
Loads CDN resources locally to speed up load times and connect to these external resources less often.
play-with
I use this add-on to pipe videos, including YouTube and audio to mpv
.
List Feeds
Searches for RSS and Atom feeds in a page and lists them in the url icon.
Open in Sci-Hub
Puts a Sci-Hub icon in the url bar when visiting paywalled academic articles to easily view it in the Sci-Hub database.
OpenBSD Specifics
Unveil directories
If you are using OpenBSD, you would know that firefox
can only see directories in which you give it access to. To edit this website locally, I do:
# echo "~/content r" >>/etc/firefox/unveil.content
Once you restart firefox
you should be able to have read access to everything in the content
folder.
Unveil Software
If you want to read pdf’s directly from a document viewer instead of the firefox
pdf viewer, you need to unveil(2) the package itself, as well as making it a “default application”.
To unveil your preferred document reader, do the following:
# echo "/usr/local/bin/zathura rx" >>/etc/firefox/unveil.main
Notice the file we are writing to. It will be unveil.main
instead of unveil.content
.
firefox
is now able to read and execute zathura
, but it does not know it to be the pdf viewer. To make firefox
understand so, we do the following:
$ echo "application/pdf; /usr/local/bin/zathura %s" >~/.mailcap
Restart firefox
, go to the settings page, search for default applications, and you can now choose the option that says Use system default application next to the pdf section. You should now be able to open pdf docs directly from firefox
with a document viewer.
Video Conferences
If this is something you must do, it can be setup quite easily. You need to permit video and audio recording down to the kernel and make your webcam usable by your user:
# sysctl kern.audio.record=1
# sysctl kern.video.record=1
# chown user /dev/video0
The chown
bit only needs to be done once for your device. After a reboot, the only steps you would need to take are the first two commands. Also, the webcam can also be /dev/video1
for example.
Resources
- Software that Rocks — Brought to you by Suckless.
- The OpenBSD Guy — More OpenBSD guides.
- Why OpenBSD Rocks — Stuff that rocks.
- Permacomputing — Keepin’ it sensible.
- Running OpenBSD on your laptop is really hard (not) — It really isn’t.