When deploying game servers or other services on Linux systems, security best practices dictate running them under unprivileged users. However, this creates a permissions paradox when those same users need to manage their own services through systemd.
The modern solution leverages Polkit (formerly PolicyKit), which provides fine-grained control over privileged operations. We'll create a custom policy that grants limited systemctl permissions exclusively for the target service.
# /etc/polkit-1/rules.d/10-gameserver.rules
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "game-server.service" &&
subject.user == "gamesrv") {
return polkit.Result.YES;
}
});
For systems without Polkit or when needing simpler deployment:
# /etc/sudoers.d/gameserver
gamesrv ALL=(root) NOPASSWD: /bin/systemctl start game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl stop game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl restart game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl status game-server.service
After implementing either solution, test with:
sudo -u gamesrv systemctl status game-server.service
sudo -u gamesrv systemctl restart game-server.service
When running game servers on Linux systems, we often face a security vs convenience dilemma. The service needs to run under an unprivileged user account (like gamesrv
) for security, but performing service operations (start/stop/restart) traditionally requires root privileges.
The modern approach uses Polkit (formerly PolicyKit) to grant fine-grained permissions. Create a Polkit rule file at /etc/polkit-1/rules.d/10-gameserver.rules
:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "game-server.service" &&
subject.user == "gamesrv") {
return polkit.Result.YES;
}
});
For systems without Polkit, create a sudoers entry in /etc/sudoers.d/gameserver
:
gamesrv ALL=(root) NOPASSWD: /bin/systemctl start game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl stop game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl restart game-server.service
gamesrv ALL=(root) NOPASSWD: /bin/systemctl status game-server.service
After applying either method, test the configuration as the gamesrv
user:
sudo -u gamesrv systemctl restart game-server.service
# Or with Polkit:
sudo -u gamesrv pkexec systemctl restart game-server.service
- Always limit permissions to specific services
- Consider adding IP restrictions if allowing remote management
- Regularly audit permission files
- Prefer Polkit over sudo when possible for finer control
For programmatic control without systemctl, you can use DBUS directly:
dbus-send --system --dest=org.freedesktop.systemd1 \
--type=method_call --print-reply \
/org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager.RestartUnit \
string:"game-server.service" string:"replace"