SELinux Murmur Server Policy for Fedora

sudo -i
mkdir ~/selinux/murmur
cd ~/selinux/murmur
sepolgen --inetd /usr/sbin/murmurd -n murmur -u system_u

Add this to murmur.te:

# Add Port defenition
type murmur_port_t;
corenet_port(murmur_port_t)

Run

semanage dontaudit off
./murmur.sh
semanage port -a -t murmur_port_t 64738 -p tcp
semanage port -a -t murmur_port_t 64738 -p udp
systemctl start murmur.service

Login to your server, restart it, generate some system calls…
Than execute and check if the policy is restrictive enough:

./murmur.sh --update

Clean up your audit log

> /var/log/audit/audit.log
rm -rf /var/log/audit/audit.log.*

Generate system calls again and rerun “–update”.
If murmur does not generate any more violations your policy is good to go.

Set it to enforcing by removing “#” before “permissive murmur_t;” in “murmur.te”.

Rerun

./murmur.sh

Restart murmur and check if everything is working as expected.

Finally enable “don’t audit” again:

semanage dontaudit on

WordPress on SELinux enforced systems

First of all SELinux is your friend not your enemy.
Hosting WordPress on SELinux enforced systems like Centos8 will mostly ruin your security concept since the majority would straight away disable SELinux leaving the system open to all other nasty exploitation attacks against running services.

TL;DR
Please don’t forget to adjust your WordPress root path.
For more information read the man page semanage-fcontext(8).

semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content/plugins(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content/themes(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content/upgrade(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content/uploads(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/nginx/html/wordpress/wp-content/wflogs(/.*)?"

Make sure your default label for e.g. /usr/share/nginx/ is “httpd_sys_content_t”.

[root@53c70r wordpress]# semanage fcontext -l | grep /usr/share/nginx/
/usr/share/nginx/html(/.*)?                        all files          system_u:object_r:httpd_sys_content_t:s0

This will cause all other files not defined by our own file context to be read only.
Finaly execute

restorecon -RFv /usr/share/nginx/

After the command being executed labeling should look as follow:

[root@53c70r wordpress]# ll -Z
total 208
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0      405 Apr 17 23:32 index.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0    19915 Aug 27 23:24 license.txt
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     7278 Sep 23 00:56 readme.html
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     7101 Aug 27 23:24 wp-activate.php
drwxr-xr-x.  9 nginx nginx system_u:object_r:httpd_sys_content_t:s0     4096 Jan 19  2020 wp-admin
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0      351 Apr 17 23:32 wp-blog-header.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     2332 Aug 27 23:24 wp-comments-post.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     2897 Jan 19  2020 wp-config.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     2913 Apr 17 23:32 wp-config-sample.php
drwxr-xr-x.  7 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0    96 Sep 23 00:57 wp-content
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     3940 Apr 17 23:32 wp-cron.php
drwxr-xr-x. 24 nginx nginx system_u:object_r:httpd_sys_content_t:s0     8192 Aug 27 23:24 wp-includes
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     2496 Apr 17 23:32 wp-links-opml.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     3300 Apr 17 23:32 wp-load.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0    48761 Aug 27 23:24 wp-login.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     8509 Jun 17 12:56 wp-mail.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0    20181 Aug 27 23:24 wp-settings.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0    31159 Aug 27 23:24 wp-signup.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     4755 Apr 17 23:32 wp-trackback.php
-rw-r--r--.  1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     3236 Aug 27 23:24 xmlrpc.php

[root@53c70r wordpress]# ll -Z wp-content/
total 4
-rw-r--r--. 1 nginx nginx system_u:object_r:httpd_sys_content_t:s0     28 Jan 19  2020 index.php
drwxr-xr-x. 7 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0 129 Sep 23 00:49 plugins
drwxr-xr-x. 4 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0  56 Aug 27 23:17 themes
drwxr-xr-x. 2 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0   6 Sep 23 00:56 upgrade
drwxr-xr-x. 6 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0  68 Jan 19  2020 uploads
drwxr-xr-x. 2 nginx nginx system_u:object_r:httpd_sys_rw_content_t:s0 224 Jan 19  2020 wflogs

If you want to upgrade your WordPress later just execute this before

setsebool httpd_unified 1

And when your upgrade is finished

setsebool httpd_unified 0

Minecraft Server with SELinux on Fedora

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.