Protecting your Perimeter Part I - IPTABLES
This article will be my first in a series of articles about network security. I decided to write this article about iptables while it is still fresh from my memory. This is intended for beginners who wish to get familiar with the basics of Iptables(like me) and some basic concepts in creating a network firewall.
What is Iptables?
Iptables is a program in Linux that is used to setup, maintain and inspect IPv4 packet filter rules. For IPv6 traffic, there is also an Ip6tables program that can be used to inspect IPv6 packet filter rules. Since IPv4 address is already almost depleted, I find it very important to give examples in both IPv4 and IPv6 packet filtering.
Adding an Iptables rule
In creating a network firewall, you basically need to write rules. Each packet that passes through the firewall will be matched to these set of rules. The general syntax of adding an Iptables rule is:
# iptables <name of table> <name of chain> <layer 3 object> [layer 4 object] <jump target>
Iptables has four tables(ip6tables only has three) and each table has its own specific purpose:
- filter table
- nat table
These tables corresponds to the different stages that a packet undergoes as it gets in an out to your firewall. There is no more NAT in IPv6, so Ip6tables don't have the nat table anymore that's why it has only three tables. The filter table, nat mangling table and the raw table.
If a table is not specified(no -t option is passed), the default table is the filter table.
Each table has built-in chains and may also contain user-defined chains. Each chain contains a set of rules that are matched on every packet that pass through the chain. Each rule specifies a criteria on what to do with a packet that matches. This is called a target. If a packet does not match the rule, the next rule in the chain is examined. If it matches the rule, then the next rule is specified by the value of the target, which can be the name of a user-defined chain or one of these values:
- ACCEPT – let the packet pass through.
- DROP – drop the packet. Do not let it pass.
- QUEUE – pass the packet to the userspace.
- RETURN – stop traversing this chain and resume at the next rule in the previous chain.
The filter table, which is the default table, has the following built-in chains:
- INPUT – for packets destined to local sockets.
- FORWARD – for packets being routed through the box.
- OUTPUT – for locally-generated packets.
The nat table has the following built-in chains:
- PREROUTING – for altering packets as soon as they come in.
- OUTPUT – for altering locally-generated packets before routing.
- POSTROUTING – for altering packets as they are about to go out.
The mangle table has PREROUTING, OUTPUT, INPUT, FORWARD and POSTROUTING chains. This table is used for specialized packet alteration (eg. Network traffic prioritization). While the raw table is used mainly for configuring exemptions from connection tracking. All packets, both incoming and outgoing will come to pass through this table first before anything else. It provide the following built-in chains: PREROUTING and OUTPUT.
A packet that matches a certain rule can be made to ju
A sample Iptables rule
Playing with iptables may result to an unaccessable machine. Do not experiment unless you are sure with what you are doing and that you can access your machine directly to the console.
# iptables -t filter -A INPUT -s 192.168.1.2 -j DROP
# iptables -A INPUT -s 192.168.1.2 -j DROP
This command will add an iptables rule to the INPUT chain of the filter table. The rule will drop any packet that is coming from the IP address 192.168.1.2. So be very extra careful in testing this rule. If you are access your machine via ssh and your IP address is 192.168.1.2, you will automatically be block.
A sample Ip6tables rule
This is similar with the first example, only this rule will drop any packet that is coming from the IPv6 address 2001:db8::2. Same caution must be observed in testing this rule.
# ip6tables -t filter -A INPUT -s 2001:db8::2 -j DROP
# ip6tables -A INPUT -s 2001:db8::2 -j DROP
may be remove since if it is not specified, by default, the rule will be added to the filter table.
Some Commands to list Tables and Chains
- list all rules from all chains from filter table.
iptables -L -v #
- list all rules from all chains from filter table in verbose mode showing all packets and bytes that matched the rules.
iptables -L -v –line-numbers
- same as the above command but also show rule the rule numbers.
iptables -L INPUT
- show all rules from the INPUT chain of the filter table.
iptables -L -t nat
- show all rules from all the chains of the nat table.
iptables -t nat -L PREROUTING
- show all rules from PREROUTING chain of the nat table.
iptables -L -t mangle
- show rules from all chains of the mangle table.
An Ip6tables Example
These series of commands sample commands will first list all the rules in the filter table and then display number of IPv6 packets that are being drop by the specific rule.
# ip6tables -L --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 DROP all 2001:db8::2/128 anywhere Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination # ip6tables -L -v # Chain INPUT (policy ACCEPT 40 packets, 3776 bytes) pkts bytes target prot opt in out source destination 27 1944 DROP all any any 2001:db8::2/128 anywhere Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 19 packets, 1584 bytes) pkts bytes target prot opt in out source destination
The first command showed that we only have one rule and that is at the INPUT chain which will drop all the packets coming from the IPv6 address 2001:db8::2/128.
The second command showed that there are already 27 packets coming from the IPv6 address 2001:db8::2/128 that are dropped by our packet filter rule.
Appending rules to a chain
If we already have several Iptables rules in a chain, they will be evaluated from first to last. And if a rule is matched, it will not be evaluated anymore in the next succeeding rules.
Using iptables -A will append a rule at the end of the rules list in the specific chain.
This rule will allow all packets from 192.168.1.2
# iptables -A INPUT -s 192.168.1.2 -j ACCEPT
This rule will only drop all IPv6 TCP packets entering port 22(SSH)
# ip6tables -A INPUT -p tcp –dport 22 -j DROP
You can ping6 the IPv6 address of your firewall, but you are not allowed to connect to via SSH.
Inserting rules to a chain
Using iptables -I, you can insert or add a rule to a specific position in a chain.
This will add a rule in position 1 in your INPUT chain
# iptables -I INPUT 1 -s 192.168.1.2 -j ACCEPT
This command will add a rule in position 5 in your INPUT chain
# ip6tables -I INPUT 5 -p tcp –dport 22 -j DROP
Deleting All Iptables rules
The following commands can be used to delete all rules from a table:
- use this to delete all rules from the filter table.
iptables -F -t nat
- use this to delete all rules from the nat table.
iptables -F -t mangle
- use this to delete all rules from the mangle table.
Deleting a specific rule from a chain
iptables -D INPUT 2
- deletes the 2nd rule from the INPUT chain.
iptables -D PREROUTING 2 -t nat
- deletes the 2nd rule from the PREROUTING chain of the nat table.
ip6tables -D INPUT -s 2001:db8::2 -j ACCEPT
- deletes the first matching IPv6 rule.
Default Chain Policy
By default, all Iptables chain have ACCEPT policy. It means that all packets are implicitly accepted. In order to change the default chain policy from ACCEPT to DROP, use this command:
# iptables -P INPUT DROP
This command will change the policy of the INPUT chain of the filter table to DROP. Please take note of the effect: even if you do not specify rules at the INPUT chain of the filter table, all packets will be implicitly drop. To start accepting packets, add rules that will accept only packets that you want to accept.
Saving and Restoring Rules
iptables-save > /etc/iptables.rules
ip6tables-restore < /etc/ip6tables.rules
Applying Rules after Reboot
There are two ways you can apply the rules during reboot. First method is to modify /etc/network/interfaces and append pre-up iptables-restore < /etc/iptables.rules:
# UNCONFIGURED INTERFACES # remove the above line if you edit this file auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp pre-up iptables-restore < /etc/iptables.rules auto eth1 iface eth1 inet dhcp
Second method is to add a executable shell script inside /etc/network/if-pre-up.d/ directory that will execute the iptables-restore command.
#!/bin/sh iptables-restore < /etc/iptables.rules exit 0
I know this article is far developing a network firewall, but I hope this gives the readers a glimpse on the basics of dropping unwanted traffic coming in and going out of your host machine or your network. I have more interesting network security articles in mind such as IPv6 core protocols, IPv6 security, translating this current articles into PF rules, and more. So please keep on visiting my blog for updates.