The following seems to more or less work (at least the output from "iptables -L -v" looks plausible. But it's not persistent. It doesn't seem sensible to wait for propellor to run again to set up a firewall after reboot. Any ideas for how to make this persistent?
module Propellor.Property.SiteSpecific.Tethera.Firewall (
ipFirewall,
) where
import Propellor.Base
import Propellor.Property.Firewall
ipFirewall :: [Port] -> [Port] -> Property DebianLike
ipFirewall tcpPorts udpPorts = propertyList "IPTables based firewall" $ props
& installed
& rule INPUT Filter DROP (Ctstate [INVALID])
& rule INPUT Filter ACCEPT (InIFace "lo")
& rule OUTPUT Filter ACCEPT (OutIFace "lo")
& rule INPUT Filter ACCEPT (Ctstate [ESTABLISHED, RELATED])
& rule INPUT Filter ACCEPT (Proto ICMP)
& openPorts TCP tcpPorts
& openPorts UDP udpPorts
& rule OUTPUT Filter ACCEPT Everything
& rule INPUT Filter DROP Everything
& rule FORWARD Filter DROP Everything
where
openPorts proto lst = combineProperties "open TCP ports" $
toProps (map
(\p -> (rule INPUT Filter ACCEPT
((Proto proto) :- (DPort p)) ))
lst)
Here's what I came up with. I don't know if I'm missing some more obvious way. Thanks to Stefan Gronke on github for answering "what's a simple way to make an iptables systemd service"
Funny, I never considered that the Firewall properties don't do anything persistent.
I don't think we want to get propellor involved in booting the system, either..
Using iptables-save seems to have a problem: If there are other iptables rules that were not set by this run of propellor, it will save those as well. So it could save rules that were set up by something else that was intended to be temporary, or perhaps rules that were set by a earlier propellor config and that then got deleted out of the propellor config.
Another way to do it could be to have Firewall.rule add its configuration to Info and then Firewall.save could see the collected Info from all the rules and use it to generate the boot script itself.
I ran out of time/motivation to do this "right", so I just hardcoded all the things, and made a new module called IPTables