This is an old revision of the document!
#!/bin/bash echo "*************" echo "* Running $0" echo "*************" echo echo "It was sad music. But it waved its sadness like a battle flag." echo " It said the universe had done all it could, but you were still alive." echo echo " Discworld" TNX_IDIOT="yes" echo " how iptables work in linux kernel 2.4.x/2.6.x" echo echo ">-[prerouting]-> + >-[forward]-> + >-[postrouting]->" echo " | |" echo " [input] >--->[output]" # path to iptables and iproute2 files IPTB="/sbin/iptables" IP="/sbin/ip" # name of our Internet and intranet interfaces INTRANET="eth1" INTERNET="eth0" # ADSL - INTERNET="ppp0" # what IPs are used in intranet LAN="192.168.6.0/24" # what is our static IP (if we have one) GW_IP="X.X.X.X" # what TCP ports/services we allow (and FORWARD) from Internet # use " " as delimiter TCP_PORTS="22 25 53 80" # what UDP ports/services we allow (and FORWARD) from Internet # use "," as delimiter UDP_PORTS="53" # which ports we forward into our intranet # use "," as delimiter FWD_TCP_PORTS="1214,6346" # set to 1 if we you have intranet WE_HAVE_INTRANET="0" echo "0" > /proc/sys/net/ipv4/ip_forward # first we flush the tables and policy $IPTB -F $IPTB -F INPUT $IPTB -F FORWARD $IPTB -F OUTPUT $IPTB -t nat -F # port redirection (transparent proxy) #$IPTB -t nat -A PREROUTING -i ! $INTERNET -p tcp -s $LAN -d ! $LAN --dport 53 -j REDIRECT #$IPTB -t nat -A PREROUTING -i ! $INTERNET -p udp -s $LAN -d ! $LAN --dport 53 -j REDIRECT #$IPTB -t nat -A PREROUTING -i ! $INTERNET -p tcp -s $LAN -d ! $LAN --dport 25 -j REDIRECT --to-ports 25 # INPUT TABLE $IPTB -P INPUT DROP # statefull firewall $IPTB -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # IPSEC #$IPTB -A INPUT -i $INTERNET -p udp --sport 500 --dport 500 -j ACCEPT #$IPTB -A INPUT -i $INTERNET -p 50 -j ACCEPT #$IPTB -A INPUT -i $INTERNET -p 51 -j ACCEPT # we allow all traffic from $INTRANET and localhost interfaces $IPTB -A INPUT -i $INTRANET -j ACCEPT $IPTB -A INPUT -i lo -j ACCEPT #$IPTB -A INPUT -m state --state INVALID -m limit --limit 1/minute -j LOG --log-prefix "INVALID packet> " #$IPTB -A INPUT -m state --state INVALID -j DROP # $IPTB -A INPUT -i $INTERNET -m pkttype --pkt-type broadcast -j DROP $IPTB -A INPUT -i $INTERNET -m pkttype --pkt-type multicast -j DROP #FIN is set and ACK is not $IPTB -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP $IPTB -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j LOG --log-prefix "FIN> " #PSH is set and ACK is not $IPTB -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP $IPTB -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j LOG --log-prefix "PSH> " #URG is set and ACK is not $IPTB -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP $IPTB -A INPUT -p tcp --tcp-flags ACK,URG URG -j LOG --log-prefix "URG> " # Block portscans: $IPTB -A INPUT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "XMAS scan> " $IPTB -A INPUT -p tcp --tcp-flags ALL ALL -j DROP #no flag is set $IPTB -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "NULL scan> " $IPTB -A INPUT -p tcp --tcp-flags ALL NONE -j DROP $IPTB -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "pscan> " $IPTB -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP #SYN and FIN are both set $IPTB -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "pscan 2> " $IPTB -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #FIN and RST are both set $IPTB -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP $IPTB -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j LOG --log-prefix "fin/rts flag>" $IPTB -A INPUT -f -j LOG --log-prefix "FRAGMENT> " $IPTB -A INPUT -f -j DROP $IPTB -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j LOG --log-prefix "SYNFIN-SCAN>" $IPTB -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP $IPTB -A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j LOG --log-prefix "NMAP-XMAS-SCAN>" $IPTB -A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP $IPTB -A INPUT -p tcp --tcp-flags ALL FIN -j LOG --log-prefix "FIN-SCAN>" $IPTB -A INPUT -p tcp --tcp-flags ALL FIN -j DROP $IPTB -A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j LOG --log-prefix "NMAP-ID>" $IPTB -A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP #SYN and RST are both set $IPTB -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "SYN-RST> " $IPTB -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # Connection limit for SSH connections ( 1 connection per minute) $IPTB -A INPUT -p tcp -m state --syn --state NEW --dport 22 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT $IPTB -A INPUT -p tcp -m state --syn --state NEW --dport 22 -j DROP # what we allow from Internet for i in $TCP_PORTS do $IPTB -A INPUT -p tcp -m state --syn --state NEW --dport $i -j ACCEPT done $IPTB -A INPUT -p udp -m multiport --dport $UDP_PORTS -j ACCEPT # identd requests $IPTB -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset # traceroute $IPTB -A INPUT -p udp -m limit --limit 3/second --sport 32769:65535 --dport 33434:33523 -j ACCEPT # Log and drop ICMP fragments (shouldn't happen at all, but often used for DoS) $IPTB -A INPUT -i $INTERNET --fragment -p icmp -j LOG --log-prefix "Fragmented incoming ICMP> " $IPTB -A INPUT -i $INTERNET --fragment -p icmp -j DROP # thou shall NOT block ALL ICMP, but only allow usefull ICMP types to pass trough $IPTB -A INPUT -p icmp --icmp-type 0 -m limit --limit 30/second -j ACCEPT $IPTB -A INPUT -p icmp --icmp-type 3 -m limit --limit 30/second -j ACCEPT $IPTB -A INPUT -p icmp --icmp-type 4 -m limit --limit 30/second -j ACCEPT $IPTB -A INPUT -p icmp --icmp-type 11 -m limit --limit 30/second -j ACCEPT $IPTB -A INPUT -p icmp --icmp-type 12 -m limit --limit 30/second -j ACCEPT #icmp-traceroute $IPTB -A INPUT -p icmp --icmp-type 30 -m limit --limit 30/second -j ACCEPT # echo-request $IPTB -A INPUT -p icmp --icmp-type 8 -m limit --limit 3/second -j ACCEPT # if the default policy is not DROP then we must use this #$IPTB -A INPUT -p icmp -j DROP # FORWARD TABLE $IPTB -P FORWARD DROP # port forwarding #$IPTB -A FORWARD -p tcp -i $INTERNET -m multiport --dport $FWD_TCP_PORTS -j ACCEPT # START / port forwarding # list forwarder ports in separate command lines #$IPTB -t nat -A PREROUTING -p tcp -i $INTERNET --dport 1214 -j DNAT --to 192.168.1.10 #$IPTB -t nat -A PREROUTING -p tcp -i $INTERNET --dport 6346 -j DNAT --to 192.168.1.10 # END / port forwarding # statefull firewall #$IPTB -A FORWARD -m state --state INVALID -j LOG --log-prefix "INVALID: " $IPTB -A FORWARD -m state --state INVALID -j DROP $IPTB -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTB -A FORWARD -m state --state NEW -i ! $INTERNET -j ACCEPT $IPTB -A FORWARD -m pkttype --pkt-type broadcast -j DROP $IPTB -A FORWARD -m pkttype --pkt-type multicast -j DROP # NAT (IP masquerading) #$IPTB -t nat -A POSTROUTING -o $INTERNET -j MASQUERADE # NAT but to certain IP (if we have multiple Internet IPs) $IPTB -t nat -A POSTROUTING -o $INTERNET -s $LAN -j SNAT --to-source $GW_IP # adsl #$IPTB -I FORWARD --protocol tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu $IPTB -I FORWARD -o $INTERNET -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu # we allow only access to network cards (NIC) that have their MAC addresses listed # in "valid-macs" file #for mac in `cat valid-macs`; do $IPTB -I FORWARD -m mac --mac-source $mac -j fwfilter ; done # list the rules $IPTB -L -v -n echo $WE_HAVE_INTRANET > /proc/sys/net/ipv4/ip_forward