OpenBSD installation on a tiny VPS

OpenBSD

I needed a gateway on the clear-net to act as an entrace to my mesh network, this is a perfect role for OpenBSD, but can we install it on a random VPS instance? Let’s see how I did it…


Getting a VPS

My requirements were the following:

My domain provider had a good VPS offer ( around US$3 / month) for 20GB SSD / 1GB RAM VPS, so I have ordered one. They provide a short list of different Linux distributions in the Dashboard (Ubuntu, Debian, CentOS and AlmaLinux, if i recall it correctly). I just picked a random Debian from the list and after a quick installation I was greeted by the login prompt. But how do we get OpenBSD on this thing? After looking around in the Dashboard I’ve found a link to a SolusVM VM manager interface. While there was many knobs for messing with the VPS there was no custom ISO option to select or upload a custom installer. What should we do now?

After thinking a while, I started my journey with collecting the most important bits about the network setup of my VPS:

I have expected all of this to be provided by DHCP, but nope. I don’t know the reason, but probably it have something to do with the cloud-install scrips or something similar. Whatever, this information is not a secret, you can find them easily using the preinstalled Linux. Now, that I had all the important info, I have simply downloaded the latest OpenBSD release using the command:

wget https://ftp.openbsd.org/pub/OpenBSD/7.4/amd64/install74.img

Obviously, I used a nearby mirror located in Esslingen, Germany, thanks!

As a next step we need to boot somehow into the installer, we could for example instruct Grub to boot into the installer74.img, but this is too much hassle so I simply DD’d it:

# dd if=install74.img of=/dev/vda

With this command we basically overwrite the preinstalled Linux with the OpenBSD installer. Warning: this will obviously destroy your current OS and all of your data!

After resetting the VPS it booted quickly into the installer, where I went trough the standard questions: I had to specify the IP adress of the virtio interface, the DNS server and the default route. I have previously collected this info from the Linux install, so it was an easy ride. I have formatted the disk using MBR, then I went for an encrypted disk and used the automatic partitioning. I also had to supply an encryption password for the FDE. After having the network in good working order I was able to use “http” for the sets. I don’t plan to use any X-related programs so I have deselected the x* and game* sets. The installation was really quick and after it finished I just rebooted the VPS using the installer prompt. Now on the console I was asked for the FDE (full-disk-encryption) password which needs to be supplied at every reboot. Then a quick boot resulted a working, fresh, clean system. I was able to login via the console, supply my SSH keys and set up doas.conf to allow privilege escalation for the created user.

I provided the following answers:

System hostname = vps
Network interface to configure = vio0
IPv4 address for vio0 = RE.DA.CT.ED
Netmask for vio0 = 255.255.255.0
IPv6 address for vio0 = none
Network interface to configure = done
Default IPv4 route = RE.DA.CT.ED
DNS domain name = my.domain
DNS nameservers = RE.DA.CT.ED
Start sshd(8) by default = yes
Do you expect to run the X Window System = no
Setup a user = redacted
Full name for user redacted = redacted
Allow root ssh login = no
What timezone are you in = Europe/Budapest
Which disk is the root disk = sd0
Encrypt the root disk with a passphrase = yes
Use (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit = w
Use (W)hole disk MBR, whole disk (G)PT or (E)dit = w
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout = a
Location of sets = http
HTTP proxy URL = none
HTTP Server = https://mirror.hs-esslingen.de
Server directory = pub/OpenBSD/7.4/amd64
Set name(s) = -x*
Set name(s) = -game*
Set name(s) = done
Location of sets = done

From this point I was able to close the KVM console window and log in via SSH.


Basic configuration

Boot straight into the system, so no chance to tamper with it using the boot maanager:

host# cat /etc/boot.conf
boot

Disable unnecessary services, enable accounting:

host# cat /etc/rc.conf.local
accounting=YES
dhcpleased_flags=NO
pkg_scripts=tailscaled
slaacd_flags=NO
sndiod_flags=NO

Disable DDB, enable all security check for malloc, enable forwarding:

host# cat /etc/sysctl.conf
ddb.panic=0
machdep.allowaperture=0
vm.malloc_conf=S
net.inet.ip.forwarding=1

Set up SSHd:

host# cat /etc/ssh/sshd_config (only the changes)
Port 12345

LogLevel VERBOSE

PermitRootLogin no
MaxAuthTries 3
MaxSessions 2

PasswordAuthentication no
PermitEmptyPasswords no

AllowAgentForwarding yes
AllowTcpForwarding yes
TCPKeepAlive no
ClientAliveCountMax 2

I don’t expect to attach any USB device to this VPS, but the provider can do shenanigans, so let’s disable the USB ports.

host# cat /etc/bsd.re-config
disable usb*
disable xhci*
disable uhci*
disable cd*
disable fdc*
disable pciide*
disable spkr*

Changed umask from 022 to 027, to make files and directories readable only by users in the same Unix group, not for everyone.

host# cat /etc/login.conf (only the changes)
:umask=027:\

PF setup

I have followed this guide to set-up a minefield and block all unwanted connection-attempts. This should provide good starting rules.


OpenSMTPD setup

I did the setup as described here.


OpenSSH Jumphost

Having all of this in place, I can now use my tiny VPS as an SSH JumpHost:

SSH jump into my mesh:

ssh -J user@jumphost user@server

SSH jump forwarding the webadmin of my remote server:

ssh -L 8080:server:80 user@jumphost

SSH jump and port forwarding for Musikcube

ssh -L 7905:musikcube_host:7905 -L 7906:musikcube_host:7906 user@jumphost

DMESG

host$ dmesg
OpenBSD 7.4 (GENERIC) #3: Wed Feb 28 06:23:08 MST 2024
    root@syspatch-74-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC
real mem = 1056813056 (1007MB)
avail mem = 1005203456 (958MB)
random: good seed from bootblocks
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.8 @ 0xf5a20 (9 entries)
bios0: vendor SeaBIOS version "1.13.0-2.module_el8.5.0+2608+72063365" date 04/01/2014
bios0: Red Hat KVM
acpi0 at bios0: ACPI 1.0
acpi0: sleep states S5
acpi0: tables DSDT FACP APIC
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: QEMU Virtual CPU version 2.5+, 2600.51 MHz, 06-0d-03
cpu0: FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,CX16,x2APIC,HV,NXE,LONG,LAHF,MELTDOWN
cpu0: 32KB 64b/line 8-way D-cache, 32KB 64b/line 8-way I-cache, 4MB 64b/line 16-way L2 cache, 16MB 64b/line 16-way L3 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 1000MHz
ioapic0 at mainbus0: apid 0 pa 0xfec00000, version 11, 24 pins
acpiprt0 at acpi0: bus 0 (PCI0)
"ACPI0006" at acpi0 not configured
acpipci0 at acpi0 PCI0
acpicmos0 at acpi0
"PNP0A06" at acpi0 not configured
"PNP0A06" at acpi0 not configured
"PNP0A06" at acpi0 not configured
"QEMU0002" at acpi0 not configured
"ACPI0010" at acpi0 not configured
acpicpu0 at acpi0: C1(@1 halt!)
pvbus0 at mainbus0: KVM
pvclock0 at pvbus0
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371SB IDE" rev 0x00: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
pciide0: channel 0 disabled (no drives)
atapiscsi0 at pciide0 channel 1 drive 0
scsibus1 at atapiscsi0: 2 targets
cd0 at scsibus1 targ 0 lun 0: <QEMU, QEMU DVD-ROM, 2.5+> removable
cd0(pciide0:1:0): using PIO mode 4, DMA mode 2
uhci0 at pci0 dev 1 function 2 "Intel 82371SB USB" rev 0x01: apic 0 int 11
piixpm0 at pci0 dev 1 function 3 "Intel 82371AB Power" rev 0x03: apic 0 int 9
iic0 at piixpm0
vga1 at pci0 dev 2 function 0 "Cirrus Logic CL-GD5446" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
virtio0 at pci0 dev 3 function 0 "Qumranet Virtio Network" rev 0x00
vio0 at virtio0: address 00:11:22:33:44:55
virtio0: msix shared
virtio1 at pci0 dev 4 function 0 "Qumranet Virtio Storage" rev 0x00
vioblk0 at virtio1
scsibus2 at vioblk0: 1 targets
sd0 at scsibus2 targ 0 lun 0: <VirtIO, Block Device, >
sd0: 20480MB, 512 bytes/sector, 41943040 sectors
virtio1: msix per-VQ
virtio2 at pci0 dev 5 function 0 "Qumranet Virtio Memory Balloon" rev 0x00
viomb0 at virtio2
virtio2: apic 0 int 10
isa0 at pcib0
isadma0 at isa0
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
usb at uhci0 not configured
vscsi0 at root
scsibus3 at vscsi0: 256 targets
softraid0 at root
scsibus4 at softraid0: 256 targets
sd1 at scsibus4 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006>
sd1: 20479MB, 512 bytes/sector, 41942448 sectors
root on sd1a (859d9465c27b589f.a) swap on sd1b dump on sd1b
fd0 at fdc0 drive 1: density unknown
host$ uname -a
OpenBSD host.mydomain.com 7.4 GENERIC#3 amd64
host$