Half off-topic, sorry: if you have some spare time on the weekend, you might want to take a look at nftables. AFAIK iptables is also just using nftables under the hood, so you are basically using a deprecated technology.
nftables is so much nicer to work with. In the end I have my custom rules (which are much saner to define than in iptables) in /etc/nftables.conf
, then I have a very simple systemd unit:
[Unit]
Description=Restore nftables firewall rules
Before=network-pre.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/nft -f /etc/nftables.conf
ExecStop=/usr/sbin/nft flush table inet filter
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
and finally if I push updates via ansible I simply replace the file and run nft -f /etc/nftables.conf
(via ansible; on-change event).
Edit: oh and as an example how the actual rules file looks like:
#!/usr/bin/nft -f
add table inet filter
flush table inet filter
table inet filter {
chain input {
type filter hook input priority 0;
# allow established/related connections
ct state {established, related} accept
# early drop of invalid connections
ct state invalid drop
# allow from loopback
iifname lo accept
# allow icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# core services
tcp dport {80, 443} accept comment "allow http(s)"
udp dport 443 accept comment "allow http3"
# everything else
reject with icmpx type port-unreachable
}
}
and with that I have my ipv4+6 firewall that allows pings and http