Minecraft Server on OpenBSD

This is a (hopefully) helpful guide to setting up a Minecraft server on OpenBSD. I initially did mine on OpenBSD 7.7, hosted on a Vultr instance. This guide is intended for people with some knowledge of Unix-like systems, but maybe not OpenBSD itself. I’ve tried to include a rationale and explanation for every step, even the “obvious” ones.

This guide assumes you have a working OpenBSD base install, with access to a command line. It also assumes a publicly facing server.

This guide uses PaperMC. Paper is a Minecraft game sever allowing a high level of configuration and performance optimisations.

System Setup

Before doing anything Minecraft related, there’s a few steps in the OpenBSD system itself that need to be taken.

Install Java

Minecraft (the good version, at least) is a Java program. Therefore we need to install Java. Like with most Linux/BSD systems, this is easy to do with the package manager:

# pkg_add jdk
...
Ambiguous: choose package for jdk
a       0: <None>
        1: jdk-1.8.0.462.b08.1v0
        2: jdk-11.0.28.6.1v0
        3: jdk-17.0.16.8.1v0
        4: jdk-21.0.8.9.1v0
Your choice: 
...

Then pick the required version – I used jdk-21 (as in, I entered ‘4’ when prompted for a choice) and it works fine. The rest of the guide is based on jdk-21.

Path Java

Unlike in many Unix-like OS’s, OpenBSD does not automatically add Java to the path. The following environment variables will add Java to the path – these can be set in ~/.profile, though this guide sets them later on; they are noted here for ease of reference.

PATH=$PATH:/usr/local/jdk-21/bin
JAVA_HOME=/usr/local/jdk-21/

These flags are for jdk-21, other versions will likely have a different name for the JAVA_HOME folder (i.e a different version number. Though the output is verbose, pkg_info -L jdk can give some clues as to where the JAVA_HOME and bin/ directories are.

login.conf / cap_mkdb

OpenBSD is conservative in its defaults. When I tried to run Java with more than 1G of memory, it failed to launch with a allocation error. To correct this, in /etc/login.conf I edited the default class.

default:\
        ...
        :datasize-max=unlimited:\
        :datasize-cur=unlimited:\
        ...

This tells the system to give users who are in the default class as much memory as they want – given Minecraft is fairly memory hungry, this is important.

To apply these changes, the following command creates the login.conf.db.

# cap_mkdb /etc/login.conf

We could also create a specific minecraft login class, and set the memory / path here. There are two reasons I haven’t done this: 1) I want the default class to have unlimited memory anyway, given my user is part of it; and 2) the path is being changed later on in a way that is more clear.

pf

We will be running Minecraft on a publicly accessible server. Therefore we need to open ports in the pf firewall. Minecraft runs on port 25565 so we will be using that. Some will advise running it on a different port to deter hackers, but this is pointless security through obscurity – a correctly configured server should be safe to open to the world; if it isn’t, you have bigger problems than port numbers.

To open our port, we need to add the following line to /etc/pf.conf.

pass in on egress inet proto tcp from any to any port 25565

This allows traffic in via tcp from any IP through port 25565. To make this change take affect, we need to reload the rule set.

# pfctl -f /etc/pf.conf

Minecraft on System

After all the talk of login classes in the last part, it’s now time to get into the actual Minecraft user and required Minecraft specific setup.

Minecraft User

To run our server, we will be using a separate user. This is to ensure a minimum level of privilege separation. If we used our standard login user, a bad actor who manage to hack the server would then be able to do everything our standard login user could do. This isn’t an impossible scenario – log4j comes to mind as a recent example of an RCE in Java. By using a Minecraft specific user (who we do not trust), and giving them limited privileges, we are protecting ourselves from this type of vulnerability.

The easiest way to add a user on OpenBSD is with simply by running the following:

# adduser

This provides an interactive way to, surprisingly, add a user. Most of the options are up to your discretion, but the important ones are:

Enter username: _minecraft
Enter shell csh ksh nologin sh [sh]: nologin
Login class auth-defaults auth-ftp-defaults daemon default staff [default]: 

This guide is based on the user being _minecraft. You can call them something else, but ensure this is changed in the following steps. The nologin group is designed for system users who do not login – such as our Minecraft user. The default class is suitable for our Minecraft user. Note that in previous steps, we adjusted the memory that default class can use, hence why we use it now.

doas -u _minecraft

Append the following into /etc/doas.conf, substituting <main_user> with your main login username.

permit persist keepenv <main_user> as _minecraft

This allows you to then use doas -u _minecraft to run commands as our Minecraft user. For those unfamiliar with OpenBSD, doas works like sudo but is much, much, easier to configure.

A further convenience step is setting up an alias, such as dum=doas -u _minecraft in your own ~/,profile. Given that we can’t login as _minecraft, but are going to be doing a lot of work as them, doing this alias saves a lot of time.

Henceforth, unless otherwise specified, all $ commands are run as user _minecraft.

/var/minecraft

We now need a place to actually run our server from. I use /var/minecraft.

# mkdir /var/minecraft
# chown _minecraft:_minecraft /var/minecraft
# chmod 755 /var/minecraft

This creates the directory, gives it _minecraft, then changes the read access to all users. We will be making this stricter once setup is complete, but for now it makes life a lot easier.

Minecraft Setup

wget paper

We’re now ready to start dealing with the server itself. We can download the PaperMC jar into our Minecraft home, /var/minecraft. For the next steps, I assume your working director is this.

Paper very kindly provide a direct link to download this, making it usable with wget. I have not provided a link to this – it is up to you to find it and verify you have got the right URL.

$ wget -O minecraft/server.jar <papermc-server-url>.jar 

start.sh

To start Minecraft, it is helpful to use a script. Here’s one I made earlier. This script assumes you are giving Java 2048M of memory to use – if this is not the case, please change this to reflect your system. We will be looking at more tailored Java launch flags later on.

!/bin/sh

PATH=$PATH:/usr/local/jdk-21/bin
JAVA_HOME=/usr/local/jdk-21/
JAVA_FLAGS="-Xmx2048M -Xms2048M"

umask 077

java $JAVA_FLAGS -jar /var/minecraft/server.jar --nogui

You will note we have (finally!) added the Java file location to our $PATH here.

This file will need to be executable. I also recommend removing unnecessary permissions from it.

# chmod 700 /var/minecraft/start.sh

This limits start.sh to only be read, written, or executed by _minecraft.

First Launch

The big moment.

$ ./start.sh

From here, we will now have the server console available – we can use this for all the normal Minecraft commands like /op, /tp, /weather, etc. We can also see the chat log and notable events like player deaths and testificate deaths.

Once the server starts completely, so we can move onto configuration of the created files, simply tell it stop in the Minecraft console

> stop

Configuration - Refer Appendix 1

A lot of people, a lot smarter than me, have written multiple guides on server optimisation and configuration – including Java flags, plugins, and config file editing. I’ve put some of my favourites in Appendix 1. This is the time to do it.

Fix Permissions

After doing our configuration, now is a good time to change the permissions and restrict the folder (and everything within) back to our Minecraft user.

# chmod -R go-rwx /var/minecraft/

This command is one of those that, if run in the wrong place, can kill your system. Please ensure you only run it on the Minecraft folder.

Background running with tmux

Currently, we can get Minecraft running in the foreground of our ssh session. If we close the session the server stops. Not ideal. Luckily, we have a way around this.

By using tmux we can run Minecraft in the background, whilst still having console access if we need it. It’s as simple as running:

$ tmux 

We then just run the server start script as usual in the tmux window.

$ ./start.sh

Then, Ctrl+B followed by d will “detach” our tmux window and leave Minecraft running in the background. If we need to use the server console again, we can use the following commands.

$ tmux ls
$ tmux attach -dt <session_id>

ls gives the session ID for our tmux session that’s running the server, and attach -dt opens it back up.

Conclusion

We now have a running Minecraft server. All that’s left to do is add the server in your Minecraft client and play! And monitor performance, adjust settings, manage user access, prevent griefing, apply patches, stay on top of costs, manage hardware/software, and do everything else that comes with a publicly accessible server.

Enjoy!

Run into any errors? Something didn’t work like I said it would? Think I’m an idiot with no business running servers, nevermind writing guides about it? Let me know: kay at kayjoseph dot xyz.

Appendix 1 - Tinkering

Basic Security

Two tips for a small server with known members (i.e a friend group):

Optimisation guides