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.
Before doing anything Minecraft related, there’s a few steps in the OpenBSD system itself that need to be taken.
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
.
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.
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.
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
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.
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.
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
.
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.
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
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
.
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
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.
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.
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.
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.
Two tips for a small server with known members (i.e a friend group):
online-mode=false
in your
server.properties
. You will get griefed. There are
legitimate use cases for this setting, but this guide does not cater to
them.
server.properties
with white-list=true
and
enforce-whitelist=true
. If you need to whitelist someone,
use /whitelist add username
in the server console or as an
op.JAVA_FLAGS="..."
with the flags in the command.