Puppet and iptables
Bhartshorne (Talk | contribs) |
Bhartshorne (Talk | contribs) |
||
| Line 23: | Line 23: | ||
iptables_add_service{ "swift_common_ssh1": service => "ssh", source => "208.80.152.0/22", jump => "ACCEPT" } | iptables_add_service{ "swift_common_ssh1": service => "ssh", source => "208.80.152.0/22", jump => "ACCEPT" } | ||
iptables_add_service{ "swift_common_ssh2": service => "ssh", source => "91.198.174.0/24", jump => "ACCEPT" } | iptables_add_service{ "swift_common_ssh2": service => "ssh", source => "91.198.174.0/24", jump => "ACCEPT" } | ||
| − | |||
=== drops === | === drops === | ||
Latest revision as of 19:03, 23 November 2011
This page is a brief braindump of what I learned setting up iptables rules for a default deny firewall on the swift hosts Bhartshorne 18:59, 23 November 2011 (UTC)
I highly recommend copy/pasting and modifying an existing set of rules rather than starting from scratch. Feel free to use the rules in swift.pp as an example of a default-deny firewall. With an example handy, this description will likely make more sense.
There are four classes you must set up and include in a specific order to make sure that all the rules show up correctly:
- purges
- accepts (more specific rules)
- drops (more general rules)
- load
Contents |
[edit] service rules
A service rule looks like this:
iptables_add_service{ "swift_common_ssh1": service => "ssh", source => "208.80.152.0/22", jump => "ACCEPT" }
Properties
- source is optional - if you want to accept traffic from 0.0.0.0/0, just leave it out.
- You can only list one IP or CIDR range per rule. If you want to accept from two specific IP addresses, you need two rules
- the first argument is the rule title; it must be unique. If you need two similar rules, consider appending an index as in the example
- the service name must exist in the iptables hash - look at the beginning of iptables.pp for the list.
- the jump target must be an iptables target, commonly ACCEPT, REJECT, DROP, etc.
[edit] accepts
The accepts class is where you put any rules describing the services this host is supposed to run. There's an existing hash in the iptables class that correlates service names to port numbers and protocol, so you can specify 'service => "ssh"' rather than tcp port 22. An example rule that will accept ssh from some of our public IP space:
iptables_add_service{ "swift_common_ssh1": service => "ssh", source => "208.80.152.0/22", jump => "ACCEPT" }
iptables_add_service{ "swift_common_ssh2": service => "ssh", source => "91.198.174.0/24", jump => "ACCEPT" }
[edit] drops
The drops class loads after the accepts rules, so is where you want to place broader deny rules so they don't obscure the more specific accept rules. For a default deny firewall, only one rule is necessary here:
iptables_add_service{ "swift_common_default_deny": service => "all", jump => "DROP" }
If you set up a default deny firewall, make sure you remember to include a rule to allow all RELATED,ESTABLISHED packets through in the accepts class. See swift.pp for an example.
[edit] load
The load class is what pulls the other classes together and then makes them happen. During your initial testing phases, if you want to generate the rules but not enable them on the target host, comment out the line:
iptables_add_exec{ "swift": service => "swift" }
[edit] testing
The rules will wind up in /etc/iptables-save on the destination host. The following is a good way of testing a ruleset without locking yourself out of a host:
/sbin/iptables-restore < /etc/iptables-save && echo "waiting" && iptables-save && sleep 60 && echo "restoring" && iptables -F
It will load the new ruleset and give you 60 seconds to test it. During this time, you should attempt to ssh in to the host from somewhere else. So long as you have ssh access, you can debug other stuff without the time pressure. If the ruleset works (you can successfully ssh in), hit CTRL-C to kill the sleep (and prevent the rest of the command line from executing). If you are locked out of the host, you won't be able to interrupt the sleep, and after 60 seconds, it will run iptables -F (flush) which will clear out the existing ruleset.
An alternate method of testing that lets you toggle between two rulesets instead of opening the host entirely (this assumes the current ruleset is working):
save=$(mktemp)&& /sbin/iptables-save > $save && /sbin/iptables-restore < /etc/iptables-save && echo -n "waiting... " && sleep 60 && echo "restoring" && iptables-restore < $save && rm $save
[edit] purge
The purges class is to allow puppet to revoke rules it's previously put in place. If you ever modify or remove any existing rules, after puppet's happily maintaining your ruleset, you must add them to the purge class. This can be a pain when you're initially setting up the rules, so an alternative is to delete /etc/iptables-save on your test host. Once these rules are managing many hosts, though, it is safer to add the rule to the purge class.