Home

Awesome

Build Status

Description

Simple cookbook with LWRPs for managing iptables rules and policies.

Requirements

None, other than a system that supports iptables.

Platforms

The following platforms are supported and known to work:

Other platforms that support iptables and the iptables-restore script are likely to work as well; if you use one, please let me know so that I can update the supported platforms list.

Attributes

This cookbook uses node attributes to track internal state when generating the iptables rules and policies. These attributes should not be overridden by roles, other recipes, etc.

Usage

Include the recipe simple_iptables somewhere in your run list, then use the LWRPs simple_iptables_rule and simple_iptables_policy in your recipes.

simple_iptables_rule Resource

Defines a single iptables rule, composed of a rule string (passed as-is to iptables), and a jump target. The name attribute defines an iptables chain that this rule will live in (and, thus, that other rules can jump to). For instance:

# Allow SSH
simple_iptables_rule "ssh" do
  rule "--proto tcp --dport 22"
  jump "ACCEPT"
end

For convenience, you may also specify an array of rule strings in a single LWRP invocation:

# Allow HTTP, HTTPS
simple_iptables_rule "http" do
  rule [ "--proto tcp --dport 80",
         "--proto tcp --dport 443" ]
  jump "ACCEPT"
end

Additionally, if you want to declare a module (such as log) you can define jump as false:

# Log
simple_iptables_rule "system" do
  rule "--match limit --limit 5/min --jump LOG --log-prefix \"iptables denied: \" --log-level 7"
  jump false
end

By default rules are added to the filter table but the nat and mangle tables are also supported. For example:

# Tomcat redirects
simple_iptables_rule "tomcat" do
  table "nat"
  direction "PREROUTING"
  rule [ "--protocol tcp --dport 80 --jump REDIRECT --to-port 8080",
         "--protocol tcp --dport 443 --jump REDIRECT --to-port 8443" ]
  jump false
end

#mangle example
#NOTE: set jump to false since iptables expects the -j MARK --set-mark in that order
simple_iptables_rule "mangle" do
  table "mangle"
  direction "PREROUTING"
  jump false
  rule "-i eth0 -j MARK --set-mark 0x6
end

#reject all outbound connections attempts to 10/8 on a dual-homed host
simple_iptables_rule "reset_10slash8_outbound" do
  direction "OUTPUT"
  jump false
  rule "-p tcp -o eth0 -d 10/8 --jump REJECT --reject-with tcp-reset"
end

By default rules are added to the chain, in the order in which its occur in the recipes. You may use the weight parameter for control the order of the rules in chains. For example:

simple_iptables_rule "reject" do
  direction "INPUT"
  jump "REJECT --reject-with icmp-host-prohibited"
  weight 90
end

simple_iptables_rule "established" do
  direction "INPUT"
  rule "-m conntrack --ctstate ESTABLISHED,RELATED"
  jump "ACCEPT"
  weight 1
end

simple_iptables_rule "icmp" do
  direction "INPUT"
  rule "--proto icmp"
  jump "ACCEPT"
  weight 2
end

This would generate the rules:

-A INPUT --jump ACCEPT -m conntrack --ctstate ESTABLISHED,RELATED
-A INPUT --jump ACCEPT --proto icmp
-A INPUT --jump REJECT --reject-with icmp-host-prohibited

Defining a simple_iptables_rule resource actually creates a new chain with the name of the resource and a jump to the chain from the chain specified in the direction attribute. By default, the jump is unconditional. However, the chain_condition attribute can be specified to make the jump conditional. For example:

simple_iptables_rule "management_interface" do
  direction "INPUT"
  chain_condition "-i eth1"
  rule [ "-p tcp --dport 80", "-p tcp --dport 443" ]
  jump "ACCEPT"
end

The rules specified under the rule attribute will only be evaluate for packets for which the rule in chain_condition holds.

Sometimes we might want to define a chain where we only want to jump from another chain we define. By default, an automatic jump will be made to chains defined using the simple_iptables_rule resource from the chain specified using the direction attribute of the resource. To prevent jumping to the chain from the direction chains, we can set the direction attribute to the symbol :none. For example, consider a chain used to log

simple_iptables_rule "logging_drop" do
  direction :none
  rule ['-j LOG --log-level 4 --log-prefix "IPTABLES_DROP: "',
        '-j DROP']
  jump false
end

We can then jump to this chain from other simple_iptables_rule chains, but an automatic jump to this chain won't be added.

By default, the name of the simple_iptables_resource is also used for an iptables comment. This default can be overridden by explicitly specifying a comment attribute.

simple_iptables_policy Resource

Defines a default action for a given iptables chain. This is usually used to switch from a default-accept policy to a default-reject policy. For instance:

# Reject packets other than those explicitly allowed
simple_iptables_policy "INPUT" do
  policy "DROP"
end

As with the simple_iptables_rules resource, policies are applied to the filter table by default. You may change the target table to nat as follows:

# Reject packets other than those explicitly allowed
simple_iptables_policy "INPUT" do
  table "nat"
  policy "DROP"
end

redhat.rb recipe

redhat.rb recipe contains default iptables rules for redhat based distributions, such as RHEL, CentOS and etc. You may include simple_iptables::redhat on your linux and get following rules:

*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
*mangle
:PREROUTING ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT --jump ACCEPT -m conntrack --ctstate ESTABLISHED,RELATED
-A INPUT --jump ACCEPT --proto icmp
-A INPUT --jump ACCEPT --in-interface lo
-A INPUT --jump ACCEPT --proto tcp --dport 22 -m conntrack --ctstate NEW
-A INPUT --jump REJECT --reject-with icmp-host-prohibited
-A FORWARD --jump REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed

IPv6 support

To support IPv6, you will need to add ipv6 the attribute like: default["simple_iptables"]["ip_versions"] = ["ipv4", "ipv6"]

When using simple_iptables_policy or simple_iptables_rule resources, you can enable the policy/rule for either :ipv4, :ipv6 or :both using the ip_version parameter. For example:

simple_iptables_rule "management_interface" do
  direction "INPUT"
  chain_condition "-i eth1"
  rule [ "-p tcp --dport 80", "-p tcp --dport 443" ]
  jump "ACCEPT"
  ip_version :both
end

will set the rule for both IPv4 and IPv6,

simple_iptables_rule "management_interface" do
  direction "INPUT"
  chain_condition "-i eth1"
  rule [ "-p tcp --dport 80", "-p tcp --dport 443" ]
  jump "ACCEPT"
  ip_version :ipv6
end

will set it for IPv6 only. The default is to set the rule/policy for ipv4 only.

Example

Suppose you had the following simple_iptables configuration:

# Reject packets other than those explicitly allowed
simple_iptables_policy "INPUT" do
  policy "DROP"
end

# The following rules define a "system" chain; chains
# are used as a convenient way of grouping rules together,
# for logical organization.

# Allow all traffic on the loopback device
simple_iptables_rule "system" do
  rule [ # Allow all traffic on the loopback device
         "--in-interface lo",
         # Allow any established connections to continue, even
         # if they would be in violation of other rules.
         "-m conntrack --ctstate ESTABLISHED,RELATED",
         # Allow SSH
         "--proto tcp --dport 22",
       ]
  jump "ACCEPT"
end

# Allow HTTP, HTTPS
simple_iptables_rule "http" do
  rule [ "--proto tcp --dport 80",
         "--proto tcp --dport 443" ]
  jump "ACCEPT"
end

# Tomcat redirects
simple_iptables_rule "tomcat" do
  table "nat"
  direction "PREROUTING"
  rule [ "--protocol tcp --dport 80 --jump REDIRECT --to-port 8080",
         "--protocol tcp --dport 443 --jump REDIRECT --to-port 8443" ]
  jump false
end

This would generate a file /etc/iptables-rules with the contents:

# This file generated by Chef. Changes will be overwritten.
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:tomcat - [0:0]
-A PREROUTING --jump tomcat
-A tomcat --protocol tcp --dport 80 --jump REDIRECT --to-port 8080
-A tomcat --protocol tcp --dport 443 --jump REDIRECT --to-port 8443
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:system - [0:0]
:http - [0:0]
-A INPUT --jump system
-A system --in-interface lo --jump ACCEPT
-A system -m conntrack --ctstate ESTABLISHED,RELATED --jump ACCEPT
-A system --proto tcp --dport 22 --jump ACCEPT
-A INPUT --jump http
-A http --proto tcp --dport 80 --jump ACCEPT
-A http --proto tcp --dport 443 --jump ACCEPT
COMMIT
# Completed
# This file generated by Chef. Changes will be overwritten.
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed

Which results in the following iptables configuration:

# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
system     all  --  anywhere             anywhere
http       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain http (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https

Chain system (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

#iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
tomcat     all  --  anywhere             anywhere

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain tomcat (1 references)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8080
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:https redir ports 8443

Changes