Iptables

IPTables is a command-line utility that is also a standard interface for control of netfilter for Linux core. To use the IPTables utility, you need superuser privileges (root).

netfilter is a set of system messages inside the Linux core. They allow the core modules to register callback functions of the chimney grate. The registered callback function processes each package passing through the network grate.

Linux firewall is controlled by the iptables program which has IPv4 filtration functions.

The # symbol means that the command is conducted from root. You should open in advance the router console — sudo -i in Debian-based systems or su in other ones.

Show status.

# iptables -L -n -v

A sample command output for an inactive firewall:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes) 

 pkts bytes target prot opt in out     source           destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) 

 pkts bytes target prot opt in out     source           destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) 

 pkts bytes target prot opt in out     source           destination

For an active firewall:

Chain INPUT (policy DROP 0 packets, 0 bytes) 

 pkts bytes target prot opt in out     source           destination

0 0 DROP   all  --  *  *       0.0.0.0/0            0.0.0.0/0       state INVALID

  394 43586 ACCEPT all  --  *  *       0.0.0.0/0            0.0.0.0/0       state RELATED,ESTABLISHED

   93 17292 ACCEPT all  --  br0 *       0.0.0.0/0        0.0.0.0/0

1   142 ACCEPT all  --  lo *       0.0.0.0/0        0.0.0.0/0

Chain FORWARD (policy DROP 0 packets, 0 bytes) 

 pkts bytes target prot opt in out     source           destination

0 0 ACCEPT all  --  br0 br0     0.0.0.0/0        0.0.0.0/0

0 0 DROP   all  --  *  *       0.0.0.0/0            0.0.0.0/0       state INVALID

0 0 TCPMSS tcp  --  *  *       0.0.0.0/0            0.0.0.0/0       tcp flags:0x06/0x02 TCPMSS clamp to PMTU

0 0 ACCEPT all  --  *  *       0.0.0.0/0            0.0.0.0/0       state RELATED,ESTABLISHED

0 0 wanin  all  --  vlan2  *       0.0.0.0/0        0.0.0.0/0

0 0 wanout     all  --  *  vlan2   0.0.0.0/0        0.0.0.0/0

0 0 ACCEPT all  --  br0 *       0.0.0.0/0        0.0.0.0/0

Chain OUTPUT (policy ACCEPT 425 packets, 113K bytes) 

 pkts bytes target prot opt in out     source           destination

Chain wanin (1 references) 

 pkts bytes target prot opt in out     source           destination

Chain wanout (1 references) 

 pkts bytes target prot opt in out     source           destination

Where:

  • L : Show the list of rules
  • v : Show additional information. The option shows the name of the interface, options, and TOS masks. It also shows the 'K', 'M', or 'G' suffixes.
  • n : Show IP address and port with numbers without using the DNS server and name defining. Such an approach will allow showing the results faster.

Show the list of rules with line numbers.

# iptables -n -L -v --line-numbers

A sample output:

Chain INPUT (policy DROP) 

num  target prot opt source           destination 

1 DROP   all  --  0.0.0.0/0        0.0.0.0/0       state INVALID 

2 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0       state RELATED,ESTABLISHED 

3 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0 

4 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0 

Chain FORWARD (policy DROP) 

num  target prot opt source           destination 

1 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0 

2 DROP   all  --  0.0.0.0/0        0.0.0.0/0       state INVALID 

3 TCPMSS tcp  --  0.0.0.0/0        0.0.0.0/0       tcp flags:0x06/0x02 TCPMSS clamp to PMTU 

4 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0       state RELATED,ESTABLISHED 

5 wanin  all  --  0.0.0.0/0        0.0.0.0/0 

6 wanout all  --  0.0.0.0/0        0.0.0.0/0 

7 ACCEPT all  --  0.0.0.0/0        0.0.0.0/0 

Chain OUTPUT (policy ACCEPT) 

num  target prot opt source           destination 

Chain wanin (1 references) 

num  target prot opt source           destination 

Chain wanout (1 references) 

num  target prot opt source           destination 

You can use the line numbers to add new rules.

Show INPUT or OUTPUT for a chain of rules.

# iptables -L INPUT -n -v

# iptables -L OUTPUT -n -v --line-numbers

Stop, launch, and relaunch a firewall.

Using the system:

# service ufw stop

# service ufw start

You can also use iptables command to stop the firewall and remove all the rules:

# iptables -F

# iptables -X

# iptables -t nat -F

# iptables -t nat -X

# iptables -t mangle -F

# iptables -t mangle -X

# iptables -P INPUT ACCEPT

# iptables -P OUTPUT ACCEPT

# iptables -P FORWARD ACCEPT

Where:

  • F : Remove (flush) all the rules.
  • X : Remove a chain.
  • t table_name : Choose a table (nat or mangle) and remove all the rules.
  • P : Choose the default actions (such as DROP, REJECT, or ACCEPT).

Remove the firewall rules.

To show the line number that presents the existing rules:

# iptables -L INPUT -n --line-numbers

# iptables -L OUTPUT -n --line-numbers

# iptables -L OUTPUT -n --line-numbers | less

# iptables -L OUTPUT -n --line-numbers | grep 202.54.1.1

Then, you get a list of IP addresses. You should look at the left number and remove a corresponding line. For example, for number 3:

# iptables -D INPUT 3

Or find the IP address of the source (202.54.1.1) and remove it from the rule:

# iptables -D INPUT -s 202.54.1.1 -j DROP

Where:

  • D : Remove one or several rules from the chain.


Add a rule into the firewall.

To add one or several rules to the chain, you should first show the list using line numbers:

# iptables -L INPUT -n --line-numbers

A sample output:

Chain INPUT (policy DROP) 

num  target prot opt source           destination 

1 DROP   all  --  202.54.1.1       0.0.0.0/0 

2    ACCEPT all  --  0.0.0.0/0        0.0.0.0/0       state NEW,ESTABLISHED 

To paste a rule between line 1 and line 2:

# iptables -I INPUT 2 -s 202.54.1.2 -j DROP

Check the rule update:

# iptables -L INPUT -n --line-numbers

Get the output:

Chain INPUT (policy DROP) 

num  target prot opt source           destination 

1 DROP   all  --  202.54.1.1       0.0.0.0/0 

2 DROP   all  --  202.54.1.2       0.0.0.0/0 

3 ACCEPT all  --  0.0.0.0/0       0.0.0.0/0       state NEW,ESTABLISHED 

Save the firewall rules:

Using iptables-save:

# iptables-save > /etc/iptables.rules

Restore the rules.

Using iptables-restore

# iptables-restore < /etc/iptables.rules

Set default policies.

To reset the whole traffic:

# iptables -P INPUT DROP

# iptables -P OUTPUT DROP

# iptables -P FORWARD DROP

# iptables -L -v -n

The above-mentioned commands make sure that no package can leave the host.

# ping google.com

Block only input connections.

To reset all the input packages without your initiative, but accept the output traffic:

# iptables -P INPUT DROP

# iptables -P FORWARD DROP

# iptables -P OUTPUT ACCEPT

# iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT

# iptables -L -v -n

Output packages and those remembered within the set sessions are allowed.

# ping google.com

Reset the addresses of isolated networks in a public network.

# iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP

# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

The list of IP addresses for isolated networks:

10.0.0.0/8 -j (A)

172.16.0.0/12 (B)

192.168.0.0/16 ©

224.0.0.0/4 (MULTICAST D)

240.0.0.0/5 (E)

127.0.0.0/8 (LOOPBACK)

Block a set IP address.

To block a hacker address 1.2.3.4:

# iptables -A INPUT -s 1.2.3.4 -j DROP

# iptables -A INPUT -s 192.168.0.0/24 -j DROP

Block input port requests.

To block all the input requests of port 80:

# iptables -A INPUT -p tcp --dport 80 -j DROP

# iptables -A INPUT -i eth1 -p tcp --dport 80 -j DROP

To block the input request of port 80 from the 1.2.3.4 address:

# iptables -A INPUT -p tcp -s 1.2.3.4 --dport 80 -j DROP

# iptables -A INPUT -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j DROP

Block input requests to the output IP address.

To block a set domain, let’s look at its address:

# host -t a facebook.com

Result: facebook.com has address 69.171.228.40

Let’s find CIDR for 69.171.228.40:

# whois 69.171.228.40 | grep CIDR

Result:

CIDR: 69.171.224.0/19

Then, let’s block the access on 69.171.224.0/19:

# iptables -A OUTPUT -p tcp -d 69.171.224.0/19 -j DROP

You can also use the domain to block access:

# iptables -A OUTPUT -p tcp -d www.fаcebook.com -j DROP

# iptables -A OUTPUT -p tcp -d fаcebook.com -j DROP

Record an event and reset.

To record in a log the movements of the packages before reset, you should add the rule:

# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "

# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Check the log (default /var/log/messages):

# tail -f /var/log/messages

# grep -i --color 'IP SPOOF' /var/log/messages

Record an event and reset (with a limited number of recordings).

Not to overfill the section with a large log, you need to limit the number of recordings using –m. For example, to record a maximum of 7 lines every 5 minutes:

# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix "IP_SPOOF A: "

# iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Reset and accept traffic from set MAC addresses.

# iptables -A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP

## *accept only for TCP port # 8080 from mac adress 00:0F:EA:91:04:07 * ##

# iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00:0F:EA:91:04:07 -j ACCEPT

Accept or decline ICMP Ping requests.

Decline Icmp messages.

A good practice is also the decline of ICMP messages which can provide extra information on the host. They can also be used for fraud like routing table modification. You can the table of possible ICMP messages types below:

ICMP messages types.

0 — echo reply (ping) 

3 — destination unreachable (can’t reach the addressee) 

4 — source quench (request to send packages more slowly) 

5 — redirect

8 — echo request (ping) 

9 — router advertisement

10 — router solicitation 

11 — time-to-live exceeded (the end of life term of a package)

12 — IP header bad (a wrong IP header of a package) 

13 — timestamp request 

14 — timestamp reply 

15 — information request 

16 — information reply

17 — address mask request

18 — address mask reply   

So, the reply to some ICMP messages can result in the disclosure of some information on the host. At the same time, other messages can cause a routing table modification, so they need to be declined.

The output is usually accepted for ICMP messages 0, 3, 4, 11, and 12, while input is allowed only for messages 3, 8, and 12. Here, you can see how the process is applied in different firewalls:

Decline dangerous ICMP messages:

iptables -A INPUT -p icmp --icmp-type 3,8,12 -j ACCEPT 

iptables -A OUTPUT -p icmp --icmp-type 0,3,4,11,12 -j ACCEPT 

To decline:

# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

# iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP

Accept for set networks/hosts:

# iptables -A INPUT -s 192.168.1.0/24 -p icmp --icmp-type echo-request -j ACCEPT

Accept only part of ICMP requests:

### ** it is assumed that default policies on input are installed in DROP ** ###

# iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT

# iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT

## ** accept reply ** ##

# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

  • iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
  • iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
  • iptables -A INPUT -p icmp --icmp-type 12 -j ACCEPT
  • iptables -A OUTPUT -i eth0 -p icmp --icmp-type 0 -j ACCEPT

Open port range.

# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT

Open address range.

## accept the connection to port 80 (Apache) if the address is from 192.168.1.100 to 192.168.1.200 ##

# iptables -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT

 

## example for nat ##

# iptables -t nat -A POSTROUTING -j SNAT --to-source 192.168.1.20-192.168.1.25

Close or open standard ports.

Change ACCEPT to DROP to block the port.

## ssh tcp port 22 ##

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT 

 

## cups (printing service) udp/tcp port 631 for a local network ##

iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT 

 

## time sync via NTP for a local network (udp port 123) ##

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT 

 

## tcp port 25 (smtp) ##

iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT 

 

# dns server ports ##

iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT 

iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT 

 

## http/https www server port ##

iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT 

iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT 

 

## tcp port 110 (pop3) ##

iptables -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT 

 

## tcp port 143 (imap) ##

iptables -A INPUT -m state --state NEW -p tcp --dport 143 -j ACCEPT 

 

## Samba file server for a local network ##

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT 

 

## proxy server for a local network ##

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 3128 -j ACCEPT 

 

## mysql server for a local network ##

iptables -I INPUT -p tcp --dport 3306 -j ACCEPT 

Limit the number of parallel connections to the server from one address.

To do this, you should use the connlimit module. To accept only 3 ssh connections for one user:

# iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT

To set the number of requests HTTP up do 20:

# iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j DROP

Where:

  • connlimit-above 3 : Shows that the rule works only if the number of connections is more than 3.
  • connlimit-mask 24 : Indicates the network mask.


Blog