---
categories:
- Linux
comments: true
date: 2015-10-18 16:54:25+0200
layout: page
tags:
- Linux
- systemd
title: 'Tip: opening and closing ports needed by a systemd service'
---

Recently I've been testing out murmur, [http://wiki.mumble.info/wiki/Main_Page](Mumble's) server component, on my CentOS 7 server. Murmur requires specific ports being open to operate, and when using it I would open them manually, and close them after the session had been completed.

I found it pretty tedious: I wanted to wrap it into a single call to the service, so I could enable my user (via ``sudoers``) to be able to start and stop the service without worrying about elevating permissions to start and stop the firewall. After reading a bit [systemd's documentation](http://www.freedesktop.org/software/systemd/man/systemd.service.html) I found about ``ExecStartPre`` and ``ExecStopPost`` that would work perfectly for the job.

It was easier said than done, though. That is because I, following the [guide on the Mumble wiki](http://wiki.mumble.info/wiki/Install_CentOS7), had set up a separate user to run the Murmur service, causing permission errors when adjusting the firewall:

````syslog
firewall-cmd[20897]: Authorization failed.
firewall-cmd[20897]: Make sure polkit agent is running or run the application as superuser.
````

I didn't feel comfortable to give this user control the firewall. However, the systemd documentation mentioned a ``PermissionsStartOnly`` option for units, which is described as

> Takes a boolean argument. If true, the permission-related execution options, as configured with User= and similar options (see systemd.exec(5) for more information), are only applied to the process started with ExecStart=, and not to the various other ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, and ExecStopPost= commands. If false, the setting is applied to all configured commands the same way. Defaults to false.


Exactly what I needed! And thus, I amended the unit file as follows:

````systemd
[Unit]
Description=Mumble Server (Murmur)
Requires=network-online.target
After=network-online.target mariadb.service time-sync.target

[Service]
User=murmur
Type=forking
PIDFile=/run/murmur/murmur.pid
PermissionsStartOnly=true
ExecStartPre=/usr/bin/firewall-cmd --add-service=murmur
ExecStart=/usr/local/murmur/murmur.x86 -ini /etc/murmur.ini
ExecStopPost=/usr/bin/firewall-cmd --remove-service=murmur

[Install]
WantedBy=multi-user.target
````
A ``systemctl daemon-reload`` afterwards, I was set! Now the service opens and closes the port when it is started or stopped, respectively.