Nowadays setting up cloud machines have become a usual day to day paractice. But whenever you create a machine, you always have to deal with some network issues because at some point you would like to connect to your machine or even allow the machine to interact to the external network. More importantly it determines the security of your machine. The more detailed the network settings are, better is the firewall of your machine.
Setting up a detailed and good firewall is one of the most important step in securing any operating system. Iptables is one of the standard firewall which is available in most Linux distributions. It acts as an interface to the kernel-level netfilter hooks that alters the network stack. The main working principle consists of matching each packet that passed the networking interface to the set of defined rules in the iptable.
The packets are defined by the follwing main characteristics:
- Protocol
- Source port
- Destination port
- Source address
- Destination address
- Interface being used
- Relation to previous packets, ... etc
When a certain pattern matches, an action takes place which is called target. It determines the final outcome of a packets such as accept or drop. However there are several other possible options.
All the rules combined together is defined as chains. A packet is matched to the rules of a chain sequentially and it executes the matched action immediately and leaves the rest.
Different chains can be creates as per required, however there are 3 chains defined by default.
- INPUT : It handles the packets addressed to your server.
- OUTPUT: It handles the packets created by your server.
- FORWARD: It handles the packets that are supposed to be forwarded to other servers.
There can be either none or more rules per chain. Each chain has a default policy which determines the consequence of a packet if it does not match to any rules mentioned in the chain.
Iptables call also track connections, which is possible through a module that can be loaded via rules. It means that a rule can also be created which determines the outcome of a packet based on its relationship to previous packets. This property is called "state tracking", "connection tracking" or configuring the "state machine".
In this blog, we will cover the command lines for the most frequent cases:
(for specific network interface, e.g. eth0, you need to add -i eth0 to command lines)
- Delete existing rules
iptables -F
(or)
iptables --flush
(or)
sudo iptables -D OUTPUT -p tcp --sport 8000 -d 0.0.0.0/0 -j ACCEPT
- Setting up default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
- Blocking an ip-address
iptables -A INPUT -s "$BLOCK_THIS_IP" -j DROP
- Allow incoming SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
- Allow outgoing SSH
iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
- Allow incoming SSH from a sepcific network
iptables -A INPUT -p tcp -s xyz.xyz.xyz.0/23 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
- Allow outgoing SSH to a sepcific network
iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -d xyz.xyz.xyz.0/23 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
- Allow incoming HTTP
iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
- Allow outgoing HTTP
iptables -A INPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
- Allow incoming HTTPS
iptables -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
- Allow outgoing HTTPS
iptables -A INPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
- Allow IMAP & IMAPS
# IMAP
iptables -A INPUT -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
# IMAPS
iptables -A INPUT -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
- Allow POP3 & POP3S
# POP3
iptables -A INPUT -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
# POP3S
iptables -A INPUT -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
- Port forwarding
# routes all traffic from port 442 to 22
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
- Logging
# Create new chain logging
iptables -N LOGGING
# All packets which could not be matched to a rule should go to logging
iptables -A INPUT -j LOGGING
# Specify a custom “log-prefix” to logs.
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "Packet Dropped: " --log-level 7
# Drop these packets
iptables -A LOGGING -j DROP
- For standard HTTP web server:
# Allow all ips to connect to port 8000 and output port 8000 to them
sudo iptables -A INPUT -p tcp --dport 8000 -s 0.0.0.0/0 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 8000 -d 0.0.0.0/0 -j ACCEPT
(note: to delete these rules, just replace -A by -D)
- For e.g to get whois data:
sudo iptables -A INPUT -p tcp --sport 43 -d 0.0.0.0/0 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 43 -s 0.0.0.0/0 -j ACCEPT
- To save and then restore all the rules of iptables
# Saving the rules
iptables-save > file_name
# Restoring the rules
iptables-restore < file_name
To get more information regarding iptables, you can always go to the manual page by:
sudo iptables --help