Skip to content

Instantly share code, notes, and snippets.

@amekusa
Last active June 29, 2022 03:51
Show Gist options
  • Select an option

  • Save amekusa/bb1a35555e053c732196faee8fd82662 to your computer and use it in GitHub Desktop.

Select an option

Save amekusa/bb1a35555e053c732196faee8fd82662 to your computer and use it in GitHub Desktop.
Learn how iptables actually works by testing by yourself
#!/bin/bash
# NOTE:
#
# To run (DO NOT RUN on your production server):
# sudo ./iptables-test.sh
#
# To test:
# ping -c 1 <ip address>
#
# To see the log:
# journalctl -fk --grep="IN=.*OUT=.*"
#
systemctl stop iptables.service
systemctl start iptables.service
iptables -t raw -F
iptables -t mangle -F
iptables -t filter -F
test="$1"
in="-p icmp"
out=""
# ---- logging --------
_base-log() {
# inbound
iptables -t raw -A PREROUTING $in -j LOG --log-prefix " "
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "-> RAW ::::: PREROUT "
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "-> MANGLE :: PREROUT "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate NEW -j LOG --log-prefix " [STATE: NEW] "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate UNTRACKED -j LOG --log-prefix " [STATE: UNTRACKED] "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate INVALID -j LOG --log-prefix " [STATE: INVALID] "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate ESTABLISHED -j LOG --log-prefix " [STATE: ESTABLISHED] "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate RELATED -j LOG --log-prefix " [STATE: RELATED] "
iptables -t mangle -A INPUT $in -j LOG --log-prefix "-> MANGLE :: INPUT "
iptables -t filter -A INPUT $in -j LOG --log-prefix "-> FILTER :: INPUT "
# outbound
[ -z "$out" ] && out="$in"
iptables -t raw -A OUTPUT $out -j LOG --log-prefix " "
iptables -t raw -A OUTPUT $out -j LOG --log-prefix "<- RAW ::::: OUTPUT "
iptables -t mangle -A OUTPUT $out -j LOG --log-prefix "<- MANGLE :: OUTPUT "
iptables -t filter -A OUTPUT $out -j LOG --log-prefix "<- FILTER :: OUTPUT "
iptables -t mangle -A POSTROUTING $out -j LOG --log-prefix "<- MANGLE :: POSTROUT "
}
# ---- tests --------
case "$test" in
0)
_base-log
;;
1)
_base-log
iptables -t raw -A PREROUTING $in -j ACCEPT
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "1. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "2. THIS SHOULD APPEAR "
;;
2)
_base-log
iptables -t raw -A PREROUTING $in -j RETURN
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "1. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "2. THIS SHOULD APPEAR "
;;
3)
_base-log
iptables -t filter -A INPUT $in -j REJECT
iptables -t filter -A INPUT $in -j LOG --log-prefix "1. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A POSTROUTING -p icmp -j LOG --log-prefix "2. THIS SHOULD APPEAR "
;;
4)
_base-log
iptables -t raw -A PREROUTING $in -j DROP
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "1. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "2. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A POSTROUTING -p icmp -j LOG --log-prefix "3. XXX THIS SHOULD NOT APPEAR XXX "
;;
5)
_base-log
iptables -t mangle -A PREROUTING $in -j MARK --set-mark 1
iptables -t mangle -A PREROUTING $in -m mark --mark 0 -j DROP
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "1. THIS SHOULD APPEAR "
iptables -t mangle -A INPUT $in -j LOG --log-prefix "2. THIS SHOULD APPEAR "
iptables -t filter -A INPUT $in -j LOG --log-prefix "3. THIS SHOULD APPEAR "
;;
6)
_base-log
iptables -t mangle -A PREROUTING $in -j MARK --set-mark 1
iptables -t mangle -A PREROUTING $in -m mark --mark 1 -j DROP
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "1. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t mangle -A INPUT $in -j LOG --log-prefix "2. XXX THIS SHOULD NOT APPEAR XXX "
iptables -t filter -A INPUT $in -j LOG --log-prefix "3. XXX THIS SHOULD NOT APPEAR XXX "
;;
7)
_base-log
iptables -t raw -A PREROUTING $in -j NOTRACK
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "1. THIS SHOULD APPEAR "
iptables -t mangle -A PREROUTING $in -m conntrack --ctstate UNTRACKED -j LOG --log-prefix "2. THIS SHOULD APPEAR "
;;
8)
_base-log
iptables -t raw -N SUBCHAIN
iptables -t raw -A PREROUTING $in -j SUBCHAIN
iptables -t raw -A SUBCHAIN -j LOG --log-prefix "1. THIS SHOULD APPEAR "
iptables -t raw -A SUBCHAIN -j NOTRACK
iptables -t raw -A SUBCHAIN -j ACCEPT
iptables -t raw -A SUBCHAIN $in -j LOG --log-prefix "2. XXX THIS SHOULD NOT APPEAR "
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "3. XXX THIS SHOULD NOT APPEAR "
;;
9)
_base-log
iptables -t raw -N SUBCHAIN
iptables -t raw -A PREROUTING $in -j SUBCHAIN
iptables -t raw -A SUBCHAIN -j LOG --log-prefix "1. THIS SHOULD APPEAR "
iptables -t raw -A SUBCHAIN -j RETURN
iptables -t raw -A SUBCHAIN $in -j LOG --log-prefix "2. XXX THIS SHOULD NOT APPEAR "
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "3. THIS SHOULD APPEAR "
;;
10)
_base-log
iptables -t raw -N SUBCHAIN
iptables -t raw -A PREROUTING $in -j SUBCHAIN
iptables -t raw -A SUBCHAIN -j LOG --log-prefix "1. THIS SHOULD APPEAR "
iptables -t raw -A SUBCHAIN -j DROP
iptables -t raw -A SUBCHAIN $in -j LOG --log-prefix "2. XXX THIS SHOULD NOT APPEAR "
iptables -t raw -A PREROUTING $in -j LOG --log-prefix "3. XXX THIS SHOULD NOT APPEAR "
iptables -t mangle -A PREROUTING $in -j LOG --log-prefix "4. XXX THIS SHOULD NOT APPEAR "
;;
11) # synproxy test
# NOTE: Test with 'telnet <ip> 80'
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
in="-p tcp ! --dport 22 ! --sport 22"; _base-log
iptables -t raw -A PREROUTING $in --syn -j LOG --log-prefix " [SYN] "
iptables -t raw -A PREROUTING $in --syn -j NOTRACK
filter="-t filter -A INPUT"
iptables $filter $in -m conntrack --ctstate INVALID,UNTRACKED -j LOG --log-prefix " [SYNPROXY] "
iptables $filter $in -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables $filter $in -m conntrack --ctstate INVALID -j LOG --log-prefix " [DROPPED BY SYNPROXY] "
iptables $filter $in -m conntrack --ctstate INVALID -j DROP
;;
12) # synproxy test 2
# NOTE: Test with 'telnet <ip> 80'
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
in="-p tcp ! --dport 22 ! --sport 22"; _base-log
iptables -t raw -A PREROUTING $in -i lo -j LOG --log-prefix " [TO: LOCAL (RAW)] "
iptables -t raw -A PREROUTING $in -i lo -j NOTRACK
iptables -t raw -A PREROUTING $in -i lo -j ACCEPT
iptables -t raw -A PREROUTING $in --syn -j LOG --log-prefix " [SYN] "
iptables -t raw -A PREROUTING $in --syn -j NOTRACK
filter="-t filter -A INPUT"
iptables $filter $in -i lo -j LOG --log-prefix " [TO: LOCAL] "
iptables $filter $in -i lo -j ACCEPT
iptables $filter $in -m conntrack --ctstate INVALID,UNTRACKED -j LOG --log-prefix " [SYNPROXY] "
iptables $filter $in -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables $filter $in -m conntrack --ctstate INVALID -j LOG --log-prefix " [DROPPED BY SYNPROXY] "
iptables $filter $in -m conntrack --ctstate INVALID -j DROP
;;
*)
echo "NO SUCH TEST"
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment