· All Posts · All in OpenBSD · All in Server

Hosted OpenBSD Server Setup

I recently went to Vultr for their hosted OpenBSD servers. One of the outstanding feature of OpenBSD is that it is configured for safety by default. In all the internet arguments this is often missed. Any system can be configured to be reasonably secure, but often takes a lot of effort. With OpenBSD that bit is a core component of the operating system. Having something as critical as security baked into the defaults is simply neat. This post is actually more a log for myself of what I did for future reference. I hope it may be of use for others. The entire setup is rather straightforward and took well under half an hour. UPDATE: Three month later I’m still pleased with customer support, speed and the service as a whole.

vultr control panel

The chosen parameters for my setup come up at just $5 per month.

os: OpenBSD 6.9
server: 1x CPU, 1G memory, 25G SSD storage
location: Tokyo, Japan

Less than a minute later we can open the server console in an noVNC window. We can log in with root and the password from the vulture product page.

Setup User and SSH

We don’t want to operate all with root, so create a user with


This goes through a brief wizard and copies an environment from /etc/skel (if you ever want to change the template).

Next copy over the ssh pubkey

cp ~/.ssh/ root@XXX.XXX.XXX.XXX:/home/dre/pubkey

and add it to authorized keys, I used vi to add it in in case there are other records.

vi /home/dre/.ssh/authorized_keys
:r /home/dre/pubkey

now we can ssh from our local machine to our remote host

ssh -i ~/.ssh/id_rsa dre@XXX.XXX.XXX.XXX
OpenBSD 6.9 (GENERIC.MP) #1: Sat May 22 13:19:59 MDT 2021

Welcome to OpenBSD: The proactively secure Unix-like operating system.


We should forbid to log in with password and also as root

vi /etc/ssh/sshd_config

PermitRootLogin no
PasswordAuthentication no

The OpenBSD equivalent to the more common sudo command is doas. We first need to enable it:

vi /etc/doas.conf
permit persist :wheel

then add your user, here dre to the group wheel:

usermod -G wheel dre

we upgrade and reboot


now we can verify that we can’t sign in as root anymore (it still works through noVNC just not via SSH).

ssh root@XXX.XXX.XXX.XXX
root@XXX.XXX.XXX.XXX: Permission denied (publickey,keyboard-interactive).

Setup httpd

Since OpenBSD 5.6 the web server daemon httpd is available in the base system, so we don’t have to install anything to run a web server. It supports CGI (via FastCGI) and TLS. Enable it to start at boot with

doas rcctl enable httpd

Also edit /etc/rc.conf.local and add the following line, it might have said “NO” before.


Then edit the config file to serve content from /var/www/htdocs/

doas vi /etc/httpd.conf
ext_ip="XXX.XXX.XXX.XXX" # external IP of this box

server "default" {
        listen on $ext_ip port 80
        root "/htdocs/"
types {
        include "/usr/share/misc/mime.types"

The target directory isn’t available yet, let’s create it and give the user write permissions:

mkdir -p /var/www/htdocs/
chown dre /var/www/htdocs/

then upload contents to /var/www/htdocs/

if we didn’t enable it as per above, start httpd with the -f flag, otherwise we can omit it.

doas /etc/rc.d/httpd -f start

our server is now available (without TLS)


We can see access logs with

tail -f /var/www/logs/access.log

The A record is used to point the domain name at one or multiple IP addresses. AAAA record does the same thing as the A record but for IPv6. Set it in your DNS panel if you have a domain, I did this for

www 10800 IN A XXX.XXX.XXX.XXX

or use a cname for the www subdomain instead of an A record

www 10800 IN CNAME

now we can ssh to our server via


Edit /etc/motd to change the welcome “message of the day” you see when you ssh into the server.

If you want to add an SSL certificate with Let’s Encrypt or another CA, you can read the post on how to use acme client with Let’s Encrypt on OpenBSD.

If you wish to block certain countries, see a snippet on blocking country traffic with pf.

Setup rsync

Since we set up SSH keys, we can use scp or better, rsync to copy files between our local machine and our server. We can install rsync from ports:

doas pkg_add rsync

For it to start successfully, we have to create a /etc/rsyncd.conf file, we need to know the uid and gid of our user for the target directory, so the files end up with the right owner.

orwell$ id
uid=1000(dre) gid=1000(dre) groups=1000(dre), 0(wheel)
orwell$ group info daemon
name    daemon
passwd  *
gid     1

The rsyncd.conf then looks as follows:

orwell$ cat /etc/rsyncd.conf
use chroot  = yes
max connection = 5
log file = /var/log/rsyncd.log

path = /var/www/htdocs/
read only = false
list = yes
uid = 1000
gid = 1

Finally enable and start the rsync daemon:

doas rcctl enable rsync
doas rcctl start rsync

And try to copy files:

rsync -a -P --delete ./public/


It then pushes the contents of ./public/ (with a trailing slash!) to /var/www/htdocs/ on the server. It’ll only update the files that are required by comparing timestamps.

Enable IPv6

Ensure that slaacd is enabled and running.

rcctl enable slaacd
rcctl start slaacd

Edit /etc/hostname.vio0 add the inet6 autoconf and further

inet6 autoconf -soii -temporary

Restart the network and test

sh /etc/netstart vio0
ping6 -c3 2001:4860:4860::8888
PING 2001:4860:4860::8888 (2001:4860:4860::8888): 56 data bytes
64 bytes from 2001:4860:4860::8888: icmp_seq=0 hlim=119 time=0.642 ms
64 bytes from 2001:4860:4860::8888: icmp_seq=1 hlim=119 time=0.683 ms
64 bytes from 2001:4860:4860::8888: icmp_seq=2 hlim=119 time=0.663 ms

--- 2001:4860:4860::8888 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.642/0.663/0.683/0.017 ms

When set up http, the website will be reachable through https://[2001:19f0:7001:40ff:5400:3ff:fe70:ec42]/ too and you can add an AAAA IPv6 record for your domain:

@ 10800 IN AAAA 2001:19f0:7001:40ff:5400:3ff:fe70:ec42

Install Software Packages

Note that OpenBSD packages are “frozen” with the OpenBSD base system for releases, which happen every six months. This means that any installed package is only as recent as the OpenBSD release they’re running on, excluding security patches.

Our server doesn’t need many tools, I install Go as it is the primary development language and alongside git allow easy deployments and tests as well as a few other utilities for debugging.

doas pkg_add go git htop curl

Installing and running services will be the subject of later articles. For the base system we’re done for now.

Published on Thursday, Jul 1, 2021. Last modified on Thursday, Mar 10, 2022.
Go back

If you’d like to support me, follow me on Twitter or buy me a coffee. Use Bitcoin
BTC address: bc1q6zjzekdjhp44aws36hdavzc5hhf9p9xnx9j7cv