This blog post will show you how to host a Minecraft Server on a Fedora Server sandboxed by SELinux and systemd.
Let us consider “/data/minecraft” will be our Minecraft Server root.
mkdir -p /data/minecraft
Download and extract the server.jar to the root.
groupadd minecraft adduser --shell=/sbin/nologin --no-create-home minecraft usermod -G minecraft -a minecraft semanage login -a -s user_u minecraft touch /data/minecraft/start chmod +x /data/minecraft/start
Add the following content to “start” and adjust the start command as needed. My setup uses spigot.
#!/bin/bash java -Xms1G -Xmx8G -jar server.jar nogui
Later we will use the “start” file for transition to our SELinux Minecraft domain.
chown -R minecraft:minecraft /data/minecraft
I like to put all generated SELinux policies to the path /root/selinux/
mkdir -p /root/selinux/minecraft_server/ cd /root/selinux/minecraft_server
Now we generate our SELinux policy:
sepolgen --inetd /data/minecraft/start -n minecraft_server -w /data/minecraft -u user_u
We disable the “don’t audit” rule of SELinux.
semanage dontaudit off
Append this to minecraft_server.te:
# Add Port defenition type minecraft_port_t; corenet_port(minecraft_port_t)
./minecraft_server.sh semanage port -a -t minecraft_port_t 25565 -p tcp
Create “/usr/lib/systemd/system/minecraft.service” and add the content:
[Unit] Description=Minecraft Server Documentation= Wants=network.target After=network.target [Service] User=minecraft Group=minecraft SuccessExitStatus=130 PrivateMounts=yes RemoveIPC=true ProtectHome=true ProtectSystem=strict PrivateDevices=true NoNewPrivileges=true PrivateTmp=true ProtectControlGroups=yes ProtectKernelModules=yes ProtectKernelTunables=yes RestrictNamespaces=yes RestrictRealtime=yes RestrictSUIDSGID=yes LockPersonality=yes InaccessibleDirectories=/root /sys /srv -/opt /media -/lost+found ReadWriteDirectories=/data/minecraft WorkingDirectory=/data/minecraft TimeoutStopSec=60 KillSignal=SIGINT ExecStart=/data/minecraft/start [Install] WantedBy=multi-user.target
restorecon -Fv /usr/lib/systemd/system/minecraft.service systemctl daemon-reload
cd /root/selinux/minecraft_server ./minecraft_server.sh systemctl enable --now minecraft
You should now see something like this:
[root@53c70r ~]# ls -Z /data/minecraft/ system_u:object_r:minecraft_server_rw_t:s0 banned-ips.json system_u:object_r:minecraft_server_rw_t:s0 banned-players.json system_u:object_r:minecraft_server_rw_t:s0 bukkit.yml system_u:object_r:minecraft_server_rw_t:s0 commands.yml system_u:object_r:minecraft_server_rw_t:s0 crash-reports system_u:object_r:minecraft_server_rw_t:s0 debug system_u:object_r:minecraft_server_rw_t:s0 eula.txt system_u:object_r:minecraft_server_rw_t:s0 help.yml system_u:object_r:minecraft_server_rw_t:s0 logs system_u:object_r:minecraft_server_rw_t:s0 ops.json system_u:object_r:minecraft_server_rw_t:s0 permissions.yml system_u:object_r:minecraft_server_rw_t:s0 plugins system_u:object_r:minecraft_server_rw_t:s0 server.jar system_u:object_r:minecraft_server_rw_t:s0 server.properties system_u:object_r:minecraft_server_rw_t:s0 spigot.yml system_u:object_r:minecraft_server_exec_t:s0 start system_u:object_r:minecraft_server_rw_t:s0 timings system_u:object_r:minecraft_server_rw_t:s0 usercache.json system_u:object_r:minecraft_server_rw_t:s0 wepif.yml system_u:object_r:minecraft_server_rw_t:s0 whitelist.json system_u:object_r:minecraft_server_rw_t:s0 world system_u:object_r:minecraft_server_rw_t:s0 world_nether system_u:object_r:minecraft_server_rw_t:s0 world_the_end
And our running process:
[root@53c70r ~]# ps xaZ | grep minecraft system_u:system_r:minecraft_server_t:s0 95956 ? Ss 0:00 /bin/bash /data/minecraft/start system_u:system_r:minecraft_server_t:s0 95957 ? Sl 9:42 java -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=7 -XX:+AggressiveOpts -Xms1G -Xmx8G -jar server.jar nogui
Let the Server run now for a while and try to interact with it as much as possible e.g. connect to it and disconnect, playing on it yada yada…
The idea is to collect as much logs as possible how the server interacts with the system to catch all system calls we want to whitelist.
If you think you caught all possible system calls execute:
cd /root/selinux/minecraft_server/ ./minecraft_server.sh --update
Confirm with “y”.
To set the policy finally to enforcing mode just change the files content of “minecraft_server.te”
permissive minecraft_server_t;
to
#permissive minecraft_server_t;
and re-execute our script.
./minecraft_server.sh
Restart the Minecraft Server and see if everything works smoothly.
systemctl restart minecraft
If not do “–update” again and see if it found new violations. This process can be repeated as many times as you want.
Finally we can enable the “don’t audit” rule again.
Keep in mind that I did not add a port specific domain like I did in this post.
semanage dontaudit on
Congratulations.
You now own a Military Grade Minecraft Server.