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.