Date created: 11/11/11 20:17:47. Last modified: 06/23/21 08:39:59

'iptables' - Notes

IPv4 iptables Notes

Add, drop, insert at position;

iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -D INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -D INPUT 14
iptables -I INPUT 14 -p tcp -m tcp --dport 80 -j ACCEPT

Add comments;

iptables -A INPUT -p tcp -m tcp --dport 80 -m comment --comment "Allow HTTP" -j ACCEPT

Full deny;

iptables -A INPUT -s 1.2.3.4/32 -m comment --comment "SSH Attacker" -j DROP

1:1 NAT'ing for clients in 192.168.1.0/24 subnet to their matching address in the 192.168.2.0/24 network, when heading to the 10.0.0.0/24 network;

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j NETMAP --to 192.168.2.0/24

 

IPv4 Base Config

#!/bin/bash

#IPTables location
IPT="/sbin/iptables"

#Flush the current FW table
$IPT -F

#Allow local loopback access
$IPT -A INPUT -i lo -j ACCEPT

#And connections comming in that are part of existing communications
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Drop invalid connections
$IPT -A INPUT -m state --state INVALID -j DROP

# Block bogons, martians, spoofs
$IPT -A INPUT -s 169.254.0.0/16 -j DROP

#Block Multicast-adresses.
$IPT -A INPUT -s 224.0.0.0/4 -j DROP
$IPT -A INPUT -d 224.0.0.0/4 -j DROP
$IPT -A INPUT -s 240.0.0.0/5 -j DROP
$IPT -A INPUT -d 240.0.0.0/5 -j DROP
$IPT -A INPUT -s 0.0.0.0/8 -j DROP
$IPT -A INPUT -d 0.0.0.0/8 -j DROP
$IPT -A INPUT -d 239.255.255.0/24 -j DROP
$IPT -A INPUT -d 255.255.255.255 -j DROP

# Stop smurf attacks
$IPT -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
$IPT -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
# Drop excessive RST packets to avoid smurf attacks
$IPT -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

#Allow ICMP packets and rate limit them against DoS
#0 = Echo Reply
$IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT
#3 = Destination Unreachable
$IPT -A INPUT -p icmp --icmp-type 3 -j ACCEPT
#8 = Echo Request
$IPT -A INPUT -p icmp --icmp-type 8 -j ACCEPT
#11 = Time Exceeded
$IPT -A INPUT -p icmp --icmp-type 11 -j ACCEPT

$IPT -A INPUT -p icmp -m icmp --icmp-type any -m limit --limit 10/sec -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp --icmp-type any -m limit --limit 10/sec -j ACCEPT

#Allow HTTP/S from anyhere
$IPT -A INPUT -p tcp --dport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT

#Reject incomming TCP packets with invalid flag settings
$IPT -N BADFLAGS
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j BADFLAGS 
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j BADFLAGS 
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK,URG -j BADFLAGS 
$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags ACK,URG URG -j BADFLAGS
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j BADFLAGS 
#Log and drop these packets
$IPT -A BADFLAGS -m limit --limit 15/min -j LOG --log-prefix "Badflags:" 
$IPT -A BADFLAGS -j DROP 

# They might be better under PREROUTING;
# Blocks all ICMP packets whose "fragmentation flag" is not 0. (ICMP should never be fragmented)
$IPT -A PREROUTING -p icmp -m u32 ! --u32 0x4&0x3fff=0x0 -j DROP
# Blocks oversized unfragmented ICMP packets
$IPT -A PREROUTING -p icmp -m length --length 1492:65535 -j DROP
# Invalid packet header combinations
$IPT -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
$IPT -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
$IPT -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
$IPT -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
$IPT -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP


#Block automated SSH attacks 
$IPT -N SSHSCAN
$IPT -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN
$IPT -A SSHSCAN -m recent --set --name SSH
$IPT -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-level info --log-prefix "SSH SCAN blocked: "
$IPT -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

# Set the default policy to drop
$IPT -P INPUT DROP
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD DROP

 

IPv4 NAT Masquerading

Traffic is coming in over a tunnel interface at leaving via physical Interface eth0 towards the public Internet. Enable masquerading on the outbound interface in POSTROUTING to only change the source IP of the packets as they leave the egress interface. The traffic won't be routed out of the egress interface if forwarding is permitted between the ingress and egress interfaces:

iptables -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -o eth0 -i tun0 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

 

IPv4 (D)NAT Masquerading

Forward traffic from 10.116.29.123 that is received on a specific TCP port (80) on a specific ingress interface (adv_kni1.4) to a specific TCP port (80) and a specific destination IP (192.168.2.1) and masquerade as the interface IP that faces 192.168.2.1 on this box (to cover reverse routing requirements):

# Port forwarding must be enabled on the ingress and egress interfaces:
# cat /proc/sys/net/ipv4/conf/adv_kni1.4/forwarding
# cat /proc/sys/net/ipv4/conf/enp2s0/forwarding
iptables -t nat -A PREROUTING -p tcp -i adv_kni1.4 --dport 80 -j DNAT --to-destination 192.168.2.1:80 iptables -A FORWARD -p tcp -d 192.168.2.1 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A POSTROUTING -t nat -p tcp -m tcp -s 10.116.29.123 --dport 80 -j MASQUERADE iptables -t nat -A PREROUTING -p tcp -i adv_kni1.4 --dport 443 -j DNAT --to-destination 192.168.2.1:443 iptables -A FORWARD -p tcp -d 192.168.2.1 --dport 443 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A POSTROUTING -t nat -p tcp -m tcp -s 10.116.29.123 --dport 443 -j MASQUERADE

 

IPv4 Port Redirect

Redirect incoming connectons on a non-standard port to a standard port:

iptables -t nat -A PREROUTING -p tcp --dport 12345 -j REDIRECT --to-port 22

 

 

IPv6 ip6tables Notes

Script to reset ip6tables to a default / allow all state:

#!/bin/bash
IPT6="/sbin/ip6tables"

# Delete all the rules from all chains
$IPT6 -F

# Set the policy on the input and output to ACCEPT and forward to DROP
$IPT6 -P INPUT ACCEPT
$IPT6 -P OUTPUT ACCEPT
$IPT6 -P FORWARD DROP

# Delete any extra chains i.e., mangle and nat, make sure to re-add these in the restore script
$IPT6 -t mangle -F
$IPT6 -t mangle -X
$IPT6 -t nat -F
$IPT6 -t nat -X

# Zero out all counters on all chains
$IPT6 -Z

Script to restore a valid config:

#!/bin/bash
IPT6="/sbin/ip6tables"
IPT6R="/sbin/ip6tables-restore"

# Zero out all counters
$IPT6 -Z

# Create any non-default chains deleted by the reset script
$IPT6 -N mangle
$IPT6 -N nat

$IPT6R < /etc/ip6tables.conf

 

IPv6 Port Redirect

Redirect incoming connectons on a non-standard port to a standard port:

ip6tables -t nat -A PREROUTING -p tcp --dport 12345 -j REDIRECT --to-port 22