Debian – Systemd: How to run script before service starts, after service starts and after service stops

debiansystemd

I have a daemon.service that starts every time on different port so I need to allow this random port through iptables every time it starts and deny it every time it stops. So I need to run a script that allows every port in iptables before the daemon.service starts then run script that changes 'allow every port' rule to 'allow only the port that daemon.service uses' after the daemon.service starts and when daemon.service stops I need to run a script that removes that rule. NOTE that daemon.service runs as it's own user and to allow/deny ports through iptables i need to do it as root so I can't use ExecStartBefore/ExecStartAfter in daemon.service

Here is a scheme (kinda) of what needs to happen:

systemctl start deamon.service
|-executing as root 'iptables -A OUTPUT -p tcp -m multiport --dports 0:65535 -j ACCEPT'
|-starting daemon.service as it's own user (not as root)
|-finding (as root) what ports daemon.service uses with netstat (I can do that so I don't need explanation on how to do it)
|-executing as root 'iptables -D OUTPUT -p tcp -m multiport --dports 0:65535 -j ACCEPT'
|-executing as root 'iptables -A OUTPUT -p tcp -m multiport --dports 56731,31267 -j ACCEPT' (ports that were found by netstat)
systemctl stop daemon.service
|-stopping daemon.service as it's own user (not as root)
|-executing as root 'iptables -D OUTPUT -p tcp -m multiport --dports 56731,31267 -j ACCEPT'

NOTE: daemon.service can't be made to run as specified port (not random)

I'm running debian btw.

Best Answer

Well, for setting the iptables stuff you would have to add the service user to the sudoers and run those commands with sudo ....
Nevertheless, instead of fiddling around with iptables, you could open a static port in your firewall, then connect that static port to your dynamic daemon port with socat.

socat -s TCP4-LISTEN:<open-firewall-port>,fork TCP4:localhost:<random-daemon-port>

Then you only would have to run the ExecStartAfter script which determines the random port and starts socat to connect those ports.

Please also note that you might have to change TCP4-LISTEN, TCP4 and/or localhost to match your configuration.