Linux Commands

Iptables for beginners

Iptables are considered one of the main defensive resources for many system administrators despite being replaced by Nftables. Top networking manufacturers incorporated Iptables to hardware still in production environments.

Iptables is highly versatile and accepts direct commands from the user who can load and unload rules according to the need.

This tutorial shows how to protect a web server, forward connections to internal IP addresses from our LAN, and offer specific services to whitelisted IP addresses only.

Note: This Iptables tutorial was first released two years ago and updated on 23/05/2021 with improved examples and better quality screenshots.

How to install

Iptables are omitted by default in distributions that incorporate Nftables.

To install Iptables on Debian based Linux distributions, run the following command:

sudo apt update && apt install iptables

Opening HTTP and HTTPS ports

First of all, let’s add all ACCEPT policies starting with the webserver.

Note: If you create a script with rules, you don’t need to use sudo.

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

To see added rules run “iptables -L

Where:

Iptables = calls the program

-A = adds a rule

INPUT = incoming traffic

-p = protocol

–ddport = destination port

-j = specify the “target”; the target is the type of policy: ACCEPT, DROP, REJECT (Built-in)…

Iptables -L = lists all iptables loaded rules (Iptables -L -v = the same with verbosity.)

In the example above, we instruct Iptables to add a rule for incoming traffic through TCP protocol and ports 80 (http) and 443 (https) to be accepted.

We can change the command to accept the connection only from a specific IP by adding the parameter “-s”:

sudo iptables -A INPUT -s 127.0.0.1 -p tcp --dport 80 -j ACCEPT

Where:

s = source

You can also test your firewall with nmap:

Note: In the example above, port 443 isn’t shown because the server has not an SSL certificate adequately configured.

Note: For more information on Nmap, you can read this.

Protecting your server with Iptables:

#Open HTTP and HTTPS services.

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

#Open SSH Port Service

iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

Where the new parameters are:

-m means “match” and is used to call Iptables extensions like conntrack, which is not part of iptables core functions.

conntrack = Allows tracking information on connections like specific addresses or, in this case, the state of the connection. This must be used carefully since many rules to defend servers from some attacks use conntrack while the hardware limits its use, and such limitation can be used to overload the server’s resources.

-ctstate = determines the state of the rule to match; the possible states are: NEW, ESTABLISHED, RELATED and INVALID.

#Protect your SSH Service against brute force attacks by allowing only a specific IP

to access iptables -A INPUT -p tcp -s X.X.X.X --dport 22 -m conntrack --ctstate NEW,

ESTABLISHED -j ACCEPT

#Protect your SSH Service against brute force attacks by limiting connection attempts
Iptables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j 22-test

Iptables -A 22-test -m recent --name CONNECTIONS --set --mask 255.255.255.255 --rsource

Iptables -A 22-test -m recent --name CONNECTIONS --rcheck --mask 255.255.255.255

--rsource --seconds 30 --hitcount 3 -j 22-protection

Iptables -A 22-test -j ACCEPT

Iptables -A 22-protection -j DROP

Where:

In the first liNe, our rule says “-m conntrack –ctstate NEW,” which means if the connection is new, then pass to the rule “22-test”.

The second line says packets netmask 255.255.255.255 are named as CONNECTIONS.

The third line says if a CONNECTIONS is over 3 times within 30 seconds, the firewall continues applying the chain 22-protection. The fourth line says if the CONNECTIONS weren’t seen over 3 times within 30 seconds, they could be accepted.

The fifth line, which belongs to the 22-protection chain, says to drop CONNECTIONS if they seem to be over 3 times within 30 seconds.

Now to end, let’s refuse all unawolled incoming connections and let’s allow all outgoing traffic:

iptables -P OUTPUT ACCEPT

iptables -P INPUT DROP

P refers to the chain policy; remember the target is the policy, ACCEPT, DROP, REJECT. In this case, we are saying the default policy for outgoing traffic is to accept, and the default policy for incoming traffic is to refuse unless we specified something different in previous rules. This is a very basic firewall that does not include rules for many attacks, for learning purposes and not for production; at the end of the article, I attach a firewall I used for production on a server; it has comments explaining each rule.

FORWARDING A CONNECTION TO A SPECIFIC PORT TO A SPECIFIC IP ADDRESS

This is also very useful for desktop users who want to enroute a connection through a specific device; it can be useful even for gamers; usually, we do it from the router settings but let’s assume the routing device is running Iptables.

iptables -A PREROUTING -t nat -p tcp -d X.X.X.X --dport 8080 -j DNAT --to-destination Y.Y.Y.Y:80

iptables -A POSTROUTING -t nat -p tcp -j SNAT --to-source X.X.X.X

The rules above invoke NAT (Network Address Translation) to specify connections through protocol TCP to the address X.X.X.X, and port 8080 will be redirected to address Y.Y.Y.Y, port 80. The second rule specifies replies must be sent to the source address (X.X.X.X). We can use these rules to allow access to an IP camera, enable online gaming with external networks, etc.

This tutorial was meant to introduce beginners to Iptables and only explains a limited number of basics. Below you can see a sample of a well-planned firewall used for a production server; it includes some of the rules we already saw to more complex rules to prevent DDoS, among other types of attacks.

Bonus: Sample of production firewall

iptables -F

#---- Enable bad error message protection

enable /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

#---- Turn on reverse path filtering. Safer, but breaks asymmetric routing and/or IPSEC

enable /proc/sys/net/ipv4/conf/*/rp_filter

#---- Don't accept source routed packets. Source routing is rarely used for legitimate

purposes disable /proc/sys/net/ipv4/conf/*/accept_source_route

#---- Disable ICMP redirect acceptance which can be used to alter your routing tables

disable /proc/sys/net/ipv4/conf/*/accept_redirects

#---- As we don't accept redirects, don't send Redirect messages either

disable /proc/sys/net/ipv4/conf/*/send_redirects

#---- Ignore packets with impossible addresses

disable /proc/sys/net/ipv4/conf/*/log_martians

#---- Protect against wrapping sequence numbers and aid round trip time measurement

enable /proc/sys/net/ipv4/tcp_timestamps

#---- Help against syn-flood DoS or DDoS attacks using particular choices of initial

TCP sequence numbers enable /proc/sys/net/ipv4/tcp_syncookies

#---- Use Selective ACK which can be used to signify that specific packets are missing

disable /proc/sys/net/ipv4/tcp_sack

modprobe nf_conntrack_ipv4

modprobe nf_nat

# modprobe nf_conntrack_ipv6

# modprobe nf_conntrack_amanda

# modprobe nf_nat_amanda

modprobe nf_conntrack_h323

modprobe nf_nat_h323

modprobe nf_conntrack_ftp

modprobe nf_nat_ftp

# modprobe nf_conntrack_netbios_ns

# modprobe nf_conntrack_irc

# modprobe nf_nat_irc

# modprobe nf_conntrack_proto_dccp

# modprobe nf_nat_proto_dccp

modprobe nf_conntrack_netlink

# modprobe nf_conntrack_pptp

# modprobe nf_nat_pptp

# modprobe nf_conntrack_proto_udplite

# modprobe nf_nat_proto_udplite

# modprobe nf_conntrack_proto_gre

# modprobe nf_nat_proto_gre

# modprobe nf_conntrack_proto_sctp

# modprobe nf_nat_proto_sctp

# modprobe nf_conntrack_sane

modprobe nf_conntrack_sip

modprobe nf_nat_sip

# modprobe nf_conntrack_tftp

# modprobe nf_nat_tftp

# modprobe nf_nat_snmp_basic

#Now we can start adding selected services to our firewall filter. The first such thing

is a localhost interface iptables -A INPUT -i lo -j ACCEPT

#We told the firewall to take all incoming packets with tcp flags NONE and just DROP them.
iptables -A INPUT -p tcp ! -m conntrack --ctstate NEW -j DROP

#We tell iptables to add (-A) a rule to the incoming (INPUT)- SSH works on port 50683

instead 22.

iptables -A INPUT -p tcp -m tcp --dport 50683 -j ACCEPT

iptables -A INPUT -p tcp -m tcp -s specific ip --dport 50683 -j ACCEPT

iptables -A INPUT -p tcp -m tcp -s specific ip --dport 50683 -j ACCEPT

iptables -A INPUT -p tcp -m tcp -s specific ip --dport 50683 -j ACCEPT

iptables -A INPUT -p tcp --dport 50683 -m conntrack --ctstate NEW -m recent --set

--name SSH -j ACCEPT

iptables -A INPUT -p tcp --dport 50683 -m recent --update --seconds 60 --hitcount 4

--rttl --name SSH -j LOG --log-prefix "SSH_brute_force "

iptables -A INPUT -p tcp --dport 50683 -m recent --update --seconds 60 --hitcount 4

--rttl --name SSH -j DROP

iptables -A INPUT -p tcp --dport 50683 -m conntrack --ctstate NEW -m recent --set

--name SSH

iptables -A INPUT -p tcp --dport 50683 -m conntrack --ctstate NEW -j SSH_WHITELIST

iptables -A INPUT -p tcp --dport 50683 -m conntrack --ctstate NEW -m recent --update

--seconds 60 --hitcount 4 --rttl --name SSH -j ULOG --ulog-prefix SSH_bru

iptables -A INPUT -p tcp --dport 50683 -m conntrack --ctstate NEW -m recent --update

--seconds 60 --hitcount 4 --rttl --name SSH -j DROP

#Now I allow imap,and smtp.
-A INPUT -p tcp --dport 25 -j ACCEPT

# Allows pop and pops connections

-A INPUT -p tcp --dport 110 -j ACCEPT

-A INPUT -p tcp --dport 995 -j ACCEPT

############ IMAP & IMAPS ############

-A INPUT -p tcp --dport 143 -j ACCEPT

-A INPUT -p tcp --dport 993 -j ACCEPT

########### MYSQL ###################

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT

########## R1soft CDP System ###############

iptables -A INPUT -p tcp -m tcp -s specific ip --dport 1167 -j ACCEPT

############### outgoing ###################

iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

### Allow ongoing, block incoming not defined ###

iptables -P OUTPUT ACCEPT

iptables -P INPUT DROP

iptables -L -n

iptables-save | tee /etc/iptables.test.rules

iptables-restore < /etc/iptables.test.rules

#service iptables restart

About the author

David Adams

David Adams is a System Admin and writer that is focused on open source technologies, security software, and computer systems.