Post

Minecraft and SystemD

In the first installment I launched a basic Minecraft service on CentOS7. However, a proper service should not be run from the command line, instead it should be controlled by the system service daemon. In years past this would be by writing a ‘sysV init script’ which would try to determine if the process was running, if not launch it and capture its PID for future reference, and capture its output to a file. CentOS-7 has switched away from that model to one called SystemD which makes much of that easier. There is some controversy over the SystemD model (is it UNIX-y? Too monolithic? Taking over everything?) but seems pretty handy for what it needs to do, plus has some nice security features.

So I will create a Minecraft service definition for SystemD. I used http://0pointer.de/blog/projects/systemd-for-admins-3.html to help me with this. The unit file will look like:

/etc/systemd/system/minecraft.service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=Minecraft server
After=syslog.target
RequiresMountsFor=/minecraft

[Service]
ExecStart=/bin/java -Xmx1024M -Xms1024M -jar /minecraft/bin/minecraft_server.jar nogui
WorkingDirectory=/minecraft/var
User=minecraft
Group=minecraft
PrivateTmp=true
NoNewPrivileges=true
InaccessibleDirectories=/home
ReadOnlyDirectories=/bin /lib /usr /etc /
ReadWriteDirectories=/minecraft

[Install]
WantedBy=multi-user.target

What this does:

  • Defines the service name
  • Designates that it requires the /minecraft mount and should run after the logging daemon starts.
  • Provides the startup command, working directory, user/group
  • Designates that /tmp should be private for that process
  • Prevents the process from gaining any privileges.
  • Hides /home from the process
  • Makes most system directories read-only (to protect against accidental permissions issues)
  • Makes /minecraft read-writeable.

The last few are for system protection – even if the java daemon is subverted to try to read the contents of /home, it can’t see it. Between the hidden and read-only directories, the limitation of privileges and the non-privileged launching user, there is much less chance of MineCraft causing system-wide havoc.

After putting the service defintion into place, reload systemd, restart the daemon and check its output:

1
2
3
4
systemctl daemon-reload
systemctl restart minecraft.service
systemctl enable minecraft.service
journalctl -u minecraft.service

To stop the service:

1
systemctl stop minecraft.service

Output will be:

1
2
3
4
5
6
7
8
9
10
11
12
Jan 12 04:18:02 ip-10-10-0-239.ec2.internal systemd[1]: Starting Daemon to detect crashing apps...
Jan 12 04:18:02 ip-10-10-0-239.ec2.internal systemd[1]: Started Daemon to detect crashing apps.
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Starting minecraft server version 1.8.1
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Loading properties
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Default game type: SURVIVAL
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Generating keypair
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Starting Minecraft server on *:25565
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Using epoll channel type
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Preparing level "world"
Jan 12 04:18:06 ip-10-10-0-239.ec2.internal java[2198]: [04:18:06] [Server thread/INFO]: Preparing start region for level 0
Jan 12 04:18:07 ip-10-10-0-239.ec2.internal java[2198]: [04:18:07] [Server thread/INFO]: Preparing spawn area: 94%
Jan 12 04:18:07 ip-10-10-0-239.ec2.internal java[2198]: [04:18:07] [Server thread/INFO]: Done (1.192s)! For help, type "help" or "?"

Update: dietrich@teilgedanken.de sent me a link to https://teilgedanken.de/Blog/post/8/ which takes this a step further and utilizes MCRCON to more gracefully control the servers shutdown state, and integrate with FirewallD if your system utilizes it.

This post is licensed under CC BY 4.0 by the author.