#!/bin/sh
IPT="/sbin/iptables"
IP6="/sbin/ip6tables"
LOGPREFIX="netfilter:"
IFext="eth0"
IPext="192.168.0.251/32"
NEText="192.168.0.0/24"
IFint="eth1"
IPint="192.168.124.1/32"
NETint="192.168.124.0/24"
BCASTint="192.168.124.255/32"
IFwifi="wlan0"
IPwifi="192.168.125.1/32"
NETwifi="192.168.125.0/24"
BCASTwifi="192.168.125.255/32"
BLTIMEOUT=86400
if [ $1 = "stats" ]
then
watch -n 10 $IPT -v -L -n --line-numbers
exit
fi
echo "###########################################################################################################################"
echo "# Forensic Firewall v. 1"
echo "# Details/Updates: http://foxpa.ws/forensic-firewall"
echo "# -------------------------------------------------------------------------------------------------------------------------"
echo "# Configures this host as a NAT gateway for hostile wired and wireless networks to facilitate traffic analysis."
echo "# Ideal for a Raspberry Pi with USB Ethernet dongle or similar configuration."
echo "# Don't forget to edit this script to reflect your environment and disable sections that are inefficient for your use case."
echo "# -------------------------------------------------------------------------------------------------------------------------"
echo "# Syslog prefix: $LOGPREFIX"
echo "# Upstream config: Interface: $IFext, IP: $IPext, Network: $NEText"
echo "# Wired config: Interface: $IFint, IP: $IPint, Network: $NETint, Broadcast: $BCASTint"
echo "# Wireless config: Interface: $IFwifi, IP: $IPwifi, Network: $NETwifi, Broadcast: $BCASTwifi"
echo "###########################################################################################################################"
echo
echo "Kill IPv6..."
$IP6 -F
$IP6 -X
$IP6 -P INPUT DROP
$IP6 -P OUTPUT DROP
$IP6 -P FORWARD DROP
echo "Sterilize iptables..."
$IPT -F -t nat
$IPT -F -t raw
$IPT -F
$IPT -X
echo "Whitelist upstream SSH for testing ruleset changes, comment this..."
$IPT -A INPUT -i $IFext -p tcp --dport 22 -j ACCEPT
echo "Prepare obsessive-compulsive REJECT chains..."
# https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
$IPT -N REJECT_NET
$IPT -A REJECT_NET -j REJECT --reject-with icmp-net-unreachable
$IPT -N REJECT_HOST
$IPT -A REJECT_HOST -j REJECT --reject-with icmp-host-unreachable
$IPT -N REJECT_PROHIBIT
$IPT -A REJECT_PROHIBIT -j REJECT --reject-with icmp-admin-prohibited
$IPT -N REJECT_PROHIBIT_NET
$IPT -A REJECT_PROHIBIT_NET -j REJECT --reject-with icmp-net-prohibited
$IPT -N REJECT_PROHIBIT_HOST
$IPT -A REJECT_PROHIBIT_HOST -j REJECT --reject-with icmp-net-prohibited
$IPT -N REJECT_TCP
$IPT -A REJECT_TCP -p tcp -j REJECT --reject-with tcp-reset
$IPT -N REJECT_UDP
$IPT -A REJECT_UDP -p udp -j REJECT --reject-with icmp-port-unreachable
$IPT -N REJECT_ICMP
$IPT -A REJECT_ICMP -p icmp -j REJECT
$IPT -N REJECT_RFC
$IPT -A REJECT_RFC -p tcp -j REJECT_TCP
$IPT -A REJECT_RFC -p udp -j REJECT_UDP
$IPT -A REJECT_RFC -p icmp -j REJECT_ICMP
$IPT -A REJECT_RFC -j REJECT
echo "Log everything for psad IDS integration (inefficient, disable if not using psad)..."
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -A INPUT -j LOG --log-tcp-options --log-prefix "$LOGPREFIX "
$IPT -A FORWARD -j LOG --log-tcp-options --log-prefix "$LOGPREFIX "
echo "Initialize INPUT, FORWARD, OUTPUT chains..."
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
$IPT -A INPUT -p tcp -m tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A FORWARD -p tcp -m tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i lo -j ACCEPT
echo "Initialize general logging chains..."
# levels: 7 debug 6 info 5 notice 4 warning 3 err 2 crit 1 alert 0 emerg
$IPT -N breakout
$IPT -A breakout -j LOG -m limit --limit 3/minute --log-level warning --log-prefix "$LOGPREFIX Breakout Attempt: "
$IPT -A breakout -j REJECT_NET
$IPT -N spill
$IPT -A spill -j LOG -m limit --limit 3/minute --log-level notice --log-prefix "$LOGPREFIX spill Attempt: "
$IPT -A spill -j DROP
$IPT -N invalid
$IPT -A invalid -j LOG -m limit --limit 3/minute --log-level info --log-prefix "$LOGPREFIX Invalid Attempt: "
$IPT -A invalid -j DROP
$IPT -N attack
$IPT -A attack -j LOG -m limit --limit 3/minute --log-level alert --log-prefix "$LOGPREFIX ACTIVE ATTACK: "
$IPT -A attack -j DROP
$IPT -N brute
$IPT -A brute -j LOG -m limit --limit 3/minute --log-level alert --log-prefix "$LOGPREFIX ACTIVE ATTACK: "
$IPT -A brute -j REJECT_RFC
$IPT -N dos
$IPT -A dos -j LOG -m limit --limit 3/minute --log-level emerg --log-prefix "$LOGPREFIX ACTIVE DoS: "
$IPT -A dos -j DROP
$IPT -N whoops
$IPT -A whoops -j LOG -m limit --limit 3/minute --log-level warning --log-prefix "$LOGPREFIX BLOCKED spill: "
$IPT -A whoops -j DROP
echo "Prepare blacklists..."
$IPT -A INPUT -p tcp -m recent --rcheck --seconds $BLTIMEOUT --name TCP-PORTSCAN -j REJECT_TCP
$IPT -A FORWARD -p udp -m recent --rcheck --seconds $BLTIMEOUT --name UDP-PORTSCAN -j REJECT_UDP
$IPT -A INPUT -p tcp -m recent --rcheck --seconds $BLTIMEOUT --name TCP-FLOOD -j REJECT_TCP
$IPT -A FORWARD -p udp -m recent --rcheck --seconds $BLTIMEOUT --name UDP-FLOOD -j REJECT_UDP
$IPT -A INPUT -p tcp -m recent --name TCP-PORTSCAN --remove
$IPT -A INPUT -p udp -m recent --name UDP-PORTSCAN --remove
$IPT -A INPUT -p tcp -m recent --name TCP-FLOOD --remove
$IPT -A INPUT -p udp -m recent --name UDP-FLOOD --remove
$IPT -N scan
$IPT -A scan -j LOG -m limit --limit 3/minute --log-level alert --log-prefix "$LOGPREFIX SCANNER BLACKLIST: "
$IPT -A scan -p tcp -m tcp -m recent --set --name TCP-PORTSCAN -j REJECT_TCP
$IPT -A scan -p udp -m recent --set --name UDP-PORTSCAN -j REJECT_UDP
$IPT -N flood
$IPT -A flood -j LOG -m limit --limit 3/minute --log-level alert --log-prefix "$LOGPREFIX FLOODER BLACKLIST: "
$IPT -A flood -p tcp -m recent --set --name TCP-FLOOD -j DROP
$IPT -A flood -p udp -m recent --set --name UDP-FLOOD -j DROP
echo "Block broadcasts..."
$IPT -A INPUT -d 255.255.255.255/32 -j DROP
$IPT -A INPUT -d $BCASTint -j DROP
$IPT -A INPUT -d $BCASTwifi -j DROP
echo "Disable multicast..."
$IPT -A INPUT -m pkttype --pkt-type multicast -j spill
$IPT -A FORWARD -m pkttype --pkt-type multicast -j spill
$IPT -A OUTPUT -m pkttype --pkt-type multicast -j spill
$IPT -A INPUT -p igmp -j spill
$IPT -A FORWARD -p igmp -j spill
$IPT -A OUTPUT -p igmp -j spill
$IPT -A INPUT -s 224.0.0.0/3 -j spill
$IPT -A FORWARD -s 224.0.0.0/3 -j spill
$IPT -A OUTPUT -s 224.0.0.0/3 -j spill
echo "Ignore invalid..."
$IPT -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID -j invalid
$IPT -A FORWARD -p tcp -m tcp -m conntrack --ctstate INVALID -j invalid
$IPT -A OUTPUT -p tcp -m tcp -m conntrack --ctstate INVALID -j invalid
echo "Neutralize IP spoofing..."
$IPT -t raw -I PREROUTING -m rpfilter --invert -j DROP
$IPT -A INPUT ! -i lo -s 127.0.0.0/8 -j invalid
$IPT -A INPUT -s 0.0.0.0/8 -j invalid
$IPT -A INPUT -s 10.0.0.0/8 -j invalid
$IPT -A INPUT -s 100.64.0.0/10 -j invalid
$IPT -A INPUT -s 169.254.0.0/16 -j invalid
$IPT -A INPUT -s 172.16.0.0/12 -j invalid
$IPT -A INPUT -s 192.0.0.0/24 -j invalid
$IPT -A INPUT -s 192.0.2.0/24 -j invalid
$IPT -A INPUT -s 198.18.0.0/15 -j invalid
$IPT -A INPUT -s 198.51.100.0/24 -j invalid
$IPT -A INPUT -s 203.0.113.0/24 -j invalid
$IPT -A INPUT -i $IFint -s $NEText -j invalid
$IPT -A INPUT -i $IFwifi -s $NEText -j invalid
$IPT -A FORWARD -s 192.168.0.0/16 -i $IFext -j invalid
echo "Drop floods..."
$IPT -A INPUT -p icmp -m icmp --icmp-type address-mask-request -m comment --comment "SMURF ICMP address-mask-request" -j dos
$IPT -A INPUT -p icmp -m icmp --icmp-type timestamp-request -m comment --comment "SMURF ICMP timestamp-request" -j dos
$IPT -A FORWARD -p icmp -m icmp --icmp-type address-mask-request -m comment --comment "SMURF ICMP address-mask-request" -j dos
$IPT -A FORWARD -p icmp -m icmp --icmp-type timestamp-request -m comment --comment "SMURF ICMP timestamp-request" -j dos
$IPT -A INPUT -f -m comment --comment "Fragmentation Attack" -j dos
$IPT -A FORWARD -f -m comment --comment "Fragmentation Attack" -j dos
echo "Mitigate floods..."
$IPT -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -m comment --comment "Mitigate SMURF" -j ACCEPT
$IPT -A FORWARD -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -m comment --comment "Mitigate SMURF" -j ACCEPT
$IPT -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 1/second -m comment --comment "Mitigate Ping of Death/SMURF" -j ACCEPT
$IPT -A FORWARD -p icmp -m icmp --icmp-type echo-request -m limit --limit 1/second -m comment --comment "Mitigate Ping of Death/SMURF" -j ACCEPT
$IPT -A INPUT -m limit --limit 20/second --limit-burst 40 -m comment --comment "Limit UDP rate" -j flood
$IPT -A FORWARD -m limit --limit 20/second --limit-burst 40 -m comment --comment "Limit UDP rate" -j flood
$IPT -N SYN_FLOOD
$IPT -A SYN_FLOOD -m limit --limit 1/second --limit-burst 4 -j LOG --log-prefix "$LOGPREFIX SYN Flood"
$IPT -A SYN_FLOOD -j flood
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -m comment --comment "Fork possible SYN flood" -j SYN_FLOOD
$IPT -A FORWARD -p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -m comment --comment "Fork possible SYN flood" -j SYN_FLOOD
echo "Detect scans (inefficient, useful for syslog monitoring - should probably be disabled if using psad)..."
# Requires psd match extension
#$IPT -A INPUT -m psd -m limit --limit 5/minute -m comment --comment "iptables portscan match module" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ACK,SYN,FIN,RST,PSH,URG NONE -m limit --limit 10/minute -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ACK,SYN,FIN,RST,PSH,URG NONE -m limit --limit 10/minute -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN,ACK,FIN,RST RST -m comment --comment "Furtive Scanner" -m limit --limit 1/second -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags SYN,ACK,FIN,RST RST -m comment --comment "Furtive Scanner" -m limit --limit 1/second -j scan
$IPT -A INPUT -p tcp -m multiport --dports 10,11 --tcp-flags ALL SYN -m limit --limit 3/minute --limit-burst 5 -m comment --comment "Probable SYN Scan" -j scan
$IPT -A FORWARD -p tcp -m multiport --dports 10,11 --tcp-flags ALL SYN -m limit --limit 3/minute --limit-burst 5 -m comment --comment "Probable SYN Scan" -j scan
$IPT -A INPUT -p tcp -m tcp --dport telnet -m comment --comment "Telnet (IoT) Probe Input Trigger" -j scan
$IPT -A FORWARD -p tcp -m tcp --dport telnet -m comment --comment "Telnet (IoT) Probe Forward Trigger" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ACK,FIN FIN -m comment --comment "FIN" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ACK,PSH PSH -m comment --comment "PSH" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ACK,URG URG -m comment --comment "URG" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL ALL -m comment --comment "XMAS scan" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL NONE -m comment --comment "NULL scan" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m comment --comment "pscan" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -m comment --comment "pscan 2" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -m comment --comment "pscan 2" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL SYN,FIN -m comment --comment "SYNFIN-SCAN" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL URG,PSH,FIN -m comment --comment "NMAP-XMAS-SCAN" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL FIN -m comment --comment "FIN-SCAN" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags ALL URG,PSH,SYN,FIN -m comment --comment "NMAP-ID" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -m comment --comment "SYN-RST" -j scan
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -m comment --comment "ACK Scan" -j scan
$IPT -A INPUT -p udp -m length --length 0:28 -m comment --comment "UDP Scan (high chance of false positive)" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ACK,FIN FIN -m comment --comment "FIN" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ACK,PSH PSH -m comment --comment "PSH" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ACK,URG URG -m comment --comment "URG" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL ALL -m comment --comment "XMAS scan" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL NONE -m comment --comment "NULL scan" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m comment --comment "pscan" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -m comment --comment "pscan 2" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -m comment --comment "pscan 2" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL SYN,FIN -m comment --comment "SYNFIN-SCAN" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL URG,PSH,FIN -m comment --comment "NMAP-XMAS-SCAN" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL FIN -m comment --comment "FIN-SCAN" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags ALL URG,PSH,SYN,FIN -m comment --comment "NMAP-ID" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -m comment --comment "SYN-RST" -j scan
$IPT -A FORWARD -p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -m comment --comment "ACK Scan" -j scan
$IPT -A FORWARD -p udp -m length --length 0:28 -m comment --comment "UDP Scan (high chance of false positive)" -j scan
# Kill any surviving invalid new TCP connections that were not initiated with a SYN packet.
# Use -I in production to skip wasteful scan detection chains above.
$IPT -A INPUT -p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -m comment --comment "Drop TCP connection not started with SYN" -j DROP
echo "Configure services available to the upstream interface..."
$IPT -A INPUT -i $IFext -p tcp --dport 22 -m comment --comment "Accept incoming SSH connections" -j ACCEPT
$IPT -A INPUT -i $IFext -p tcp --dport 80 -m comment --comment "Accept incoming HTTP connections" -j ACCEPT
$IPT -A INPUT -i $IFext -p tcp --dport 443 -m comment --comment "Accept incoming HTTPS conenctions" -j ACCEPT
$IPT -A INPUT -i $IFext -p udp --sport 53 -m comment --comment "Accept DNS responses" -j ACCEPT
$IPT -A INPUT -i $IFext -p udp --sport 123 -m comment --comment "Accept NTP responses" -j ACCEPT
$IPT -A INPUT -i $IFext -p icmp -m comment --comment "Accept ICMP Traffic" -j ACCEPT
echo "Protect the upstream subnet from the analysis interfaces..."
$IPT -A FORWARD -d $NEText -i $IFint -j breakout
$IPT -A FORWARD -d $NEText -i $IFwifi -j breakout
echo "Protect this host's upstream IP from the analysis interfaces..."
$IPT -A INPUT -d $IPext -i $IFint -j breakout
$IPT -A INPUT -d $IPext -i $IFwifi -j breakout
echo "Construct the NAT..."
#$IPT -A FORWARD -o $IFint -i $IFext -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
#$IPT -A FORWARD -o $IFint -i $IFwifi -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -o $IFext -i $IFint -s $NETint -j ACCEPT
$IPT -A FORWARD -o $IFext -i $IFwifi -s $NETwifi -j ACCEPT
$IPT -t nat -A POSTROUTING -o $IFext -j MASQUERADE
echo "Configure gateway services for the analysis subnets..."
$IPT -A INPUT -p tcp -m tcp -d $IPint --dport 53 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -d $IPwifi --dport 53 -j ACCEPT
$IPT -A INPUT -p udp -m udp -d $IPint --dport 53 -j ACCEPT
$IPT -A INPUT -p udp -m udp -d $IPwifi --dport 53 -j ACCEPT
$IPT -I INPUT -i $IFint -p udp -d 255.255.255.255/32 --dport 67:68 --sport 67:68 -j ACCEPT
$IPT -I INPUT -i $IFwifi -p udp -d 255.255.255.255/32 --dport 67:68 --sport 67:68 -j ACCEPT
$IPT -A INPUT -d $IPint -j REJECT_RFC
$IPT -A INPUT -d $IPwifi -j REJECT_RFC
echo "Preemptive/redundant protection from spills into analysis interfaces from this host (i.e: Chromium SSDP, avahi...)"
$IPT -A OUTPUT -o $IFint -p udp -m udp --dport 1900 -j whoops
$IPT -A OUTPUT -o $IFint -p udp -m udp --sport 1900 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --dport 1900 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --sport 1900 -j whoops
$IPT -A OUTPUT -o $IFint -p udp -m udp --dport 5353 -j whoops
$IPT -A OUTPUT -o $IFint -p udp -m udp --sport 5353 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --dport 5353 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --sport 5353 -j whoops
$IPT -A OUTPUT -o $IFint -p udp -m udp --dport 5355 -j whoops
$IPT -A OUTPUT -o $IFint -p udp -m udp --sport 5355 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --dport 5355 -j whoops
$IPT -A OUTPUT -o $IFwifi -p udp -m udp --sport 5355 -j whoops
$IPT -A OUTPUT -o $IFint -p tcp -m tcp --dport 5355 -j whoops
$IPT -A OUTPUT -o $IFint -p tcp -m tcp --sport 5355 -j whoops
$IPT -A OUTPUT -o $IFwifi -p tcp -m tcp --dport 5355 -j whoops
$IPT -A OUTPUT -o $IFwifi -p tcp -m tcp --sport 5355 -j whoops
echo "Finalize ruleset..."
$IPT -A INPUT -j REJECT_RFC
$IPT -A FORWARD -j REJECT_HOST