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.

  • I'm all for notching another mark in the "systemd is inflexible and fiddly!" column but, running at all of those times, as root, seems like an extremely specific use case that it's easier for you to engineer around than for systemd to design around; if this mystery service insists on launching on a random port (is the vendor a sadist?), then how about launching it from a wrapper service that you write, or having a separate service proxying to the random port instead of using iptables rewriting? – Shane Madden Apr 22 '17 at 7:20

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.

  • But that would work only if the daemon doesn't fails and stops immediately if it can't connect through the random port, right? Because if it does that then you can't detect what port it wants to allow it? (My daemon isn't like that so it'll work) – FieryRider Apr 23 '17 at 23:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.