This post is old and way out of date. Now that the OpenBSD project provides binary updates for the most recent release much of the detail is now completely unnecessary
Looking for a secure and reliable platform on which to host a website or other web application? In this post I explain how to set up a VPS deployment of OpenBSD.
My current preferred server distribution is OpenBSD which is a Unix-like operating system with a focus on code-correctness and a proactive approach to security. Like many server operating systems a successful install will provide a minimal command-line interface. Basic Unix system administration skills are needed. Nonetheless the userland tools are generally simple to use and well-documented. There are excellent resources available for learning OpenBSD such as Michael W Lucas’s marvellous Absolute OpenBSD or the comprehensive but slightly less newbie-friendly project FAQ.
VPS or bare-metal?
If you install an operating system on a virtual private server (VPS), you are installing it in an virtualised environment. You are using a host operating system to interface with the server hardware. While OpenBSD has an exceptionally good reputation for security, arguably you lose some of that advantage when your client OS is piggy-backing on a host OS. You might be confident that your deployment of OpenBSD is secure but how do you know that the Xen hypervisor running your virtualised OS is also secure? If the host machine is compromised the data in your virtualised environment is at risk. For this reason some strongly recommended that OpenBSD is installed directly on hardware (a so-called ‘bare-metal’ install) as this removes numerous potential attack vectors.
Note: OpenBSD now includes a hypervisor and there are service providers which can offer virtualised OpenBSD instances hosted on OpenBSD
Setting up the server
I’m not going to provide a full install guide. This can be found on the FAQ (which is really more of a user manual). Instead, here are a few pointers on how to set things up successfully.
If I have a VNC connection to my VPS: before setting up my system I change the VNC password to something much longer and harder to brute-force. I then disable VNC straight after the install – it seems sensible to disable the service when it isn’t needed. Unless you have set up VNC on the VPS it will be ‘out-of-band’; it is a connection into your virtualised environment via the host operating system. VNC is useful when you need to install a new OS, but not needed for day-to-day administration tasks (unless you have really hosed your box).
Setting up SSH securely
When given the option during the install, you should create a non-root user. You will use this user to log in routinely using SSH. Using the root user to administer the box isn’t good practice, unless elevated privileges are necessary for the task at hand. I also disable root logins when given the option. Once my box is running I enable public key authorisation and copy across my public SSH key into the ~/.ssh/authorized_keys file. After I’m satisfied that everything is working as it should, I disable passwords logins in /etc/ssh/ssh_config. For extra piece of mind, I set a passphrase for my key.
While using a single, large root partition is perfectly feasible it isn’t considered best practice on a production system. Helpfully, the installer comes with an auto partitioning tool which divides the hard drive into (mostly) sensibly-sized partitions. Depending on the proposed use of the system you may want to edit the suggest partition layout. After selecting the custom layout option, you are presented with a prompt by the disklabel tool. It isn’t immediately obvious what to do next…
Typing p at the prompt prints (at the terminal) the existing disklabel (the existing partition layout). As you will see, the disklabel partitions are assigned letters sequentially. Usefully, p g prints the disklabel in gigabytes. Typing d deletes a partition, a adds a partition and m modifies a partition. In each case you need to specify the disklabel partition in respect of which the command should be executed. Answer the queries and then print the disklabel to check that the new partitioning scheme meets your needs.
It isn’t easy to resize partitions after the install, so spend a bit of time trying to get it right the first time. On a recent install the auto partitioning tool presented me with this disklabel layout:
a / 490MB b swap 767MB c unused This isn't really a single partition, rather it is a shortcut for the whole disk. You can ignore this. d /tmp 775MB e /var 1145MB f /usr 1310MB g /usr/X11R6 757.7MB h /usr/local 2867MB i /usr/src 1188MB j /usr/obj 1628MB k /home 4432MB (this is basically the left-over space)
If the system will be used predominantly to serve web pages I will reduce the size of the /home partition and use the space to make /var/www larger as this is where web content is stored by default (in a chroot environment as a security measure).
If I’m going to be building stable to keep the system up to date (hence recompiling the OS), you need at least 2GB of free space in /usr/src and 2GB in /usr/obj. Additionally, if you are going to building software from the ports tree you will want to make /usr sufficiently large to mirror the ports tree. If you’ve made a partition too small, an ugly hack is to move the part of the tree onto another partition with sufficient free space and then symlink the directory back it back to its proper location. For example, if you run out of space in /usr for the ports tree you could put the ports tree elsewhere, say /usr/src/ports and symlink it back to /usr (when in the /usr directory):
ln -s /usr/src/ports/ ports
This is a layout I set up recently for a system intended to follow stable and to use ports:
a / 490MB b swap 767MB c unused d /tmp 775MB e /var 1145MB f /usr 2110MB g /usr/X11R6 758MB h /usr/local 2867MB i /usr/src 2288MB j /usr/obj 2228MB k /var/www 1532MB l /home 200MB
Finally, when you are happy with your disklabel partitioning scheme, type q to write the changes to disk. I hope you made a backup, as this is the point of no return!
Note: Consider using the doas tool instead of sudo
When you create a normal user during system installation the user is automatically added to the wheel group. This doesn’t do a great deal until you type visudo at the command line and uncomment the relevant line in the sudo configuration file to allow users of the wheel group to escalate their privilege level by prefixing commands which need superuser privileges with sudo. Using sudo is encouraged in preference to routinely carrying out system administration with the root user.
Partition mount options
I typically specify that at system startup filesystems are mounted with soft updates and noatime enabled. I find that this improves disk performance. Accomplish by editing /etc/fstab. Refer to the OpenBSD FAQ entry for more information on how to do this.
Synchronising the system clock
To enable the OpenBSD network time protocol daemon (NTPD) at system startup edit /etc/rc.conf.local, creating it if necessary, adding ntpd_flags=“-s” on a new line.
Note: The -s flag to ntpd is now deprecated.
cat /etc/myname prints the current system hostname to the terminal. Your hostname should be the fully-qualified domain name (FQDN). Changes made to cat /etc/myname will be picked up at the next reboot, else pass the FQDN to hostname -s yourFQDN to change the hostname on the fly.
Setting the package path variable
I’ll cover managing software on OpenBSD elsewhere. For now, just set the package path variable so that the system knows where to find add-on software packages.
export PKG_PATH=http://YourPreferredMirror/pub/OpenBSD/`uname -r`/packages/`uname -m`/
Finding a suitable http mirror is as easy as navigating to http://www.openbsd.org/ftp.html and copying the URL of a mirror located close to you. If you have any problems with a particular mirror, simply select an alternative from the list. To make this setting persistent add the export PKG_PATH line at end of your .profile file.
Typing man afterboot gives helpful instructions to help new users orientate themselves.