While I'm not aware of a single/simple iptables
rule to have it open/close a port based on a service actually listening on that port, you can achieve what you need by changing the default iptables
policy to DROP
and allow only the ports you need.
For example, say you have sshd
listening on port 22
and apache2
on port 80
(don't do this if connected via ssh!)
# Start with empty tables
iptables -F
iptables -X
# Change INPUT policy to DROP
iptables -P INPUT DROP
# Make sure the machine itself can connect to the internet
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Maybe allow ICMP's echo/reply (i.e. ping)
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
# Add ports for which there are services listening
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
This way, for every port but 22 and 80, iptables
drops the packets.
If you need a new port open, just add ("append") a new rule
iptables -A INPUT -p tcp --dport NN -j ACCEPT
If you don't need a port anymore, delete the relevant rule
iptables -D INPUT -p tcp --dport 80 -j ACCEPT
If you want a sort of automatic allowing/denying based on services (it looks so from your question), you can always have a basic iptables
ruleset and then modify your services' scripts to append (-A) the relevant rule on startup and delete it (-D) on stop.