Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Running Starbound server on CentOS 7

I recently set up a Starbound dedicated server instance on my CentOS 7 machine. Technically it was a migration of an existing map, or "universe." Here's how to do it. At least I documented this one. My Ark: Survival Evolved server setup (with complementing web page for administering) is still undocumented... The end goal includes running Starbound as a system service (although the actual systemctl enable starbound-server.service commands are not documented here) and presenting a web page for easy administration of the application. Starbound generic
image

Install steam

Install steam and its prerequisites and Starbound's prerequisites.

sudo yum install glibc.i686 libstdc++.i686 libvorbis
sudo useradd steam
sudo su - steam

Steps as steam user

So now as user "steam" download steamcmd and prepare the run scripts.

wget http://media.steampowered.com/installer/steamcmd_linux.tar.gz
tar -xvzf steamcmd_linux.tar.gz

Set up the update script as file /home/steam/bin/update_starbound.sh

1
2
3
4
5
6
7
#!/bin/sh
# References:
#    https://starbounder.org/Guide:LinuxServerSetup
#    https://stackoverflow.com/questions/25375528/installing-steamcmd-on-centos-7
# ./steamcmd.sh +login $USERNAME $PASSWORD +force_install_dir $STARBOUNDSERVERDIR +app_update 211820 validate +quit
cd /home/steam
./steamcmd.sh +login USERNAME PASSWORD +force_install_dir /home/steam/Steam +app_update 211820 validate +quit

And set up the run script as file /home/steam/bin/run_starbound.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh
is_running="$( netstat -tlpnu 2>/dev/null | awk '/:21025/ && $NF ~ /starbound_/{print "running"}' )"
if test "${is_running}" = "running" ;
then
   echo "Starbound is already running."
   :
else
   cd /home/steam/Steam/linux
   /home/steam/Steam/linux/starbound_server
fi

Run the steam shell and prepare Starbound. Use your username and password. If you omit the password, it will prompt you separately which is actually more secure.

./steamcmd.sh
login USERNAME PASSWORD
force_install_dir /home/steam/Steam
app_update 211820
quit

Configure starbound with file /home/steam/Steam/storage/starbound_server.config Change gameServerBind from :: to * to get it to enable ipv4. I also set maxPlayers to 20 and maxTeamSize 10.

  "serverUsers" : {
    "Myaccountname" : {
      "admin" : true,
      "password" : "Mypassword"
    }

Make the public log directory.

mkdir -p ~/public-log
chmod 0755 ~/public-log
chmod o+rx ~

Steps as root

Change user to root.

sudo su - root

Set up the firewall rule as /lib/firewalld/services/starbound.xml

      starbound
      Starbound server is a dedicated game server for Starbound on Steam. This firewall rule opens up the required ports to host a game server.

Set up the systemd service as /etc/systemd/system/starbound-server.service

[Unit]
Description=Starbound dedicated server
Wants=network-online.target
After=network.target syslog.target

[Service]
WorkingDirectory=/home/steam/Steam/linux
User=steam
Group=steam
Type=simple
ExecStartPre=/home/steam/bin/update_starbound.sh
TimeoutStartSec=120
ExecStart=/home/steam/Steam/linux/starbound_server -logfile /home/steam/public-log/systemd-starbound-server.log
RestartSec=15
Restart=always
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

Testing

Run the game at least once, manually, and make sure clients can connect to it.

# as user steam
run_starbound.sh

Steps on router

Set up external port 21025 to forward to this IP address at port 21025.

Import universe from old server

Export the starbound/storage directory from starbound-2020-07-25.7z as directory /home/steam/Steam/storage

# as user steam, and make sure server is stopped first.
cd ~/Steam
mv storage storage.blank
7za x starbound-2020-07-25.7z starbound/storage
mv starbound/storage . && rmdir starbound

Adding web front end

Bonus round!

I like to present a web front-end where my non-technical compatriates can come check server status, start and stop it, and see who is online without having to run the game.

Adjust apache config

Set a simple password in a file, in format username:password.

echo "myuser:mypassword" >> /etc/httpd/httpasswd

Adjust /etc/httpd/conf.d files. In my virtual host, I set a location with this config.

   DocumentRoot "/var/www/html"
   AddHandler cgi-script .cgi
   Options +ExecCGI

      Options +Indexes +FollowSymLinks +ExecCGI
      AuthType Basic
      AuthName "Restricted to [Wally]"
      AuthUserFile /etc/httpd/htpasswd
      Require user mark


      AllowOverride All

Write web page files

Set all files in /var/www/html/starbound with useful contents. File index.html

Starbound server: Servername1




# Servername1




Private server for running [Starbound](https://store.steampowered.com/app/211820/Starbound/).




[status](cgi-bin/status.cgi)
| ![](images/starbound-ship.jpg)

---|---

[current users](cgi-bin/current-users.cgi)

[log (static)](cgi-bin/logs.cgi)

[log (follow)](cgi-bin/logs.cgi?f)


Useful documentation: [Guide:LinuxServerSetup - Starbounder - Starbound Wiki](https://starbounder.org/Guide:LinuxServerSetup)


###### Server actions



[![](images/media-playback-start.png)start](cgi-bin/server.cgi?action=start)
| [![](images/system-reboot.png)restart](cgi-bin/server.cgi?action=restart)  
---|---

[![](images/process-stop.png)stop](cgi-bin/server.cgi?action=stop)

File .styles/reset.css

@import 'https://fonts.googleapis.com/css?family=Open+Sans';

body {
  font-family: 'Open Sans';
  -webkit-font-smoothing: antialiased;
}

html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: border-box;
}

body, html {
  padding: 0px;
  margin: 0px;
  width: 100%;
  height: 100%;
}

img {
  max-width: 100%;
}

File .styles/styles.css

body{
   background-color:  #f2f2f2;

}
.regular_img{
   display: block;
   margin-left: auto;
   margin-right: auto;
   width: 50%;
   min-width: 200px;
}
h1{
   background-color: #cc3300;
   padding-top: 15px;
   padding-bottom: 25px;
   padding-right: 20px;
   padding-left: 20px;
   display: flex;
   font-family: helvetica, sans-serif;
   font-size: 24pt;
   justify-content: center;
   color: white;
}
td{
   padding-top: 4px;
   padding-bottom: 4px;
   padding-right: 25px;
}
td a{
   display: flex;
   justify-content: center;
   background-color:  #d9d9d9;
   border-radius: 25px;
   padding-top: 10px;
   padding-bottom: 10px;
   padding-left: 50px;
   padding-right: 50px;
   color: black;

}
td a:hover{
   background-color: #cccccc;
   color: white;

}
p{
   display: block;
   width: 400px;
   margin: 0 auto;
   margin-top: 25px;
   border: solid 2px;
   border-radius: 25px;
   padding: 5px;
   font-size: 12pt;
   font-weight: 100;
   text-decoration: none;
   text-align: center;
   transition: all .3s;
   color: white;
   background-color: #cc3300;
}

h6{
   background-color:  #cccccc;
   padding-top: 10px;
   padding-bottom: 10px;
   padding-right: 20px;
   padding-left: 20px;
   display: flex;
   font-family: helvetica, sans-serif;
   font-size: 20pt;
   justify-content: center;
   color: white;
   margin-bottom: 10px;
}
table {
   padding-top: 25;
   display: flex;
   justify-content: center;
}
td{
   padding: 10px;
}

And all the cgi scripts. Yes, I used shell, because I can! File cgi- bin/current-users.cgi

1
2
3
4
5
6
7
8
9
#!/bin/sh
printf "%s\n\n" "Content-type: text/html"
echo "Servername1: current users"
echo "


"
sudo /usr/local/bin/starbound-users.sh current
echo "

" echo "Go Back" echo ""

File cgi-bin/logs.cgi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh
# Reference:
#    https://bytes.com/topic/html-css/answers/155314-tail-logfile-web-page
#    arkserver/cgi-bin/logs.cgi
# Improve:
#    split QUERY_STRING, and use variables: refresh=3&tail
printf "%s\n\n" "Content-type: text/html"
echo "Servername1 server log"
if test "f" = "${QUERY_STRING}" ;
then
   echo ''
fi
echo ""
echo "


"

# calculate most recent server log file.
test -z "${INDIR}" && export INDIR=/home/steam/public-log
test -z "${INFILE}" && export INFILE="$( find "${INDIR}" -maxdepth 1 -mindepth 1 ! -type d -name 'systemd-starbound-server.log*' -printf '%T@ %p\n' | sort -n | tail -n1 | awk '{print $2}' )"
# static view
tail -n10000 "${INFILE}"
echo "

" echo ""

File cgi-bin/server.cgi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/sh
# References:
#    https://www.tutorialspoint.com/How-to-use-JavaScript-to-redirect-a-webpage-after-5-seconds

printf "%s\n\n" "Content-type: text/html"
echo ""
echo ""
echo ''
echo ''
echo "Servername1 server actions"
echo ""
echo "


"

test -z "${SERVICE}" && export SERVICE=starbound-server

#echo "${QUERY_STRING}"

for opt in $( echo "${QUERY_STRING}" | tr '[&?]' '\n' ) ;
do
   item="$( echo "${opt}" | awk -F'=' '{print $1}' )"
   value="$( echo "${opt}" | awk -F'=' '{print $2}' )"
   eval "${item}"="${value}"
done

# hardcode to protect against variable injection
SERVICE=starbound-server

case "${action}" in
   start)
      echo "sudo systemctl ${action} ${SERVICE}"
      sudo systemctl ${action} ${SERVICE}
      USE_TIMER=1 ; TIMER_SEC=3
      ;;
   stop|restart)
      echo "Click this link to ${action} the server:"
      alt_action="$( echo "${action}" | tr '[a-z]' '[A-Z]' )"'!'
      echo "[${alt_action}](?action=${alt_action}&force=yes)"
      ;;
   "STOP!"|"RESTART!")
      if test -n "${force}" ;
      then
         orig_action="$( echo "${action%%\!}" | tr '[A-Z]' '[a-z]' )"
         orig_action_show="${orig_action}"
         test "stop" = "${orig_action}" && orig_action_show="stopp"
         echo "OK, ${orig_action_show}ing server..."
         echo "sudo systemctl ${orig_action} ${SERVICE}"
         sudo systemctl ${orig_action} ${SERVICE}
         USE_TIMER=1 ; TIMER_SEC=1
      else
         :
      fi
      ;;
   *)
      echo "Unable to understand that command. No action taken."
      ;;
esac
echo "

" if test "1" = "${USE_TIMER}" ; then TIMERVALUE=$(( TIMER_SEC * 1000 )) echo "" echo "setTimeout(function(){" echo " window.location.href = '../';" echo "}, ${TIMERVALUE});" echo "" fi echo ""

File cgi-bin/status.cgi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh
# References:
#    https://stackoverflow.com/questions/4797124/malformed-header-from-script-bad-header-doctype-html#4797178
printf "%s\n\n" "Content-type: text/html"
echo "Servername1: status"
echo "


"
sudo /usr/local/bin/starbound-status.sh
echo "

" echo "Go Back" echo ""

I found it very important to run a restorecon -Rv on /var/www/html/starbound. I might have even had to make a new file context rule, but I cannot remember now.

-rwxr-xr-x. root root unconfined_u:object_r:httpd_sys_script_exec_t:s0 current-users.cgi*

Write files for /usr/local/bin

So the web pages sometimes call local scripts. Some of these are put in the path for terminal users, because some commands are useful even on the terminal. File /usr/local/bin/starbound-status.sh

1
2
#!/bin/sh
sudo ss -tlpnu | awk '/starbound_s/{print $1, $2, $5, $7}'

File /usr/local/bin/starbound-users.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/sh
# Startdate: 2020-07-30
# Reference: ark-users.sh
test -z "${INDIR}" && export INDIR=/home/steam/public-log
test -z "${INGLOB}" && export INGLOB="*.log"

infiles="$( find "${INDIR}" -maxdepth 1 -mindepth 1 -name ${INGLOB} -printf '%T@ %p\n' | sort -n | tail -n5 | awk '{print $NF}' )"

export allusers="$(
{
   # collect all users who are still connected
   cat ${infiles} | grep -E 'Client.*\<connected'
   echo "MINUS"

   # collect users who are disconnected
   cat ${infiles} | grep -E 'Client.*\<(dis)connected'
} | \
   awk 'BEGIN {minus=0} !/MINUS/{if (minus==0){users[$5,$7]++;times[$5,$7]=$1} else users[$5,$7]--} /MINUS/{minus=1} END {for (user in users) print users[user], user,"at",times[user];}' | sed -r -e "s/'.?\(/',\(/g;" )"

param="${1}"
param_lower="$( echo "${param}" | tr '[A-Z]' '[a-z]' )"
{
case "${param_lower}" in
   all)
      printf "${allusers}" | awk '{print $2,$3,$4}'
      ;;
   *)
      printf "${allusers}" | awk '$1 !~ /0/{print $2,$3,$4}'
      ;;
esac
} | sed -r -e "s/',\(/' \(/g;"

Write custom sudoers

So now we need to allow apache, and any other relevant users, to run these commands. File /etc/sudoers.d/60_starbound_sudo

# file: /etc/sudoers.d/60_starbound_sudo
ALL   ALL=(ALL)   NOPASSWD: /bin/systemctl start starbound-server, /bin/systemctl stop starbound-server, /bin/systemctl status starbound-server, /bin/systemctl restart starbound-server, /bin/systemctl start starbound-server.service, /bin/systemctl stop starbound-server.service, /bin/systemctl status starbound-server.service, /bin/systemctl restart starbound-server.service, /usr/local/bin/starbound-status.sh, /usr/local/bin/starbound-users.sh *, /usr/bin/journalctl -f -u starbound-server.service, /usr/bin/journalctl -u starbound-server.service -f, /usr/bin/journalctl -u starbound-server.service -n100, /usr/sbin/service starbound-server *

SELinux module

This part is probably the biggest secret sauce out of this entire process. Most people have set up a systemd unit for arbitrary processes. And sudo is pretty well-known. But SELinux is the epitome of overkill. Write custom selinux module for allowing httpd to invoke systemctl stop starbound- server.service.

SELinux policy file

Load this into a file, cgibin-sudo.te

# Notes:
#    semodule --disable_dontaudit --build
#    semodule --build
# References:
#    https://wiki.gentoo.org/wiki/SELinux/Tutorials/Where_to_find_SELinux_permission_denial_details

module cgibin-sudo 1.0;

require {

   class capability { sys_ptrace setgid setuid dac_override dac_read_search sys_resource net_admin audit_write };
   class dbus send_msg;
   class dir { getattr open read search };
   class fifo_file write;
   class file { search lock getattr open read };
   class filesystem getattr;
   class lnk_file read;
   class netlink_audit_socket { write create getattr nlmsg_relay read };
   class netlink_kobject_uevent_socket getattr;
   class netlink_route_socket getattr;
   class netlink_selinux_socket getattr;
   class netlink_socket getattr;
   class netlink_tcpdiag_socket { read write bind create getattr nlmsg_read setopt };
   class packet_socket getattr;
   class process { noatsecure rlimitinh siginh setrlimit getattr };
   class service { status stop start restart };
   class tcp_socket getattr;
   class udp_socket getattr;
   class unix_dgram_socket getattr;
   class unix_stream_socket connectto;
   class unix_stream_socket getattr;
   type auditd_t;
   type crond_t;
   type dnsmasq_t;
   type firewalld_t;
   type getty_t;
   type gssd_t;
   type gssproxy_t;
   type httpd_sys_script_t;
   type httpd_t;
   type initrc_var_run_t;
   type init_t;
   type irqbalance_t;
   type iscsid_t;
   type kernel_t;
   type ksmtuned_t;
   type lvm_t;
   type NetworkManager_t;
   type nfs_t;
   type ntpd_t;
   type oddjob_t;
   type policykit_t;
   type postfix_master_t;
   type postfix_pickup_t;
   type postfix_qmgr_t;
   type proc_net_t;
   type rpcbind_t;
   type shadow_t;
   type sshd_t;
   type sssd_conf_t;
   type sssd_t;
   type syslogd_t;
   type system_dbusd_t;
   type systemd_logind_sessions_t;
   type systemd_logind_t;
   type systemd_unit_file_t;
   type tuned_t;
   type udev_t;
   type unconfined_t;
   type user_home_dir_t;
   type user_home_t;
   type virtd_t;
   type virtlogd_t;

}

#============= httpd_sys_script_t ==============

allow httpd_sys_script_t auditd_t:dir { open read search };
allow httpd_sys_script_t auditd_t:file { open read getattr };
allow httpd_sys_script_t auditd_t:lnk_file read;
allow httpd_sys_script_t auditd_t:netlink_audit_socket getattr;
allow httpd_sys_script_t auditd_t:process getattr;
allow httpd_sys_script_t auditd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t auditd_t:unix_stream_socket getattr;
allow httpd_sys_script_t crond_t:dir { open read search };
allow httpd_sys_script_t crond_t:file { getattr open read };
allow httpd_sys_script_t crond_t:lnk_file read;
allow httpd_sys_script_t crond_t:process getattr;
allow httpd_sys_script_t crond_t:unix_dgram_socket getattr;
allow httpd_sys_script_t dnsmasq_t:dir { open read search };
allow httpd_sys_script_t dnsmasq_t:file { getattr open read };
allow httpd_sys_script_t dnsmasq_t:lnk_file read;
allow httpd_sys_script_t dnsmasq_t:netlink_route_socket getattr;
allow httpd_sys_script_t dnsmasq_t:process getattr;
allow httpd_sys_script_t dnsmasq_t:tcp_socket getattr;
allow httpd_sys_script_t dnsmasq_t:udp_socket getattr;
allow httpd_sys_script_t dnsmasq_t:unix_dgram_socket getattr;
allow httpd_sys_script_t dnsmasq_t:unix_stream_socket getattr;
allow httpd_sys_script_t firewalld_t:dir { open read search };
allow httpd_sys_script_t firewalld_t:file { getattr open read };
allow httpd_sys_script_t firewalld_t:lnk_file read;
allow httpd_sys_script_t firewalld_t:process getattr;
allow httpd_sys_script_t firewalld_t:unix_dgram_socket getattr;
allow httpd_sys_script_t firewalld_t:unix_stream_socket getattr;
allow httpd_sys_script_t getty_t:dir { open read search };
allow httpd_sys_script_t getty_t:file { open read };
allow httpd_sys_script_t getty_t:lnk_file read;
allow httpd_sys_script_t getty_t:process getattr;
allow httpd_sys_script_t gssd_t:dir { open read search };
allow httpd_sys_script_t gssd_t:file { getattr open read };
allow httpd_sys_script_t gssd_t:lnk_file read;
allow httpd_sys_script_t gssd_t:process getattr;
allow httpd_sys_script_t gssd_t:unix_stream_socket getattr;
allow httpd_sys_script_t gssproxy_t:dir { read open search };
allow httpd_sys_script_t gssproxy_t:file { getattr read open };
allow httpd_sys_script_t gssproxy_t:lnk_file read;
allow httpd_sys_script_t gssproxy_t:process getattr;
allow httpd_sys_script_t gssproxy_t:unix_dgram_socket getattr;
allow httpd_sys_script_t gssproxy_t:unix_stream_socket getattr;
allow httpd_sys_script_t httpd_t:dir { open read search };
allow httpd_sys_script_t httpd_t:file { getattr open read };
allow httpd_sys_script_t httpd_t:lnk_file read;
allow httpd_sys_script_t httpd_t:process getattr;
allow httpd_sys_script_t httpd_t:tcp_socket getattr;
allow httpd_sys_script_t initrc_var_run_t:file { lock open read };
allow httpd_sys_script_t init_t:dbus send_msg;
allow httpd_sys_script_t init_t:dir { read search open };
allow httpd_sys_script_t init_t:file { getattr read search open };
allow httpd_sys_script_t init_t:lnk_file read;
allow httpd_sys_script_t init_t:netlink_audit_socket getattr;
allow httpd_sys_script_t init_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t init_t:netlink_selinux_socket getattr;
allow httpd_sys_script_t init_t:process getattr;
allow httpd_sys_script_t init_t:tcp_socket getattr;
allow httpd_sys_script_t init_t:udp_socket getattr;
allow httpd_sys_script_t init_t:unix_dgram_socket getattr;
allow httpd_sys_script_t init_t:unix_stream_socket connectto;
allow httpd_sys_script_t init_t:unix_stream_socket getattr;
allow httpd_sys_script_t irqbalance_t:dir { read search open };
allow httpd_sys_script_t irqbalance_t:file { getattr read search open };
allow httpd_sys_script_t irqbalance_t:lnk_file read;
allow httpd_sys_script_t irqbalance_t:process getattr;
allow httpd_sys_script_t iscsid_t:unix_stream_socket getattr;
allow httpd_sys_script_t kernel_t:dir { read search open };
allow httpd_sys_script_t kernel_t:file { read search open };
allow httpd_sys_script_t kernel_t:process getattr;
allow httpd_sys_script_t kernel_t:unix_dgram_socket getattr;
allow httpd_sys_script_t kernel_t:unix_stream_socket getattr;
allow httpd_sys_script_t ksmtuned_t:dir { open read search };
allow httpd_sys_script_t ksmtuned_t:file { getattr open read };
allow httpd_sys_script_t ksmtuned_t:lnk_file read;
allow httpd_sys_script_t ksmtuned_t:process getattr;
allow httpd_sys_script_t lvm_t:dir { read search open };
allow httpd_sys_script_t lvm_t:file { read search open getattr };
allow httpd_sys_script_t lvm_t:lnk_file read;
allow httpd_sys_script_t lvm_t:process getattr;
allow httpd_sys_script_t lvm_t:unix_stream_socket getattr;
allow httpd_sys_script_t NetworkManager_t:dir { open read search };
allow httpd_sys_script_t NetworkManager_t:file { getattr open read };
allow httpd_sys_script_t NetworkManager_t:lnk_file read;
allow httpd_sys_script_t NetworkManager_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t NetworkManager_t:netlink_route_socket getattr;
allow httpd_sys_script_t NetworkManager_t:netlink_socket getattr;
allow httpd_sys_script_t NetworkManager_t:packet_socket getattr;
allow httpd_sys_script_t NetworkManager_t:process getattr;
allow httpd_sys_script_t NetworkManager_t:unix_dgram_socket getattr;
allow httpd_sys_script_t NetworkManager_t:unix_stream_socket getattr;
allow httpd_sys_script_t nfs_t:filesystem getattr;
allow httpd_sys_script_t ntpd_t:dir { open read search };
allow httpd_sys_script_t ntpd_t:file { getattr open read };
allow httpd_sys_script_t ntpd_t:lnk_file read;
allow httpd_sys_script_t ntpd_t:netlink_route_socket getattr;
allow httpd_sys_script_t ntpd_t:process getattr;
allow httpd_sys_script_t ntpd_t:udp_socket getattr;
allow httpd_sys_script_t ntpd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t oddjob_t:dir { open read search };
allow httpd_sys_script_t oddjob_t:file { getattr open read };
allow httpd_sys_script_t oddjob_t:lnk_file read;
allow httpd_sys_script_t oddjob_t:process getattr;
allow httpd_sys_script_t oddjob_t:unix_stream_socket getattr;
allow httpd_sys_script_t policykit_t:dir { read search open };
allow httpd_sys_script_t policykit_t:file { getattr read open };
allow httpd_sys_script_t policykit_t:lnk_file read;
allow httpd_sys_script_t policykit_t:process getattr;
allow httpd_sys_script_t policykit_t:unix_dgram_socket getattr;
allow httpd_sys_script_t policykit_t:unix_stream_socket getattr;
allow httpd_sys_script_t postfix_master_t:dir { open read search };
allow httpd_sys_script_t postfix_master_t:file { getattr open read };
allow httpd_sys_script_t postfix_master_t:lnk_file read;
allow httpd_sys_script_t postfix_master_t:process getattr;
allow httpd_sys_script_t postfix_master_t:tcp_socket getattr;
allow httpd_sys_script_t postfix_master_t:unix_dgram_socket getattr;
allow httpd_sys_script_t postfix_master_t:unix_stream_socket getattr;
allow httpd_sys_script_t postfix_pickup_t:dir { open read search };
allow httpd_sys_script_t postfix_pickup_t:file { getattr open read };
allow httpd_sys_script_t postfix_pickup_t:lnk_file read;
allow httpd_sys_script_t postfix_pickup_t:process getattr;
allow httpd_sys_script_t postfix_pickup_t:unix_dgram_socket getattr;
allow httpd_sys_script_t postfix_pickup_t:unix_stream_socket getattr;
allow httpd_sys_script_t postfix_qmgr_t:dir { open read search };
allow httpd_sys_script_t postfix_qmgr_t:file { getattr open read };
allow httpd_sys_script_t postfix_qmgr_t:lnk_file read;
allow httpd_sys_script_t postfix_qmgr_t:process getattr;
allow httpd_sys_script_t postfix_qmgr_t:unix_dgram_socket getattr;
allow httpd_sys_script_t postfix_qmgr_t:unix_stream_socket getattr;
allow httpd_sys_script_t proc_net_t:file { open read search getattr };
allow httpd_sys_script_t rpcbind_t:dir { read search open };
allow httpd_sys_script_t rpcbind_t:file { getattr read search open };
allow httpd_sys_script_t rpcbind_t:lnk_file read;
allow httpd_sys_script_t rpcbind_t:process getattr;
allow httpd_sys_script_t rpcbind_t:tcp_socket getattr;
allow httpd_sys_script_t rpcbind_t:udp_socket getattr;
allow httpd_sys_script_t rpcbind_t:unix_stream_socket getattr;
allow httpd_sys_script_t self:capability { net_admin audit_write sys_ptrace setgid setuid dac_override dac_read_search sys_resource };
allow httpd_sys_script_t self:netlink_audit_socket { write getattr create nlmsg_relay read };
allow httpd_sys_script_t self:netlink_tcpdiag_socket { bind create getattr nlmsg_read setopt read write };
allow httpd_sys_script_t self:process { setrlimit getattr };
allow httpd_sys_script_t shadow_t:file { read open getattr };
allow httpd_sys_script_t sshd_t:dir { open read search };
allow httpd_sys_script_t sshd_t:file { getattr open read };
allow httpd_sys_script_t sshd_t:lnk_file read;
allow httpd_sys_script_t sshd_t:process getattr;
allow httpd_sys_script_t sshd_t:tcp_socket getattr;
allow httpd_sys_script_t sshd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t sshd_t:unix_stream_socket getattr;
allow httpd_sys_script_t sssd_conf_t:dir search;
allow httpd_sys_script_t sssd_conf_t:file { read open getattr };
allow httpd_sys_script_t sssd_t:dir { read search open };
allow httpd_sys_script_t sssd_t:file { getattr read search open };
allow httpd_sys_script_t sssd_t:lnk_file read;
allow httpd_sys_script_t sssd_t:netlink_route_socket getattr;
allow httpd_sys_script_t sssd_t:process getattr;
allow httpd_sys_script_t sssd_t:tcp_socket getattr;
allow httpd_sys_script_t sssd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t sssd_t:unix_stream_socket getattr;
allow httpd_sys_script_t syslogd_t:dir { read search open };
allow httpd_sys_script_t syslogd_t:file { getattr read open search };
allow httpd_sys_script_t syslogd_t:lnk_file read;
allow httpd_sys_script_t syslogd_t:process getattr;
allow httpd_sys_script_t syslogd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t system_dbusd_t:dbus send_msg;
allow httpd_sys_script_t system_dbusd_t:dir { read search open };
allow httpd_sys_script_t system_dbusd_t:file { getattr read open };
allow httpd_sys_script_t system_dbusd_t:lnk_file read;
allow httpd_sys_script_t system_dbusd_t:netlink_audit_socket getattr;
allow httpd_sys_script_t system_dbusd_t:netlink_selinux_socket getattr;
allow httpd_sys_script_t system_dbusd_t:process getattr;
allow httpd_sys_script_t system_dbusd_t:unix_dgram_socket getattr;
allow httpd_sys_script_t system_dbusd_t:unix_stream_socket connectto;
allow httpd_sys_script_t system_dbusd_t:unix_stream_socket getattr;
allow httpd_sys_script_t systemd_logind_sessions_t:fifo_file write;
allow httpd_sys_script_t systemd_logind_t:dbus send_msg;
allow httpd_sys_script_t systemd_logind_t:dir { open read search };
allow httpd_sys_script_t systemd_logind_t:file { getattr open read };
allow httpd_sys_script_t systemd_logind_t:lnk_file read;
allow httpd_sys_script_t systemd_logind_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t systemd_logind_t:process getattr;
allow httpd_sys_script_t systemd_logind_t:unix_dgram_socket getattr;
allow httpd_sys_script_t systemd_logind_t:unix_stream_socket getattr;
allow httpd_sys_script_t systemd_unit_file_t:dir getattr;
allow httpd_sys_script_t systemd_unit_file_t:service { status stop start restart };
allow httpd_sys_script_t tuned_t:dir { open read search };
allow httpd_sys_script_t tuned_t:file { getattr open read };
allow httpd_sys_script_t tuned_t:lnk_file read;
allow httpd_sys_script_t tuned_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t tuned_t:process getattr;
allow httpd_sys_script_t tuned_t:unix_stream_socket getattr;
allow httpd_sys_script_t udev_t:dir { read search open };
allow httpd_sys_script_t udev_t:file { getattr read open };
allow httpd_sys_script_t udev_t:lnk_file read;
allow httpd_sys_script_t udev_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t udev_t:process getattr;
allow httpd_sys_script_t udev_t:unix_dgram_socket getattr;
allow httpd_sys_script_t udev_t:unix_stream_socket getattr;
allow httpd_sys_script_t unconfined_t:dir { open read search };
allow httpd_sys_script_t unconfined_t:file { getattr open read };
allow httpd_sys_script_t unconfined_t:lnk_file read;
allow httpd_sys_script_t unconfined_t:netlink_audit_socket getattr;
allow httpd_sys_script_t unconfined_t:netlink_selinux_socket getattr;
allow httpd_sys_script_t unconfined_t:process getattr;
allow httpd_sys_script_t unconfined_t:unix_dgram_socket getattr;
allow httpd_sys_script_t unconfined_t:unix_stream_socket getattr;
allow httpd_sys_script_t user_home_dir_t:dir search;
allow httpd_sys_script_t user_home_t:lnk_file read;
allow httpd_sys_script_t virtd_t:dir { open read search };
allow httpd_sys_script_t virtd_t:file { getattr open read };
allow httpd_sys_script_t virtd_t:lnk_file read;
allow httpd_sys_script_t virtd_t:netlink_audit_socket getattr;
allow httpd_sys_script_t virtd_t:netlink_kobject_uevent_socket getattr;
allow httpd_sys_script_t virtd_t:netlink_route_socket getattr;
allow httpd_sys_script_t virtd_t:process getattr;
allow httpd_sys_script_t virtd_t:tcp_socket getattr;
allow httpd_sys_script_t virtd_t:unix_stream_socket getattr;
allow httpd_sys_script_t virtlogd_t:unix_stream_socket getattr;

#============= systemd_logind_t ==============
allow systemd_logind_t httpd_sys_script_t:dbus send_msg;
#============= httpd_t ==============
allow httpd_t httpd_sys_script_t:process { noatsecure rlimitinh siginh };
allow httpd_t self:capability net_admin;

Then build a policy from it and install it.

checkmodule -M -m -o cgibin-sudo.mod cgibin-sudo.te && semodule_package -o cgibin-sudo.pp -m cgibin-sudo.md && semodule -i cgibin-sudo.pp

The process for building this selinux policy

How to build this entire .te file is very involved. I had to enable deep selinux auditing as noted in the file.

semodule --disable_dontaudit --build

And to rebuild the current policies with dontaudit back on:

semodule --build

But you have to just keep trying the script in enforcing mode, and check the audit logs and pipe it to audit2allow, and lather, rinse, repeat.

tail -n15000 /var/log/audit/audit.log | audit2allow -m cgibin-sudo -o cgibin-sudo-temp.te # saves to cgibin-sudo-temp.te

Merge any new changes into your master cgibin-sudo.te policy file and rebuild and install it.

checkmodule -M -m -o cgibin-sudo.mod cgibin-sudo.te && semodule_package -o cgibin-sudo.pp -m cgibin-sudo.md && semodule -i cgibin-sudo.pp && echo "" > /var/log/audit/audit.log

Next steps

I need to set up proper server backup tasks and document it.

References

Weblinks

  1. https://stackoverflow.com/questions/25375528/installing-steamcmd-on-centos-7
  2. https://starbounder.org/Guide:LinuxServerSetup
  3. https://starbounder.org/Guide:Setting_Up_Multiplayer#Server_Setup

Comments