chr4

Devops Diary

iptables-ng cookbook for chef

Today, I released iptables-ng, a cookbook to maintain iptables rules on different machines using chef.

But why another cookbook? There are two fairly often used around

Well, I wanted a tool which can do all the following:

  • Configure iptables rules in a consistent and nice way for all distributions
  • Be configured by using LWRPs only
  • Be configured by using node attributes only
  • Respect the way the currently used distribution stores their rules
  • Provide a good-to-read and good-to-maintain way of deploying complex iptables rulesets
  • Provide a way of specifying the order of the iptables rules, in case needed
  • Only run iptables-restore once during a chef run, and only if something was actually changed
  • Support both, ipv6 as well as ipv4
  • Be able to assemble iptables rules from different recipes (and even cookbooks), so you can set your iptables rule where you actually configure the service

# Respect the way the distribution handles iptables

Every distribution has its own way of maintaining iptables rules. While iptables-restore provides a generic format/tool available to save and restore iptables rules, every distribution uses it differently.

# Debian and Ubuntu

Debian based systems provide a package called iptables-persistent, which provides a system service to save and load iptables rules. Debian Squeeze (and earlier) use an outdated version of iptables-persistent, which doesn’t support ipv6.

iptables-persistent stores the rules in these files:

1
2
3
# Debian
/etc/iptables/rules.v4 # ipv4
# ipv6 [not supported]
1
2
3
# Ubuntu
/etc/iptables/rules.v4 # ipv4
/etc/iptables/rules.v6 # ipv6

# RHEL

Redhat (and clones like CentOS) provide a system service by default which loads iptables rules from the following files:

1
2
3
# RHEL
/etc/sysconfig/iptables  # ipv4
/etc/sysconfig/ip6tables # ipv6

# Gentoo

Gentoo also provides system services by default, but stores the rules here:

1
2
3
# Gentoo
/var/lib/iptables/rules-save  # ipv4
/var/lib/ip6tables/rules-save # ipv6

# Archlinux

Archlinux uses iptables-restore too, and stores its files here:

1
2
3
# Archlinux
/etc/iptables/iptables.rules  # ipv4
/etc/iptables/ip6tables.rules # ipv6

# The new iptables-ng cookbook

The iptables-ng cookbook supports all of those platforms transparently for the user, as well as trying to be as compatible as possible to the way of the currently used distribution.

It automatically saves the assembled rules to the locations specified above, and if the system doesn’t support its own service provider, it will fall back to apply to rules manually using iptables-restore. (This enables e.g. ipv6 support in Debian, yeee!)

It furthermore provides LWRPs for all its functions, while it also can be configured using only node attributes.

# Examples

Let me show you some examples

1
2
3
4
5
6
7
8
# Set default policy to DROP (whitelist mode)
# Unless it is already specified
%w{input output forward}.each do |chain|
  iptables_ng_policy chain.upcase do
    policy 'DROP [0:0]'
    action :create_if_missing
  end
end
1
2
3
4
# Drop invalid packages
iptables_ng_rule '10-input-drop-invalid' do
  rule '--match state --state INVALID --jump DROP'
end
1
2
3
4
5
6
# Drop ICMP timestamp packages (ipv4 only)
iptables_ng_rule '14-drop-icmp-timestamp' do
  rule [ '--protocol icmp --icmp-type timestamp-request --jump DROP',
         '--protocol icmp --icmp-type timestamp-reply --jump DROP' ]
  ip_version 4
end
1
2
3
4
5
6
# Masquerade (nat table automatically is only applied to ipv4)
iptables_ng_rule '99-masquerade' do
  chain 'POSTROUTING'
  table 'nat'
  rule  '-o eth0 -j MASQUERADE'
end
1
2
3
4
# Delete a rule
iptables_ng_rule '10-unwanted-rule' do
  action :delete
end

All rules will be written to /etc/iptables.d directory, resulting in the following directory structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
├── filter
│   ├── FORWARD
│   │   └── default
│   ├── INPUT
│   │   ├── 10-input-drop-invalid.rule_v4
│   │   ├── 10-input-drop-invalid.rule_v6
│   │   ├── 14-drop-icmp-timestamp.rule_v4
│   │   └── default
│   └── OUTPUT
│       └── default
├── mangle
│   ├── FORWARD
│   │   └── default
│   ├── INPUT
│   │   └── default
│   ├── OUTPUT
│   │   └── default
│   ├── POSTROUTING
│   │   └── default
│   └── PREROUTING
│       └── default
├── nat
│   ├── OUTPUT
│   │   └── default
│   ├── POSTROUTING
│   │   ├── 99-masquerade.rule_v4
│   │   └── default
│   └── PREROUTING
│       └── default
└── raw
    ├── OUTPUT
    │   └── default
    └── PREROUTING
        └── default

At the end of the chef run, they will be assembled into a sinble iptables restore script. Finally, if the ruleset was changed, iptables-ng takes care of reloading the rules, using the systems provider (e.g. /etc/init.d/iptables). If the system doesn’t provide it’s own way of loading the rules, iptables-ng will fall back to iptables-restore.

Fore more examples, have a look at the README

# Get it!

You can grab your copy from these locations