Linux Firewall using IPTABLES
What is IPTABLES?
· Iptables is a generic table structure for the definition of rulesets
· iptables is Linux's firewall which has been a part of the kernel since version 2.4
What can I do with netfilter/iptables?
· build internet firewalls based on stateless and stateful packet filtering
· use NAT and masquerading for sharing internet access if you don't have enough public IP addresses
· use NAT to implement transparent proxies
The Rules of the Game…
· iptables makes decisions on what to do with a packet based on rules
· A rule specifies the criteria necessary for a packet to match it
· A decision is known as a target and it can be a user-defined chain (not covered in this article) or one of the following:
Things to remember… DECISION
ACCEPT Allow the packet through the firewall.
DROP Drops the packet; the packet is not allowed through the firewall
TABLES
There are three default tables which the packets may traverse; we are only concerned with one of these right now: the filter
table. This is the default table and contains three chains: the filter table
(filter table)
OUTPUT For packets generated by and leaving your machine
INPUT Any packets coming into your mahine
FORWARD For packets being routed through your machine
The two other tables available by default are the nat table and the mangle table. This will be discussed on advance topic.
STATES
This means that we can create rules not only based on IPs and ports but also on whether a packet exists in any of the following states:
NEW The packet is trying to start a new connection.
ESTABLISHED A connection that has seen packets travel in both directions
RELATED A packet that is starting a new connection but is related to an
existing connection
INVALID This packet is associated with no known connection. These packets
should be dropped.
Creating and Saving the RULES
Rules can be appended to the chains directly by using the iptables command.
Example: To add a new rule to allow new connections to a web server running on your computer from anywhere we would execute the following:
$ iptables -A INPUT -s 0/0 -d 10.10.10.10 -m state --state NEW -p tcp --dport 80 -i eth0 -j ACCEPT
where:
-s (or --src or --source) and -d (or --dst or --destination)
0/0 is shorthand for 0.0.0.0/0.0.0.0 meaning that the source can be ANY IP address.
10.10.10.10 is the IP Address our your machine or the destination address
-m state --state NEW
matches only packets that have a status of NEW. This can be anyone
of or a comma separated list of the four possible states.
-p tcp
apply this rule to packets using the TCP protocol only. This can be
anyone of tcp, udp, icmp or all (default). The exclamation mark can
be used to invert the match.
--dport 80 (or --destination-port)
matches a packet trying to connect to port 80. The exclamation mark
can be used to invert this match also. A range of ports can be
given in the format begin:end.
-i eth0 (or --in-interface eth0)
name of an interface via which a packet is going to be received.
Possible interfaces on your computer can be found using the command
'ifconfig'. In this example your computer is connected to
the Internet through the first (or only) ethernet card.
-j ACCEPT
the target. In this case, if the incoming packet is creating a new
TCP connection from anywhere to port 80 on your computer through
the first ethernet card, we will allow it through.
Breaking the Manual Creation
File: /etc/sysconfig/iptables
The essential elements of an iptables file
1 # Firewall configuration
2 *filter
3 :INPUT [0:0]
4 :FORWARD [0:0]
5 :OUTPUT [0:0]
6 # your rules here
7 COMMIT
Line 1 Comment
Line 2 this file tells iptables that the following rules apply to the filter table.
Line 3, 4, 5 define the default targets for the three chains. We place our rules after these and before COMMIT
Line 6 comment about your rules
Line 7 Commit, end of the file
Each packet traverses the rules of the appropriate chain from the first to the last. If a packet matches a rule then it stops
traversing the chain at that rule and its fate is decided by that rule's target. If the packet does not match any rule then its
fate is the default target of its chain.
Skeleton …
Using this skeleton, you can easily create your rules and adjust as you need it.
# Start of the file
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# allow local loopback connections
-A INPUT -i lo -j ACCEPT
# drop INVALID connections
-A INPUT -m state --state INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP
-A FORWARD -m state --state INVALID -j DROP
# allow all established and related
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# add your rules here before the COMMIT
COMMIT
Scenario 1: Standard Machine
A good practice in firewall is to allow the needed ports/connections then drop all. In that order you can monitor the OPEN ports/connections.
/etc/sysconfig/firewall
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
# Loopback connections
-A INPUT -i lo -j ACCEPT
# Drop ALL INVALID Connections
-A INPUT -m state --state INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP
-A FORWARD -m state --state INVALID -j DROP
# Allow all established and related connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# OUTPUT CHAIN HERE
# allow connections to my ISP's DNS servers
# Primary DNS 10.9.8.7, Secondary DNS 10.9.8.6
# DNS port is 53
-A OUTPUT -d 10.9.8.7 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
-A OUTPUT -d 10.9.8.6 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
# allow outgoing connections to web servers
# Destination is ANY
# http is port 80, https is port 443
-A OUTPUT -d 0/0 -m state --state NEW -p tcp --dport http -o eth0 -j ACCEPT
-A OUTPUT –d 0/0-m state --state NEW -p tcp --dport https -o eth0 -j ACCEPT
# allow outgoing mail connections to my ISP's SMTP and POP3 server only
# Mail Server is 10.10.10.40
-A OUTPUT -d 10.10.10.40 -m state --state NEW -p tcp --dport smtp -o eth0 -j ACCEPT
-A OUTPUT -d 10.10.10.40 -m state --state NEW -p tcp --dport pop3 -o eth0 -j ACCEPT
# log all other attempted out going connections
-A OUTPUT -o eth0 -j LOG
# default is to DROP out-going connections
COMMIT