• Get In Touch
August 19, 2016

Working with Iptables

Need Hosting? Try ours, it's fast, reliable and feature loaded with support you can depend on.
View Plans

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”

  1. INPUT : This is the default chain that originating to system.
  2. OUTPUT : This is the default chain that genrating from system.
  3. 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.

  1. 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.
  2. OUTPUT : This chain is used for altering packets that is generated from local machine.
  3. 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.

  1. 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
Need Hosting? Try ours, it's fast, reliable and feature loaded with support you can depend on.
View Plans

Share this Article!

Related Posts

Node.js Authentication – A Complete Guide with Passport and JWT

Node.js Authentication – A Complete Guide with Passport and JWT

Truth be told, it’s difficult for a web application that doesn’t have some kind of identification, even if you don’t see it as a security measure in and of itself. The Internet is a kind of lawless land, and even on free services like Google’s, authentication ensures that abuses will be avoided or at least […]

Node.js and MongoDB: How to Connect MongoDB With Node

Node.js and MongoDB: How to Connect MongoDB With Node

MongoDB is a document-oriented NoSQL database, which was born in 2007 in California as a service to be used within a larger project, but which soon became an independent and open-source product. It stores documents in JSON, a format based on JavaScript and simpler than XML, but still with good expressiveness. It is the dominant […]

Using MySQL with Node.js: A Complete Tutorial

Using MySQL with Node.js: A Complete Tutorial

Although data persistence is almost always a fundamental element of applications, Node.js has no native integration with databases. Everything is delegated to third-party libraries to be included manually, in addition to the standard APIs. Although MongoDB and other non-relational databases are the most common choice with Node because if you need to scale an application, […]

Node.Js Vs Django: Which Is the Best for Your Project

Node.Js Vs Django: Which Is the Best for Your Project

Django and NodeJs are two powerful technologies for web development, both have great functionality, versatile applications, and a great user interface. Both are open source and can be used for free. But which one fits your project best? NodeJs is based on JavaScript, while Django is written in Python. These are two equally popular technologies […]

Nodejs Vs PHP:  Which Works Best?

Nodejs Vs PHP: Which Works Best?

Before getting into the “battle” between Node.js and PHP we need to understand why the issue is still ongoing. It all started with the increased demand for smartphone applications, their success forcing developers to adapt to new back-end technologies that could handle a multitude of simultaneous requests. JavaScript has always been identified as a client-side […]