Comprehensive Guide to Linux Iptables
November 20, 2024
Linux SecurityServerHardeningIptables
🛡️ Comprehensive Guide to Linux Iptables
🔐 Linux Iptables
Netfilter
- Netfilter is a software firewall, a packet filtering framework inside the Linux Kernel.
- It enables packet filtering, NAT, PAT, Port Forwarding and packet mangling.
- Netfilter framework is controlled by the iptables command.
- Iptables is a tool that belongs to the user space used to configure netfilter.
- Netfilter and Iptables are often combined into a single expression netfilter/iptables.
- Every Linux distribution uses netfilter/iptables, there is nothing extra that should be installed.
- Only root user can use or configure the netfilter framework.
Netfilter Chain
- Every packet is inspected by firewall rules. Firewall rules determine what traffic your firewall allows and what is blocked.
- The iptables firewall uses tables to organize its rules.
- Within each iptables table, rules are further organized within separate CHAINS. Rules are placed within a specific chain of a specific table.
- Within a chain, a packet starts at the top of the chain and is matched rule by rule.
- When a match is found the target is executed.
- A target is the action that is triggered when a packet meets the matching criteria of a rule. If the target is terminating no other rule will evaluate the packet.
INPUT
- used for filtering incoming packets. Our host is the packet destination.
OUTPUT
- used for filtering outgoing packets. Our host is the source of the packet
FORWARD
- used for filtering routed packets. Our host is router.
PREROUTING
- used for DNAT / Port Forwarding
POSTROUTING
- used for SNAT (MASQUERADE)
🧱 Netfilter Tables
filter
- filter is the default table for iptables
- iptables filter table has the following built in chains: INPUT, OUTPUT and FORWARD
nat
- nat table is specialized for SNAT and DNAT (Port Forwarding)
- iptables NAT table has the following built in chains: PREROUTING, POSTROUTING and OUTPUT (for locally generated packets)
mangle
- iptables mangle table is specialized for packet alteration
- mangle table has the following built in chains: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
raw
- The raw table is only used to set a mark on packets that should not be handled by the connection tracking system. This is done by using the NOTRACK target on the packet.
- raw table has the following built in chains: PREROUTING and OUTPUT.
- Incoming traffic is filtered on the INPUT CHAIN of the filter table.
- Outgoing traffic is filtered on the OUTPUT CHAIN of the filter table.
- Routed traffic is filtered on the FORWARD CHAIN of the filter table.
- SNAT/MASQUERADE is done on the POSTROUTING CHAIN of the nat table.
- DNAT/PortForwarding is done on the PREROUTING CHAIN of the nat table.
- To modify values from the packet headers we add rules to the mangle table.
- To skip connection tracking we add rules with NOTRACK target to the raw table
🛡️ Iptables Commands
- iptable -t table_name -COMMAND -CHAIN_NAME machtes -j TARGET
- iptables -t filter -A OUTPUT -p tcp --dport 443 -d www.test.com -j DROP
| Table | Command | CHAIN | matches | Target/Jump |
|---|---|---|---|---|
| filter | -A (Append) | INPUT | -s source_ip | ACCEPT |
| nat | -I (Insert) | OUTPUT | -d dest_ip | DROP |
| mangle | -D (Delete) | FORWARD | -p protocol | REJECT |
| raw | -R (Replace) | PREROUTING | --sport source_p | LOG |
| -F (Flush) | POSTROUTING | --dport dest_p | SNAT | |
| -Z (Zero) | USER_DEFINED | -i incoming_int | DNAT | |
| -S (Show) | -o outgoint_int | MASQUERADE | ||
| -N | -m mac | LIMIT | ||
| -X | -m time | RETURN | ||
| -L (List) | -m quota | TEE | ||
| -P | -m limit | TOS | ||
| -m recent | TTL |
- -A : Append the rule to the end of the selected chain.
- -I : Insert one or more rules in the selected chain on a specific position, by default on top (position 1).
- -L : List all rules in the selected chain. If no chain is selected, all chains are listed.
- -F : Flush the selected chain (all the chains in the table if none is given).
- -Z : Zero the packet and byte counters in all chains, or only the given chain.
- -N : Create a new user defined chain by the given name.
- -X : Delete the user defined chain specified.
- -P : Set the policy for the built in chain (INPUT, OUTPUT or FORWARD).
- -D : Delete one or more rules from the selected chain.
- -R : Replace a rule in the selected chain.
- -S : Print all rules in the selected chain.
- -v : verbose output, prints interface name, packets and bytes counters.
- -n : avoid long reverse DNS lookups. Prints IP address and port numbers instead of domain and service names.
Iptables Flags
1iptables -F
2
3# -A -> appends a rule at the end of the CHAIN
4iptables -A OUTPUT -p tcp --dport 443 -j DROP
5
6# -I -> inserts a rule on top (1st position) of the CHAIN
7iptables -I OUTPUT -p tcp --dport 443 -d www.linux.com -j ACCEPT
8
9# -F -> flushes the CHAIN
10iptables -t filter -F OUTPUT
11
12# -Z -> zeroises the packet and byte counters
13iptables -t filter -Z
14
15# -D -> deletes a rule
16iptables -D OUTPUT 2
17
18# -P -> sets the default POLICY
19iptables -P INPUT ACCEPT
20
21# -N -> creates a user-defined CHAIN
22iptables -N TCP_TRAFFIC
23
24# -X -> delete a user-defined CHAIN
25iptables -X TCP_TRAFFICListing Firewall
1# listing the filter table of all chains (INPUT, OUTPUT and FORWARD)
2iptables -t filter -L
3
4# listing the filter table (it's default) of all chains, verbose (v) and in numeric format (n)
5iptables -vnL
6
7# listing just a chain
8iptables -vnL INPUT
9
10# listing another table, not filter
11ptables -t nat -vnL
12
13# listing just a CHAIN
14iptables -t nat -vnL POSTROUTINGDefault Policy
- Policy specifies what happens to packets that are not matched against any rule.
- By default Policy is set to accept all traffic.
- Policy can be changed only for INPUT, OUTPUT and FORWARD chains.
- Policy can be changed using -P option.
Setting Policy
1# By default POLICY is ACCEPT on all CHAINS
2
3# !!! If there is no rule that accepts packets and the policy is set to drop, all traffic will be dropped.
4
5# Setting the DROP Policy on FORWARD chain
6iptables -P FORWARD DROP
7
8# Setting the ACCEPT Policy on OUTPUT chain
9iptables -P OUTPUT ACCEPT
10
11# Setting the DROP Policy on INPUT chain
12iptables -P INPUT DROPDeleting Firewall
- Setting the ACCEPT POLICY on all CHAINS.
- Flushing all tables from all chains.
- If any, delete any user defined chains, after flushing rules from those chains.
Deleting Firewall
1#1. Set the ACCEPT POLICY an all CHAINS
2iptables -P INPUT ACCEPT
3iptables -P OUTPUT ACCEPT
4iptables -P FORWARD ACCEPT
5
6#2. Flush all tables from all CHAINS
7iptables -t filter -F
8iptables -t nat -F
9iptables -t mangle -F
10
11#3. Delete user defined CHAINS (if there is any)
12iptables -X🧩 Iptables matches
Filter by IP Address
1# Match by Source IP or Network Address
2iptables -A INPUT -s 100.0.0.0/16 -j DROP
3
4# Match by Destination IP or Network Address
5iptables -A FORWARD -d 80.0.0.1 -j DROP
6iptables -A OUTPUT -d www.ubuntu.com -j DROPFilter By IP Range and address Type
1# Match by IP Range
2iptables -A INPUT -m iprange --src-range 10.0.0.10-10.0.0.29 -p tcp --dport 25 -j DROP
3
4# Match by Address Type
5iptables -A OUTPUT -m addrtype --dst-type MULTICAST -j DROPFilter By Port
1# Match by a single port
2iptables -A INPUT -p tcp --dport 22 -j DROP
3
4# Match by multiple ports
5iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -j ACCEPTFilter By Protocol
1# dropping incoming GRE traffic
2iptables -A INPUT -p gre -j DROP
3
4# allowing outgoing ICMP traffic
5iptables -A OUTPUT -p icmp -j DROPFilter By Interface
1# Match by incoming interface. Available for: INPUT, FORWARD and PREROUTING chains.
2iptables -A INPUT -i wlan0 -j ACCEPT
3
4# Match by outgoing interface. Available for: FORWARD, OUTPUT and POSTROUTING chains.
5iptables -A OUTPUT -o enp8s0 ACCEPTFilter By MAC address
1iptables -A INPUT -i wlan0 -m mac --mac-source 08:00:27:55:6f:20 -j DROPFilter By datetime
1# !!!!! TIME is UTC and not system time
2
3# accepting incoming tcp port 22 (ssh) packets daily ONLY between 8:00-18:00
4iptables -A INPUT -p tcp --dport 22 -m time --timestart 8:00 --timestop 18:00 -j ACCEPTFilter by Conlimit
1iptables -A INPUT -p tcp --dport 25 --syn -m connlimit --connlimit-above 5 -j REJECT --reject-with tcp-rstFilter By Limit
1iptables -A FORWARD -m limit --limit 1/minute -p udp --dport 53 -j LOG
2
3iptables -A INPUT -p tcp --syn -m limit --limit 2/s --limit-burst 7 -j ACCEPTFilter By Quota
1iptables -A OUTPUT -d 80.0.0.1 -p tcp --sport 80 -m quota --quota 1000000000 -j ACCEPT
2
3iptables -A OUTPUT -d 80.0.0.1 -p tcp --sport 80 -j DROPNegating Matches
1# dropping all incoming ssh traffic accepting packets from 100.0.0.1 (management station)
2iptables -A INPUT -p tcp --dport 22 ! -s 100.0.0.1 -j DROP
3
4# dropping all outgoing https traffic excepting to www.linux.com
5iptables -A OUTPUT -p tcp --dport 443 ! -d www.linux.com -j DROP
6
7# dropping all communication excepting that with the default gateway (mac is b4:6d:83:77:85:f4)
8iptables -A INPUT -m mac ! --mac-source b4:6d:83:77:85:f4 -j DROP
9
10iptables -P INPUT ACCEPTFilter By match TCP Flags
1# dropping all incoming tcp packets that have syn set
2iptables -A INPUT -p tcp --syn -j DROP
3
4# logging outgoing traffic that has syn and ack set
5iptables -A OUTPUT -p tcp --tcp-flags syn,ack,rst,fin syn,ack -j🔥 Stateful Firewall (Connection Tracking)
- Connection tracking = ability to maintain state information about connections.
- Stateful firewalls are more secure than stateless firewalls.
- Stateful firewalls decide to accept or to drop packets based on the relations these packets are with other packets.
- Netfilter is a stateful firewall.
Packet states
- NEW - the first packet from a connection.
- ESTABLISHED - packets that are part of an existing connection.
- RELATED - packets that are requesting a new connection and are already part of an existing connection (Ex: FTP).
- INVALID - packets that are not part of any existing connection.
- UNTRACKED - packets marked within the raw table with the NOTRACK target.
11. ###*** FIREWALL FOR A DESKTOP OPERATING SYSTEM ***###
2
3# flush filter table from all chains
4iptables -F
5
6# allow loopback interface traffic
7iptables -A INPUT -i lo -j ACCEPT
8iptables -A OUTPUT -o lo -j ACCEPT
9
10# drop invalid packets on INPUT and OUTPUT CHAINS
11iptables -A INPUT -m state --state INVALID -j DROP
12iptables -A OUTPUT -m state --state INVALID -j DROP
13
14# optional, uncomment the line if you want to allow incoming connections from our LAN
1517. #iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT
16
17# optional, uncomment the line if you want to allow incoming ssh connection from a specific ip address
18iptables -A INPUT -p tcp --dport 22 --syn -s 80.0.0.1 -j ACCEPT
19
20# allow only ESTABLISHED and RELATED packets on INPUT
21iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
22
23# allow also NEW packets on OUTPUT (packets that initialize connections)
24iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
25
26# set policy to DROP on INPUT and OUTPUT CHAINS
2730. iptables -P INPUT DROP
2831. iptables -P OUTPUT DROPThe Recent Match
- It creates a dynamic database of blacklisted source IP addresses.
- The list with blacklisted IP addresses is found in: /proc/net/xt_recent/LIST_NAME
Match Options
- --name: creates a list in which the source IP address will be added and checked.
- --set: adds the source IP address to the list.
- --update: checks if the source IP address is in the list and updates the "last seen time".
- --rcheck: checks if the source IP address is in the list and DOESN’T update the "last seen time".
- --seconds: used with --update or --rcheck. Matches the packet only if the source IP address is in the list and the last seen time is valid.
1iptables -A FORWARD -m recent --name badguys --update --seconds 60 -j DROP
2
3iptables -A FORWARD -p tcp -i eth0 --dport 8080 -m recent --name badguys --set -j DROP🧱 Iptables Targets
TARGET
- A TARGET is the action that is triggered when a packet meets the matching criteria of a rule.
- A TARGET can be:
- Terminating (Example: ACCEPT, DROP)
- Non terminating (Example: LOG, TEE)
ACCEPT
- ACCEPT is a terminating target.
1iptables -A INPUT -p tcp --dport 25 -j ACCEPTDROP
- DROP is a terminating target.
- DROP denies the packet and doesn’t send any packet back to the source.
1iptables -I OUTPUT -p udp --dport 53 ! -d 8.8.8.8 -j DROPREJECT
- REJECT is a terminating target.
- Like DROP it denies the packet but also sends back a reply packet to the source.
- By default it sends back an ICMP Port Unreachable packet.
- It’s possible to change the response packet using --reject-with option.
- Sometimes it’s more efficient to REJECT than DROPPING the packet.
1iptables -I FORWARD -p udp --dport 69 -j REJECT --reject-with icmp-port-unreachableLOG
- LOG is a non terminating target.
- It logs detailed information about packet headers.
- Logs can be read with dmesg or from syslogd daemon.
- LOG is used instead of DROP in the debugging phase.
- ULOG has MySql support (extensive logging).
Options
- --log-prefix
- --log-level
1iptables -A INPUT -p tcp --dport 22 --syn -j LOG --log-prefix="incoming ssh:" --log-level infoTEE
- The TEE target will clone a packet and redirect this clone to another machine on the local subnet.
- It is used for traffic mirroring.
1iptables -A FORWARD -i eth0 -o eth1 -p tcp -d 80.0.0.1 -j TEE --gateway 10.0.0.10REDIRECT
- Used to redirect packets from one port to another on the same machine.
- The REDIRECT target is extremely good to use for transparent proxying, where the LAN hosts do not know about the proxy at all.
- REDIRECT target is only valid within the PREROUTING and OUTPUT chains of the nat table.
1iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080🧪 NAT and Port Forwarding
- NAT involves rewriting the source and/or destination addresses of IP packets as they pass through a router or firewall.
- SNAT replaces the private IP address from the packet with the public IP address of the router external interface.
- Netfilter framework enables a Linux machine with an appropriate number of network cards (interfaces) to become a router capable of NAT.
- SNAT uses the nat table and the POSTROUTING chain.
- MASQUERADE is a special case of SNAT used when the public IP address of the NAT Router is dynamic. It will automatically use the IP address of the outgoing network interface for network translation.
- When uses SNAT or MASQUERADE the netfilter also performs port address translation (PAT) on the packet.
Enable the routing process
1echo "1" > /proc/sys/net/ipv4/ip_forwardAdd an iptables rule to nat table and POSTROUTING chain that matches packets that should be NATed, specify the external interface using -o option and use -j SNAT --to-source public_ip_address or -j MASQUERADE targets
1iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j SNAT --to-source 80.0.0.1⛓️ User defined CHAINS
- By default, the iptables filter table consists of three built in chains: INPUT, OUTPUT and FORWARD.
- You can add as many custom (user defined) chains as you like to help simplify managing large rule sets.
- User defined chains are useful in optimizing the ruleset. They allow the rules to be organized in categories.
- From a builtin chain using -j CUSTOM-CHAIN, you can jump into a custom chain.
- From a built in chain using -j CUSTOM-CHAIN, you can jump into a custom chain. After the user defined chain is traversed, control returns to the calling built in chain, and matching continues from the next rule in the calling chain, unless the user defined chain matched and took a terminating action on the packet.
- The RETURN target in a rule of a custom chain makes processing resume back in the chain that called the custom chain. -j RETURN can also be used inside a built in chain. In this case no other rule will be inspected and packet executes the default POLICY
- If you want to stop using your custom chain temporarily, you can simply delete the jump from the INPUT chain (rather than flushing or deleting the entire custom chain)
Options
- -N NEW_CHAIN creates a new user defined chain
- -L NEW_CHAIN lists the content of the chain
- -X NEW_CHAIN deletes the custom chain (it must be emptied before using -F)
- -F NEW-CHAIN flushes all rules from the chain
1# creating a user-defined chain
2iptables -N TCP_TRAFFIC
3
4# add rules to the chain
5iptables -A TCP_TRAFFIC -p tcp -j ACCEPT
6
7# jump to the chain from the input chain
8iptables -A INPUT -p tcp -j TCP_TRAFFIC
9
10# flush all rules in the chain
11iptables -F TCP_TRAFFIC
12
13# delete the chain
14iptables -X TCP_TRAFFIC