Adventures in BSD 🐡

Root sets sail with his trusted blowfish companion to explore the vast world of 4.4 BSD UNIX-like operating systems!

By Root BSD

I took control of my daemons with rcctl(8)!


All *nix like operating systems have a system services or daemons manager. In most GNU/Linux systems it's systemctl, sv, rc-service or something similar. On FreeBSD it's service, and on OpenBSD it's rcctl(8).

On OpenBSD services are basically shell scripts that are stored in the /etc/rc.d/ directory. The main configuration files are /etc/rc.conf and /etc/rc.conf.local for user-specific settings. The /etc/rc file is a system startup script run by init on autoboot or after single-user startup.

Some features of rcctl(8) need to be ran using doas(1) or as root. Others don't like checking the status of a daemon. For example,

rcctl -df check unbound doing _rc_parse_conf doing _rc_quirks unbound_flags empty, using default >-c /var/unbound/etc/unbound.conf< doing _rc_parse_conf /var/run/rc.d/unbound doing _rc_quirks unbound doing rc_check (ok)

This will give me basic information on what the unbound daemon is doing. The command after the -df option is called an action argument. Removing the -df option will just give you the basic status of the daemon, usually either (ok) or (failed).

The main commands for rcctl(8), are start, stop, reload, restart, enable and disable. Those are pretty self-explanatory. Start and stop are temporary, enable/disable are persistent across boots. As mentioned previous the -df option will output more information as the commands are ran, sort of like a verbose option.

doas rcctl -df restart tor doas rcctl reload sndiod

The get command displays the value of the service or daemon variable. For example,

rcctl get sndiod
sndiod_class=daemon sndiod_flags= sndiod_logger= sndiod_rtable=0 sndiod_timeout=30 sndiod_user=root

You can include a variable to search for information, like this,

rcctl get sndiod user root

The variables that can be used are class, flags, logger, status, timeout or user. You can set the get command to “all” to get a full listing of all the service values and variables on the system.

rcctl get all | grep "NO"

Will output a list of all the services whose flags are set to “NO”. The getdef command is like get but returns all the default values of the daemons. The ls command can be used with ls arguments or lsargs, for example

doas rcctl ls on

This will list all the system services and daemons that are currently enabled. The ls arguments are all, failed, off, on, rogue, started or stopped. The argument rogue is interesting, it lists daemons which are disabled, but are still currently running.

The order command is useful when a new package daemon is started and it needs to be ran before other already enabled daemons, placing it at the beginning of pkg_scripts.

Last is the set command, which can set the status variable of a service or daemon to on or off. The set command is also used to configure flags and options for specific daemons. For example,

doas rcctl set apmd status on doas rcctl set apmd flags -A this writes “apmd_flags=-A” to the /etc/rc.conf.local file

This sets the status of the apm(8) daemon to on, the sets the flags to -A for automatic power management.

doas rcctl set sndiod flags -e s24le4lsb -z 400 -s default -m play,mon -s mon

That enables daemon specific settings for sndiod(8), the encoding is set to it's highest possible value, the audio device block size to 400 frames (120Hz), the exposed sub-devices to default, the mode to playback and monitoring, and another monitoring sub-device. These flags are detailed in the sndiod(8) manpage. Once again this command writes to the /etc/rc.conf.local, so it is not necessary to manually edit that file.

The rcctl(8) utility is a simple and effective tool for managing system services and daemons in OpenBSD. You can also write your own daemons, place them in the /etc/rc.d directory and start/enable them with rcctl(8). Everything is K.I.S.S., simple, elegant and straightforward. That's the OpenBSD way. I hope you learned something new. I sure did. May your UNIX beard grow long and your knowledge increase, and as always, happy hacking in OpenBSD!


Configuring the apm(8) (power management) daemon to automatic, then enabling it to start every boot.

by Root BSD

Learning the man(1) page system, and apropos(1)!

A funny joke I've heard about retail is that in the United States, the customer is always right. In France, the customer is king. In Japan, the customer is god! Well, when a unhappy patron to a French shop complained about the service, they reminded the store owner that in France the customer is king! The owner then replied, “Madame, this is Paris. We have cut off the heads of our kings!”

The manual pages in OpenBSD are definitely king, and they're always right. If not, it is considered a bug. So I wanted to make sure I knew more about the manual system, and how I could make it more useful to me in my quest to learn the OpenBSD base system.

What's great is in OpenBSD the manpages have their own manpage!

$ man man

This will give you a rundown of how to use the manual page system. Pages may be viewed by category (section) or machine architecture (subsection). You are first met with a group of command line options for specific use cases and queries. For example

$ man -c cat | col -b > cat

Will pipe the standard output of cat(1) to col(1), which will remove it's markup and save it to a plain text file called cat. The command man -f is the same as whatis(1)

man -f pkg_add pkg_add(1) - install or update software packages whatis pkg_add pkg_add(1) - install or update software packages

The -h option will display the SYNOPSIS section of the page only. The -k option is the same as apropos(1). man -k pkg will display a list of every manual page that has “pkg” in it's title, apropos will do the same exact thing with apropos pkg

The manual pages are broken up in sections, numbered 1-9

1 General commands (tools and utilities). 2 System calls and error numbers. 3 Library functions. 3p perl(1) programmer's reference guide. 4 Device drivers. 5 File formats. 6 Games. 7 Miscellaneous information. 8 System maintenance and operation commands. 9 Kernel internals.

The -s option specifies a section to look at for man page listing. For example the -k option I discussed earlier can be combined with -s. man -k -s 3p pkg will only look in the perl(1) programmer's reference guide for pages with “pkg” in the title.

Another cool thing I learned is the MANPAGER environment variable. By default, less(1) is used for the manuals pagination (how it's displayed). But you can specify any program and use the -T option (defined in the mandoc(1) manpage) to format the manual to something that be understood by your desired MANPAGER. For example, MANPAGER=links man -T html ls will display the manual page for the ls(1) command in html on the links terminal web browser.

The following output formats are supported, ascii, html, the default of locale, man, markdown, pdf, ps, tree, and utf8. Yes, that's right, you can view your manual pages in you favorite pdf viewer!

man -T ascii -O width=65 pledge | col -b

This will ignore any UTF-8 characters, remove markup and change the width of the text body. This can be useful for quoting manpage entries in emails, blogs, etc.

Now on to apropos(1), pronounced a-pruh-pow. A manpage database is generated by makewhatis(8), apropos(1) and whatis(1) will query that database to help you search and list manual pages by section and description. For example,

apropos -s 1 . | grep "files" | less

This command will display the titles and descriptions of every manual page in section 1 (general commands (tools and utilities)) that have the word “files” in their descriptions and pipe the list into less for easy browsing. This would be a fantastic way to really explore and learn about all the different commands and utilities that are in the OpenBSD base system, as I don't know them all!

apropos(1) command line options are very similar to the man(1) command line options, however apropos(1) can even search using expressions and macros, a use case a little too advanced for my current needs, but really cool none the less, like this example from the apropos(1) manpage,

“Search for manuals in the library section mentioning both the “optind” and the “optarg” variables:”

$ apropos -s 3 Va=optind -a Va=optarg getopt(3) - get option character from command line argument list getopt_long, getopt_long_only(3) - get long options from command line argument list

Well that's enough for today. I definitely learned a lot about using OpenBSD's manual pages system and the apropos(1) command. This is a good foundation for digging deeper into the base system and all that it has to offer. As always, I hoped you learned something new. Happy hacking in OpenBSD!


An example usage of the apropos(1) command piped to grep(1).

By Root BSD

Today I generated a secure ssh key pair using ssh-keygen(1)!

I do own a bare metal server running OpenBSD 7.0 -stable that is stored at a private location. It's been up for a couple months now. Root ssh logins are disabled, but my user is only using a password login. Let's use ssh-keygen(1) to generate a private and public key to exchange between the two machines.

ssh-keygen(1) uses a mathematical process called the Diffie-Hellman key exchange, this comprises of both public variables and private variables. Variables from both keys are mixed with the public key, then exchanged to either side to be finally mixed with the local keys. The final product is a shared secret, whereas an attacker who can only see the public information can't extract necessary data from either side of the private variables to break the key exchange (i.e. my laptop to my server).

First, after a cursory glance at the ssh-keygen manpage, I thought it would be prudent to generate groups for use in Diffie-Hellman group exchange. This is called MODULI GENERATION (per the manpage),

“Generating these groups is a two-step process: first, candidate primes are generated using a fast, but memory intensive process. These candidate primes are then tested for suitability (a CPU-intensive process).”

# ssh-keygen -M generate -O bits=2048 moduli-2048.candidates

Then we screen the prime candidates for suitability,

# ssh-keygen -M screen -f moduli-2048.candidates moduli-2048

Then install the candidates to /etc/moduli. Now it wasn't specific on how I should do this, so I backed up the original moduli file just in case

doas cp -v /etc/moduli /etc/moduli.bak doas cp -v moduli-2048.candidates /etc/moduli

Alright, I hope I did that right.

Now we generate our keys. Using the -t option we have the choice of, “dsa”, “ecdsa”, “ecdsa-sk”, “ed25519”, “ed25519-sk”, or “rsa”. I chose ed25519 because I've heard it is a very strong cipher. Potentially overkill for my use case, but that's ok!

ssh-keygen -t ed25519

I entered a strong, super secret passphrase,

Your identification has been saved in /home/glitch/.ssh/id_ed25519
Your public key has been saved in /home/glitch/.ssh/
The key fingerprint is: REDACTED

I can't show you that output, that's the private bit I don't want the attackers to see!

Now we need to copy over the public key to the server. This part was a bit of fun because OpenBSD does have the popular tool, ssh-copy-id. So it's time to properly use the most misunderstood tool in the UNIX toolbox, cat(1), which is short for concatenate. Concatenate means to connect or link in a series or chain, in this case the standard input of the public key is linked to ssh to write to a “authorized_keys” file.

cat /home/glitch/.ssh/ | ssh user@remotelogin "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Now I'm all good to go!

ssh Enter passphrase for key '/home/user/.ssh/id_ed25519':

Perfect! I made sure to run doas syspatch(8) to apply the latest security patches and fw_update(8) for firmware updates to my server. We owe a lot of gratitude to the OpenBSD project for OpenSSH, for they originally created it. It feels good that smarter people than me figured out these clever ways for people to login and communicate with machines over the network in a secure and private manner.

That was a pretty fun exercise, I learned something and I hope you did too. As always, happy hacking in OpenBSD.


by Root BSD

My first time ever setting up local unbound(8)!

So awhile ago a friend of mine on the fediverse was talking about not trusting your ISP to do your DNS resolving, but resolving your DNS locally (i.e. rolling your own DNS server), for more privacy. I've used dnscrypt-proxy before in the past, but OpenBSD has it's own DNS validating resolver, unbound(8). I have never use unbound(8) before so I'm a total amatuer at this, take it easy on me, this was my first time setting something like this up!

I had a lot help from this guide here,

To begin we enable and start the unbound daemon,

doas rcctl enable unbound doas rcctl start unbound

Then we need to set /etc/resolv.conf to

doas rcctl stop resolvd

Replace the existing nameserver in the resolv.conf with this,


Test unbound(8) to make sure it's working with dig, a DNS lookup utility,


; <<>> dig 9.10.8-P1 <<>> ;; global options: +cmd ;; Got answer: ;; –>>HEADER<<– opcode: QUERY, status: NOERROR, id: 2971 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ; IN A


;; Query time: 449 msec ;; SERVER: ;; WHEN: Wed Jan 05 00:40:54 MST 2022 ;; MSG SIZE rcvd: 56

Voila! It works as expected. Then we can enable DNSSEC with unbound-anchor(8). unbound-anchor(8) performs setup or update of the root trust anchor for DNSSEC validation (per the manpage). This downloads something called the KSK or root key signing key.

doas unbound-anchor -a "/var/unbound/db/root.key"

Then you can configure unbound(8) via /var/unbound/etc/unbound.conf. The KSK is signing and verifying the DNS entries to ensure privacy and prevents something like DNS cache poisoning or spoofing. I chose to use a root-hints file, (unbound does have it's own as well), but this appeared to be a better option in the unbound.conf(8) manpage,

“Read the root hints from this file. Default is nothing, using builtin hints for the IN class. The file has the format of zone files, with root nameserver names and addresses only. The default may become outdated, when servers change, therefore it is good practice to use a root-hints file.”

root-hints: “/var/unbound/db/root.hints” auto-trust-anchor-file: “/var/unbound/db/root.key” qname-minimisation: yes

Then I retrieved a root.hints file, is a master list of primary root DNS servers worldwide. Using OpenBSD's native tools, ftp(1)

cd /var/unbound/db doas ftp && doas mv named.root root.hints

You can also do it like this,

ftp -S do -o /var/unbound/db/root.hints

Then we can use the unbound-checkconf(8) tool to make sure I didn't make any errors,

doas unbound-checkconf unbound-checkconf: no errors in /var/unbound/etc/unbound.conf doas rcctl restart unbound doas rcctl disable resolvd to disable overwriting of my /etc/resolv.conf

Everything works, I performed some tests from the article linked above, rebooted the machine and everything works great! DNS caching is resolved locally, I think I'm doing everything right. It was suggested in the article that I can use nsd(8) in conjunction with unbound. nsd(8) an implementation of an authoritative DNS nameserver. I will look into that at a later date.

I also enabled randomized MAC addresses to be assigned to my wifi for extra privacy and security, by adding this to my /etc/hostname.interface

lladdr random nwid (network id) wpakey (wifi passphrase)

The link layer address is set to random. I put on my tin foil hat and feel safer now!

All in all, I am happy to finally try out unbound(8) and learn more about these tools. As I said, this is my first time doing this so I'm a bit of a noob. Well that's all, happy hacking in OpenBSD!


by Root BSD

Today I learned some cool new things about tmux(1),xterm(1), and installed the source tree via cvs(1).

Day 3 into the challenge and I'm getting some cool refreshers about using xterm(1) and tmux(1). Turns out my problem with tmux is because the -2 flag needs to be set for 256 color mode in the terminal (my main terminal sakura doesn't require this). I was unsuccessful in getting 256 color-mode set in ~/.tmux.conf. So I set this in my ~/.cwmrc

xterm -e tmux -2

Simple enough! The tmux(1) man page was pretty lengthy, so I made heavy use of the / command to find right keywords to get me going. Setting colors for the window statuses is done like this,

setw -g window-status-current-style 'fg=colour0 bg=colour36 bold' setw -g window-status-current-format ' #I#[fg=colour0]:#[fg=colour0]#W#[fg=colour0]#F '

setw -g window-status-style 'fg=colour49 bg=colour233' setw -g window-status-format ' #I#[fg=colour192]:#[fg=colour193]#W#fg=colour194]#F '

window-status-current is the active tab, window-status-format is the inactive tab. The clock on the right hand side is set like this,

set -g status-right '#[fg=colour233,bg=colour42] %m/%d #[fg=colour233,bg=colour42] %I:%M:%S '

There is also a clock-mode-style option to set 12 or 24 hour formats.

Control of tmux(1) is pretty straightforward. CTRL-b is the prefix key. C-b “ will split the window horizontally, C-b % will split the window vertically. C-b c will open a new window in a tabbed arrangement, windows are numbered beginning with 0. C-b arrow key will move you to your desired frame. C-b C-arrows resize panes, C-b ! will break your current frame from the panes into it's own tab, etc. The tmux(1) manpage has a detailed list of all the keybindings. They can be configured in the ~/.tmux.conf

Another cool feature I discovered is attach/detach client feature. C-b d will “detach” the client, basically suspending all your work to memory. Then resume with tmux attach, really neat stuff. I feel like I'm only scratching the surface of what I can do with tmux. I normally just use it because I'm a tabbed window manager kind of guy and I don't want 20 terminals open, rather one terminal open with tmux doing the heavy lifting for me.

Another really cool thing I learned is how to resize the internal border (space between text and window border) in xterm(1), it can be done with the -b flag or in the ~/.Xdefaults(or .Xresources)

xterm*internalBorder: 8

If only xterm(1) did better with transparency, I may switch to it on my production machine. Normally I use the sakura terminal.

I also went ahead and installed the entire OpenBSD source tree via anoncvs. Instructions are listed in the anoncvs section on OpenBSD's main website. The key thing is to setup your src ports and xenocara folders to belong to the wsrc group. However I was still not getting write permissions so I just set my user as the folder's owner. Don't know if this is cheating or not, but they advised not to do too much as root.

chown user src ports xenocara

Well that's enough for today. I also found a neat way to read gopher sites through links fb via's gopher proxy lite.

Gopher is an alternative web protocol and gopher sites are called 'gopher holes'. A lot of interesting reads can be found in gopher holes. I also found a gemini portal for the gemini protocal, but many of the listed sites didn't work. I'll look more into that.

All in all using OpenBSD this way is opening my mind to a based kind of simplicity in OpenBSD that I knew was there, but never really forced myself to learn it. I realize now just how bloated my normal way of using the machine is. Now I understand that the software in ports is there for us to use and enjoy, however base tools, command line tools do take it to a calmer level of computer interaction. I expect this month to really change the way I use an OpenBSD system going forward. Anyways, happy hacking in OpenBSD!

Also, please forgive me but I installed scrot. No more photos of the LCD screen with my phone, that just didn't feel right.

Tmux beauty

My tmux rice!

Installing the source tree

Installing the source tree via anoncvs.

by Root BSD

I'm beginning to really like cwm(1)!

The majority of the time on the laptop today was spent learning cwm(1) or the calm window manager. Just a quick note, the number appended to the base utility represents it classification in the manual system,

1 General commands (tools and utilities). 2 System calls and error numbers. 3 Library functions. 3p perl(1) programmer's reference guide. 4 Device drivers. 5 File formats. 6 Games. 7 Miscellaneous information. 8 System maintenance and operation commands. 9 Kernel internals.

The man page for cwmrc(5) is absolutely fantastic! The calm window manager was definately designed to be K.I.S.S. (keep it simple stupid) in nature. Whenever I try to learn a new window manager I generally go online to find an example configuration file. A example configuration file was included in the cwmrc(5) man page. Using ctrl + v, I copied it into vi(1) and began to edit. vi(1) quickly started to get on my nerves. The modal nature of the program forces me to be slow and constantly think about pressing the correct command, what mode I'm in, and is a little less forgiving to mistakes. So I switched over to mg(1) and I like it much more to be honest. It feels like a good old fashion text editor, like wordstar in MS-DOS. It's actually an emacs clone, so you use emacs keys to control it. I only need the C-x C-x, C-x C-c key combos (save and quit).

Back to the subject of cwm(1). I was able to learn a lot in a short period of time just modifying the example .cwmrc file and having the cwmrc(5) manpage in a vertical tmux(1) pane to the right. Honestly, I don't know how people did work in the terminal before tmux(1) or GNU screen.

Key things learned -

1) Pressing the alt key with M1 (left mouse button) will allow you to move a window with the mouse, the right mouse button will allow you to resize a window.

2) group-only-[n] shows only group n, where n is 1-9, hiding other groups(windows/frames). This is cwm's approach to workspaces basically. Very useful on a laptop where the screen real estate is limited.

3) From what I can tell so far, unless I missed something, cwm(1) is absolutely a manual tiler. The word layout wasn't even in the manpage.

4) cwm(1) doesn't appear to have an exec command (application autostart). Which is disappointing because I always have ratpoison/starfish autostart a terminal + tmux(1) when I login.

My .cwmrc so far, the bold text is just comments, interprets # as markdown headings, so just ignore that.

set default Xft(3) font

fontname “Input Mono:pixelsize=14:bold”

Turn on sticky-group mode

sticky yes

Any entry here is shown in the application menu

command links “links -g" command term “xterm -e tmux” command toot “xterm -e toot tui” command calc xcalc


borderwidth 3 color activeborder darkblue

Autogroup definitions

autogroup 3 “aterm,XTerm” autogroup 3 “xterm,XTerm”

Ignore programs by that name by not drawing borders around them.

ignore xcalc ignore xclock

Key bindings

bind-key CM-r restart bind-key 4-Return “xterm -e tmux” bind-key C4-equal window-vmaximize bind-key C4S-equal window-hmaximize bind-key M-1 group-only-1 bind-key M-2 group-only-2 bind-key M-3 group-only-3 bind-key MS-1 window-movetogroup-1 bind-key MS-2 window-movetogroup-2 bind-key MS-3 window-movetogroup-3 unbind-key 4-o unbind-key CM-equal unbind-key CMS-equal

Mouse bindings

bind-mouse M-2 window-lower bind-mouse M-3 window-resize

I love simple, uncomplicated config and this is almost as small as my sdorfehs(ratpoison) config.

Misc things -

1) I added this alias to my .kshrc to make drive identification easier, sysctl hw.disknames just doesn't cut it for me.

alias drives="dmesg | grep '^[ws]d.*[0-9]'"

2) This stops the obnoxious terminal beep, in the ~/.Xdefaults config


3) To stop screen tearing when I opened a terminal, or the visual bell flashed, I created this 20-intel.conf file in /etc/X11/xorg.conf.d/

Section "Device" Identifier "Intel Graphics" Driver "intel" Option "TearFree" "true" EndSection

In closing it was a good day. I realize though, I could literally spend the entire month just on ricing cwm(1), and configuring/mastering tmux(1). So I will only go to the extent of helping my workflow and making the system very utilitarian. Tomorrow I will dive into tmux(1) and relearn it from scratch. In the meantime I'm on the hunt for good and interesting reads online as my web browser is html only. I was really enjoying 100 Rabbits website (Rekk and Devine They are sailing the world together and writing FOSS software which is really cool. I enjoy their outlook on computers, software and life in general; very inspirational! I also found Theo de Raadt's personal website too. He is really into hiking! Well, that's all. Happy hacking in OpenBSD!

My laptop workflow

My laptop workflow.


My fetch script called rootfetch

by Root BSD

It begins!

So day one has definitely been a little touch and go. I realized that I need to relearn tmux(1) and write a new .tmux.conf from scratch. Not sure why, but xterm + tmux is not recognizing the color scheme in my old .tmux.conf. The old one is just one that I found online and repurposed for use in OpenBSD with trial and error. So back to the drawing board.

cwm(1) is nice and lightweight. Easy enough to pick up and use quickly, although so far I have only been using manual tiling. It would be nice to setup an automatic tiling layout in .cwmrc, that's a new priority. Opening a terminal is done with CTRL + ALT + Return. Making a terminal fullscreen is done with C + A + m. Cycling through windows is done with Alt + Shift + TAB, etc. OpenBSD does have a handy dandy man page for .cwmrc configuration. I will be happy to dive into that.

One very important thing I did was configure ksh(1) to show me the working directory. You can add this to your ~/.kshrc

PS1='$PWD' “

And this to your ~/.profile

export ENV=$HOME/.kshrc

All in all it's a nice, minimalist system. On day one though, I realize that I'm a bit spoiled with the modern luxuries of computer software, and I have a bit of a short attention span. I need to rectify this!

Goals for the coming week -

1) Read the ifconfig(8) manpage and get a better grasp on all my options with connecting to wifi. There is a join option I have never used before

2) Configure cwm(1) and read the cwmrc(5) manpage. Automated tiling and autoloading a tmux session would be better for my workflow.

3) Read a chapter of Absolute OpenBSD a day.

4) Setup a ssh public key pair for my OpenBSD server.

5) Setup and configure local unbound(8), a caching DNS resolver.

All in all, day one highlights how much I have to learn about the OpenBSD base system, especially cwm(1) and tmux(1). I am feeling a bit of system shock and withdrawals from modern distractions like YouTube videos, memes on my Mastodon home feed, etc. It will get better. First days are always the hardest. Happy New Year, and happy hacking on OpenBSD!

Workflow Screenshot

Hello Fediverse! By Root BSD

I just discovered a feature for readers to follow my posts on the fediverse, my handle is

Very cool!

by Root BSD

OpenBSD Based Challenge

In the spirit of New Year's resolutions and the popular “Linus Tech Tips: Linux Gaming Challenge” on YouTube, I have decided to take on the OpenBSD BASED challenge!

Start January 1st 2022, for 30 days I will only use OpenBSD 7.0 -current + links + toot on both my desktop PC and Thinkpad T420. I will daily journal my learning experience and upload my adventures to this blog via my Pinephone.

I will only use my Pinephone for uploading blog entries to this site and calls/texts for family or emergencies.

My window manager will be base cwm(1) (the calm window manager), the terminal will be xterm. xsetroot(1) will be used background color. links+ and toot (cli mastodon client) will be the only 3rd party packages installed.

This is meant to be an educational experience, to get me more in tuned with OpenBSD's base utilities and man pages. I will attempt to screencast using X11 native tools, we'll see how that goes.

At the end of 30 days I will release a video on my YouTube channel, Root BSD, detailing the adventure and highlighting what I learned.

Looking forward to the adventure!