Setting up a good firewall is necessary for every system administrator to secure their operating system. Iptables is a command line tool that
allows a linux system administrator to configure the tables provided by the linux kernel implemented within the Netfilter project.
Iptables is used to protect your server from unwanted traffic from the internet.
There are many different firewall tools available that you can use to configure your firewall. Iptables is one of them included in most linux distributions by default.
Iptables uses a set of tables with different chains, chains contains set of built in rules or user defined rules.
There are three types of tables available in iptable:
FILTER Table : This is the default table that contains following chains”
- INPUT : This is the default chain that originating to system.
- OUTPUT : This is the default chain that genrating from system.
- FORWARD : This is the default chain that routed through the system.
NAT Table : This table is used when packet tries to create a new connection. It has the following built in chains.
- PREROUTING : This chain alters packets before routing. This is used to translate the destination ip address of the packets that matches the routing on the local machine. It is also used for destination NAT.
- OUTPUT : This chain is used for altering packets that is generated from local machine.
- POSTROUTING : This chain is used for altering packets after routing. This is used translate the source ip address of the packets that match the routing on the local machine.
MANGLE Table : This table is used for packet altering. Currently there are five chains available.
- PREROUTING chain 2. OUTPUT chain 3. FORWARD chain 4. INPUT chain 5. POSTROUTING chain
In this tutorial, we will see different iptables tips and tricks to protect your server on Ubuntu 14.04.
Requirements
- A CentOS-7 server
- A Non-root user account with sudo privileges
Installing Iptables
By default firewalld is available on CentOS-7 to manage iptables, so you will need to disable firewalld and enable first. You can disable firewalld by running the following commands:
sudo systemctl stop firewalld
sudo systemctl mask firewalld
Now, install iptables by running the following command:
sudo yum install iptables-services
Enable the service to start at boot time by running the following commands:
sudo systemctl enable iptables
sudo systemctl enable ip6tables
You can start, ttop and restart the iptables by running the following command:
sudo systemctl start iptables
sudo systemctl stop iptables
sudo systemctl restart iptables
When you reboot the system and restart the iptable service, the existing rules will be flushed out, so you will need to run the following command whenever you add any rule.
sudo service iptables save
The above command will save iptables rules in /etc/sysconfig/iptables file by default and rules are applied or restored in case of iptables flushes out.
Displaying the Status of Your Firewall
To list all rules on filter table, run the following command:
sudo iptables -L
You should see the following output:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
If you want to list ipatbles rules for specific tables like the nat table or mangle table, then run the following commands:
sudo iptables -L -t nat
sudo iptables -L -t mangle
You should see the following output:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
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
If you want to list all the rules with more data, then run the following command:
sudo iptables -L -n -v
Output:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
250 19030 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
3 568 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 129 packets, 14800 bytes)
pkts bytes target prot opt in out source destination
- -L is used to list rules.
- -v is used to list rules with detail information.
- -n is used to display IP address and port in numeric format. This option speeds up the listing because it does not use DNS to resolve names.
You can also list all rules with line number by running the following command:
sudo iptables -n -L -v --line-numbers
Output:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 296 22494 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 3 568 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 159 packets, 19056 bytes)
num pkts bytes target prot opt in out source destination
If you want to list rules for specific chain like INPUT and OUTPUT, then run the following command:
sudo iptables -L INPUT -n -v
sudo iptables -L OUTPUT -n -v
Set the Default Firewall Policies
You can block all incoming and outgoing traffic by running the following commands:
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
After running above commands, you will not be able to connect anywhere.
To block all incoming / forwarded packets, but allow outgoing traffic, run the following commands:
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
Now, check the firewall status by running the following command:
sudo iptables -L -v -n
Output:
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
33 2444 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 3 packets, 328 bytes)
pkts bytes target prot opt in out source destination
Block by IP Address
If you want to block specific IP address (192.168.1.34), then run the following command:
sudo iptables -A INPUT -s 192.168.1.34 -j DROP
Where you need to change 192.168.1.34 as you wish. The -A option appends the rule in the end of the selected chain.
The DROP option drops the packet without responding any acknowledgement.
If you want to block only TCP traffic from that specific IP address then run the following command:
sudo iptables -A INPUT -p tcp -s 192.168.1.34 -j DROP
If you want to block multiple source IP address like 192.168.1.20, 192.168.0.23, 10.11.1.2, then run the following command:
sudo iptables -A INPUT -s 192.168.1.20,192.168.0.23,10.11.1.2 -j DROP
To block specific IP address range, run the following command:
sudo iptables -A INPUT -s 192.168.0.0/24 -j DROP
If you no longer want to block requests from specific IP address, then you can delete the blocking rule with the following command:
sudo iptables -D INPUT -s 192.168.1.34 -j DROP
The -D option deletes one or more rules from the selected chain.
Block Ports in Iptables
Sometimes you will need to block incoming and outgoing connections on a specific port.
If you want to block outgoing connection on port 22, then run the following command:
sudo iptables -A OUTPUT -p tcp --dport 22 -j DROP
To allow incoming connections on port 22, run the following command:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Where you will change the 22 with the actual port as you wish to allow. If you want to block UDP traffic instead TCP, then simply run the following command:
sudo iptables -A INPUT -p udp --dport 22 -j ACCEPT
If you want to allow multiple port like 80, 25 and 443, then use multiport option as below:
sudo iptables -A INPUT -p tcp -m multiport --dports 25,80,443 -j ACCEPT
For outgoing connections, run the following command:
sudo iptables -A OUTPUT -p tcp -m multiport --dports 25,80,443 -j ACCEPT
If you can also limit the certain connections for specific port to specific network. For example if you want to allow outgoing connections on port 80 to network 192.168.0.1/24, then run the following command:
sudo iptables -A OUTPUT -p tcp -d 192.168.0.1/24 --dport 80 -j ACCEPT
To block all service requests on port 80, run the following command:
sudo iptables -A INPUT -p tcp --dport 80 -j DROP
To block port 80 only for an ip address 192.168.1.10, run the following command:
sudo iptables -A INPUT -p tcp -s 192.168.1.10 --dport 80 -j DROP
To block outgoing traffic to network 192.168.0.1/24 from interface eth1, then run the following command:
sudo iptables -A OUTPUT -o eth1 -d 192.168.1.0/24 -j DROP
Block or Accept Traffic from a Mac Address
If you wan to block all incomming connections from specific MAC address, then run the following command:
sudo iptables -A INPUT -m mac --mac-source 01:0P:BA:91:14:08 -j DROP
If you want to accept traffic for TCP port 22 from specific MAC address, then run the following command:
sudo iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 01:0P:BA:91:14:08 -j ACCEPT
Log and Drop Packets
If you want to log and block IP spoofing on specific interface, then run the following commands:
sudo iptables -A INPUT -i eth1 -j LOG --log-prefix "IP_SPOOF A: "
sudo iptables -A INPUT -i eth1 -j DROP
The messages are logged in to file /var/log/messages, you can see by running the following command:
sudo tail -f /var/log/messages
Open Common Ports
To open NTP port for time syncing for specific network, run:
sudo iptables -A INPUT -s 192.168.20.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT
To open SMTP port for mail, run:
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT
To allow HTTP and HTTPS for all, run:
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
To allow printing service for specific network, run:
sudo iptables -A INPUT -s 192.168.20.0/24 -p udp -m udp --dport 631 -j ACCEPT
sudo iptables -A INPUT -s 192.168.20.0/24 -p tcp -m tcp --dport 631 -j ACCEPT
To open POP3 and IMAP port, run:
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 143 -j ACCEPT
To allow Samba file server to specific network, run:
sudo iptables -A INPUT -s 192.168.20.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT
sudo iptables -A INPUT -s 192.168.20.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT
sudo iptables -A INPUT -s 192.168.20.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT
sudo iptables -A INPUT -s 192.168.20.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT
To allow access for mysql, run:
sudo iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
Advanced Iptable Rules
If you want to limit number of concurrent connections establish from single IP address on specific port, then run the following command:
sudo iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 3 -j REJECT
The above command allows only 3 connections on port 80 per client. You can change the port number as your need.
If you want to allow only established and related incoming traffic for incomming connections, run the following command:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
For outgoing connections, run the following command:
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
If you want to block email sending from your system, then you can do this by blocking outgoing ports on SMTP:
sudo iptables -A OUTPUT -p tcp --dports 25,465,587 -j REJECT
Sometimes you will need to forward traffic to another port. You can do this by running the following command:
sudo iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
The above command forwards all incoming traffic on interface eth1 from port 80 to port 8080. You may change the ports with your need.
If you want to share internet, you will need to set FORWARD chain to ACCEPT target by running the following command:
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
Next, you need to enable IP masquerading for your WAN interface on NAT table.
You can do this by running the following command:
sudo iptables -t nat -I POSTROUTING -o wan0 -j MASQUERADE
Delete Iptable Rules
If you want to delete all iptable rules, run the following command:
sudo iptables -F
To delete chain, run the following command:
sudo iptables -X
You can delete chains from specific table like nat and mangle table by running the following command:
sudo iptables -t nat -F
sudo iptables -t mangle -F
You can also delete iptable rules by line number.
First, display all rules for INPUT chain with line number run the following command:
sudo iptables -L INPUT -n --line-numbers
Output:
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
6 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED
In the above output, you can see the list of all rules with line number.
Now, to delete line number 5, run the following command:
sudo iptables -D INPUT 5
Testing Iptable Rules
You can list all open port on your system by running the following command:
sudo netstat -tulpn
Output:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 819/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1445/master
udp 0 0 0.0.0.0:5353 0.0.0.0:* 573/avahi-daemon: r
udp 0 0 0.0.0.0:34090 0.0.0.0:* 573/avahi-daemon: r
udp 0 0 127.0.0.1:323 0.0.0.0:* 586/chronyd
udp 0 0 0.0.0.0:58329 0.0.0.0:* 2327/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 2327/dhclient
You can see that port 22 and 25 are open.
To check whether iptables allowing access to the port 22 from outside or not by running the following command:
sudo iptables -L INPUT -v -n | grep 22
Output:
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
You can also use the telnet command to see if firewall allows to connect to port 22.
On remote machine, run the following command:
telnet server-ip-address 22
You should see the following output:
Trying 192.168.43.7...
Connected to 192.168.43.7.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1
You can also use nmap command to check whether port 22 allow or not:
On remote machine, run the following command:
sudo nmap -sS -p 22 server-ip-address
Output:
“` language-bash
Starting Nmap 6.40 ( http://nmap.org ) at 2016-08-17 14:25 IST
Nmap scan report for centOS-7 (192.168.43.7)
Host is up (0.00082s latency).
PORT STATE SERVICE
22/tcp open ssh
MAC Address: 08:00:27:8C:3F:C6 (Cadmus Computer Systems)
Nmap done: 1 IP address (1 host up) scanned in 0.58 seconds