iptables - HaymonEdmur/DockerConfiguration GitHub Wiki

Tables

A table is added in kernel. User cannot add a new table by CLI. Following are the standard tables.

  1. filter
  2. nat
  3. mangle
  4. raw
  5. security

Chains

A chain is an ordered set of rules. A rule can be inserted/deleted/appended to a chain. A user can add a new chain.

Chain-X = { Rule1, Rule2, Rule3, ...., Policy }
If ( packet ~ Rule1 ) then
     take action specified by Rule1
else if ( packet ~ Rule2 ) then
     take action specified by Rule2
....
else 
     Policy = { ACCEPT, DROP, REJECT ... }

These are 3 predefined chains in the filter table to which we can add rules for processing IP packets passing through those chains. These chains are:

Chain Description
INPUT All packets destined for the host computer.
OUTPUT All packets originating from the host computer.
FORWARD All packets neither destined for nor originating from the host computer, but passing through (routed by) the host computer. This chain is used if you are using your computer as a router.

iptables_small

List of all chains in each table

# iptables -t filter -L | grep -iw chain | awk '{print NR,$2}'
1 INPUT
2 FORWARD
3 OUTPUT
4 DOCKER1
5 DOCKER2
6 DOCKER3

iptables -t nat -L | grep -iw chain | awk '{print NR,$2}'
1 PREROUTING
2 INPUT
3 OUTPUT
4 POSTROUTING
5 OUTPUT_direct
6 POSTROUTING_ZONES
7 POSTROUTING_ZONES_SOURCE
8 POSTROUTING_direct
9 POST_public
10 POST_public_allow
11 POST_public_deny
12 POST_public_log
13 PREROUTING_ZONES
14 PREROUTING_ZONES_SOURCE
15 PREROUTING_direct
16 PRE_public
17 PRE_public_allow
18 PRE_public_deny
19 PRE_public_log

iptables -t mangle -L | grep -iw chain | awk '{print NR,$2}'
1 PREROUTING
2 INPUT
3 FORWARD
4 OUTPUT
5 POSTROUTING
6 FORWARD_direct
7 INPUT_direct
8 OUTPUT_direct
9 POSTROUTING_direct
10 PREROUTING_ZONES
11 PREROUTING_ZONES_SOURCE
12 PREROUTING_direct
13 PRE_public
14 PRE_public_allow
15 PRE_public_deny
16 PRE_public_log

iptables -t raw -L | grep -iw chain | awk '{print NR,$2}'
1 PREROUTING
2 OUTPUT
3 OUTPUT_direct
4 PREROUTING_ZONES
5 PREROUTING_ZONES_SOURCE
6 PREROUTING_direct
7 PRE_public
8 PRE_public_allow
9 PRE_public_deny
10 PRE_public_log

iptables -t security -L | grep -iw chain | awk '{print NR,$2}'
1 INPUT
2 FORWARD
3 OUTPUT
4 FORWARD_direct
5 INPUT_direct
6 OUTPUT_direct

How to check a table and its configuration?

By default iptables access filter table. Use -t option to access a required table. Following example shows all the chains in mangle table and its configuration.

# iptables -t mangle -L | grep -w Chain
Chain PREROUTING (policy ACCEPT)
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)
Chain FORWARD_direct (1 references)
Chain INPUT_direct (1 references)
Chain OUTPUT_direct (1 references)
Chain POSTROUTING_direct (1 references)
Chain PREROUTING_ZONES (1 references)
Chain PREROUTING_ZONES_SOURCE (1 references)
Chain PREROUTING_direct (1 references)
Chain PRE_public (1 references)
Chain PRE_public_allow (1 references)
Chain PRE_public_deny (1 references)
Chain PRE_public_log (1 references)

# iptables -t mangle -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N FORWARD_direct
-N INPUT_direct
-N OUTPUT_direct
-N POSTROUTING_direct
-N PREROUTING_ZONES
-N PREROUTING_ZONES_SOURCE
-N PREROUTING_direct
-N PRE_public
-N PRE_public_allow
-N PRE_public_deny
-N PRE_public_log
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A INPUT -j INPUT_direct
-A FORWARD -j FORWARD_direct
-A OUTPUT -j OUTPUT_direct
-A POSTROUTING -j POSTROUTING_direct
-A PREROUTING_ZONES -g PRE_public
-A PRE_public -j PRE_public_log
-A PRE_public -j PRE_public_deny
-A PRE_public -j PRE_public_allow

How to add a new chain to a table?

Following command adds a new rule to a security table

# iptables -t security -N BRAINTREE

# iptables -t security -L | grep -iw chain | awk '{print NR,$2}'
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain BRAINTREE (0 references)
Chain FORWARD_direct (1 references)
Chain INPUT_direct (1 references)
Chain OUTPUT_direct (1 references)

How to delete a chain into a table?

By default a chain is accessed from a filter table.

A chain may be empty (without any rule). Following chain is any empty chain.

# iptables -t security -X BRAINTREE

Lets us add a chain to filter table with a rule and try to delete the chain

# iptables -N BRAINTREE

# iptables -t filter -L | grep BRAINTREE
Chain BRAINTREE (0 references)

# iptables -A BRAINTREE -p tcp --dport 22 -j DROP

# iptables -L BRAINTREE --line-numbers
Chain BRAINTREE (0 references)
num  target     prot opt source               destination
1    DROP       tcp  --  anywhere             anywhere             tcp dpt:ssh

# iptables -X BRAINTREE
iptables: Directory not empty.

  • Delete all rules from a chain before deleting a chain of a table.
# iptables -D BRAINTREE 1
# iptables -L BRAINTREE --line-numbers
Chain BRAINTREE (0 references)
num  target     prot opt source               destination
# iptables -X BRAINTREE

How block SSH ?

You want to allow SSH connection only from one Window server. All other servers should not get access to port 22 on Linux server.


Server IP Address SSH Access Linux Server IP
window server 192.168.1.16 **All putty to connect Linux Server ** 192.168.1.35

For this requirement we can add a new rule in filter table in INPUT chain.

# iptables -t filter -A INPUT -s 192.168.1.16 -p tcp --dport 22 -j ACCEPT 

# iptables -t filter -A INPUT -p tcp --dport 22 -j DROP 

# iptables -t filter -L INPUT --line-number 
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     tcp  --  192.168.1.16         anywhere             tcp dpt:ssh
2    DROP       tcp  --  anywhere             anywhere             tcp dpt:ssh

Tables and Chains processing flow

tables_chains

tables_chains_stream

AWS Docker configuration for iptables

AWS EC2 adds following rules into nat table

# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 58080 -j DNAT --to-destination 172.17.0.2:80