#!/bin/sh ############################################################### # # modular packet filter using iptables # # (c) 2004 Markus Schade # # License: GPLv2 or later # ############################################################### IPT="/sbin/iptables" IPTR="/sbin/iptables-restore" IPTS="/sbin/iptables-save" DESC="IPTables Netfilter" INNER="eth2" DEAD="eth1" OUTER="eth0" OUTERIP="134.109.96.136" INNERIP="192.168.1.1" INNERSUB="192.168.1.0/24" # define more Variables test -x $IPT || exit 0 set -e ################### Functions ###################### # define Functions function setup_inputfw() { $IPT -P INPUT DROP $IPT -N icmp_packets $IPT -N CHECK_FLAGS $IPT -N Server setup_inputchains # Eigentliche INPUT Chain - Von hier aus wird in die Subchains verzweigt # ICMP fangen wir gleich mal zu ab $IPT -A INPUT -p icmp -j icmp_packets # Conntrack $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -m state --state NEW -j Server $IPT -A INPUT -m limit --limit 10/m -m state --state INVALID -j LOG --log-prefix "INVALID INPUT DROP: " $IPT -A INPUT -m state --state INVALID -j DROP # Der Rest wird von der Policy erschlagen (was auch immer da kommen mag) $IPT -A INPUT -m limit --limit 10/m -j LOG --log-prefix "INPUT DROP POLICY: " } function setup_inputchains() { # Subchains aufbauen: ######################################################## # icmp_packets chain ######################################################## # icmp protection (really? *g*) # Chain loeschen echo -n "icmp_packets " $IPT -F icmp_packets # nur icmp echo-request sollte new sein, der rest established $IPT -A icmp_packets -p icmp --icmp-type echo-request -m limit \ --limit 5/s -m state --state NEW -j ACCEPT $IPT -A icmp_packets -p icmp --icmp-type echo-request -m limit \ --limit 5/m -j LOG --log-prefix "PING:" # nu ist gut mit rumgepinge $IPT -A icmp_packets -p icmp --icmp-type echo-request -j DROP $IPT -A icmp_packets -p icmp --icmp-type echo-reply -m state \ --state ESTABLISHED -j ACCEPT $IPT -A icmp_packets -p icmp --icmp-type destination-unreachable -j ACCEPT $IPT -A icmp_packets -p icmp --icmp-type time-exceeded -j ACCEPT $IPT -A icmp_packets -p icmp --icmp-type parameter-problem -j ACCEPT $IPT -A icmp_packets -p icmp -m limit --limit 5/m -j LOG --log-prefix "ICMP DROP: " $IPT -A icmp_packets -p icmp -j DROP ######################################################## # CHECK_FLAGS Chain ######################################################## # typische Portscans echo -n "CHECK_FLAGS " $IPT -F CHECK_FLAGS $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \ --limit 5/m -j LOG --log-prefix "NMAP-XMAS: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL NONE -m limit \ --limit 5/m -j LOG --log-prefix "NMAP-NULL: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL NONE -j DROP $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN -m limit \ --limit 5/m -j LOG --log-prefix "NMAP-FIN: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags ALL FIN -j DROP # kaputte Verbindungsaufbauten $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,RST SYN,RST -m limit \ --limit 5/m -j LOG --log-prefix "SYN/RST: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \ --limit 5/m -j LOG --log-prefix "SYN/FIN: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,ACK SYN,ACK -m limit \ --limit 5/m -j LOG --log-prefix "SYN/ACK: " $IPT -A CHECK_FLAGS -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset # Neue TCP Pakete sollten ein Syn-flag haben. (außer DNS) $IPT -A CHECK_FLAGS -p tcp --dport ! 53 ! --syn -m limit \ --limit 10/m -j LOG --log-prefix "NEW NOT SYN: " $IPT -A CHECK_FLAGS -p tcp --dport ! 53 ! --syn -j DROP ########################################################## # Server Chain ########################################################## echo -n "Server " $IPT -F Server # accept all from the local interface (in god we trust) $IPT -A Server -i lo -j ACCEPT # private Adressraeume ungeloggt entsorgen, sonst gibts # zuviel muell (die gibts maximal auf nem Tunnel-IF oder am internen IF $IPT -A Server -i eth+ -s 10.0.0.0/8 -j DROP $IPT -A Server -s 169.254.0.0/16 -j DROP $IPT -A Server -s 172.16.0.0/12 -j DROP $IPT -A Server -i ! $INNER -s 192.168.0.0/16 -j DROP # Multicast $IPT -A Server -d 236.83.227.179 -j ACCEPT $IPT -A Server -d 224.0.0.0/8 -j DROP # Am inneren nur privates Subnetz $IPT -A Server -i $INNER -s ! $INNERSUB -j DROP # Nein, ich beantworte keine DHCP Requests, außer von intern $IPT -A Server -i ! $INNER -d 255.255.255.255 -j DROP # Das ungenutze Interface wird tot geschaltet $IPT -A Server -i $DEAD -j DROP # Nach dem wir das geklaert haben, koennten wir uns mal den Verbindungen widmen # Wenn nicht von Loopback, schauen wir beim tcp genauer hin $IPT -A Server -p tcp -j CHECK_FLAGS # Dienste, wunderschoene Dienste, frei fuer alle... # FTP $IPT -A Server -p tcp --dport 21 -j ACCEPT # SSH $IPT -A Server -p tcp --dport 22 -j ACCEPT # DNS $IPT -A Server -p udp --dport 53 -j ACCEPT # DNS tcp $IPT -A Server -p tcp --dport 53 ! --syn -j ACCEPT # Finger $IPT -A Server -p tcp --dport 79 -j ACCEPT # HTTP(S) $IPT -A Server -p tcp --dport 80 -j ACCEPT $IPT -A Server -p tcp --dport 443 -j ACCEPT # Auth $IPT -A Server -p tcp --dport 113 -j ACCEPT # NTP $IPT -A Server -p udp --dport 123 -j ACCEPT # Samba (im offenen Internet will man das nicht) $IPT -A Server -p udp --dport 137:138 -j ACCEPT $IPT -A Server -p tcp --dport 139 -j ACCEPT $IPT -A Server -p tcp --dport 445 -j ACCEPT # Talk $IPT -A Server -p udp --dport 517:518 -j ACCEPT # AFS-Callback Service $IPT -A Server -p udp --dport 7001 -j ACCEPT # Zum Schluss erlaube ich mal die internen IPs auf alle Ports $IPT -A Server -i $INNER -s $INNERSUB -j ACCEPT # Der Rest waeren Verbindungen auf nicht absichtlich angebotene Dienste $IPT -A Server -m limit --limit 10/m -j LOG --log-prefix "UNWANTED_IN: " $IPT -A Server -p tcp -j REJECT --reject-with tcp-reset $IPT -A Server -j DROP } function setup_forwardfw() { $IPT -P FORWARD DROP $IPT -F FORWARD $IPT -N Forward_NEW setup_forwardchains # Conntrack $IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A FORWARD -m state --state NEW -j Forward_NEW $IPT -A FORWARD -m limit --limit 10/m -m state \ --state INVALID -j LOG --log-prefix "--invalid forward drop-- " $IPT -A FORWARD -m state --state INVALID -j DROP # Der Rest wird von der Policy erschlagen (was auch immer da kommen mag) $IPT -A FORWARD -m limit --limit 10/m -j LOG --log-prefix "FORWARD DROP POLICY: " } function setup_forwardchains() { echo -n "Forward_NEW " $IPT -F Forward_NEW $IPT -A Forward_NEW -p tcp -j CHECK_FLAGS $IPT -A Forward_NEW -i $INNER -o $OUTER -s $INNERSUB -j ACCEPT $IPT -A Forward_NEW -i $OUTER -o $INNER -d $INNERSUB -j ACCEPT } function setup_outputfw() { $IPT -P OUTPUT ACCEPT $IPT -A OUTPUT -o $DEAD -j DROP } ################### Procedures ##################### case "$1" in start) echo -n "Starting $DESC: $NAME" /sbin/modprobe ip_tables /sbin/modprobe ip_conntrack /sbin/modprobe ip_conntrack_ftp /sbin/modprobe ip_conntrack_irc /sbin/modprobe ip_conntrack_talk echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects # Alle Regeln loeschen $IPT -F $IPT -X $IPT -t nat -F $IPT -t nat -X $IPT -t mangle -F $IPT -t mangle -X # Regeln aufbauen setup_inputfw setup_forwardfw setup_outputfw # NAT und Forwarding aktivieren $IPT -t nat -A POSTROUTING -o eth0 -j SNAT --to $OUTERIP echo 1 > /proc/sys/net/ipv4/ip_forward echo "done." ;; stop) echo -n "Stopping $DESC: $NAME " echo 0 > /proc/sys/net/ipv4/ip_forward $IPT -F $IPT -X $IPT -t mangle -F $IPT -t mangle -X $IPT -P INPUT ACCEPT $IPT -P OUTPUT ACCEPT $IPT -P FORWARD DROP echo "done." ;; reload-server) echo -n "Reloading $DESC INPUT Subchains configuration..." setup_inputchains echo "done." ;; reload-forward) echo -n "Reloading $DESC FORWARD Subchains configuration..." setup_forwardchains echo "done." ;; restart|force-reload) $0 stop && $0 start ;; dump) echo -n "Writing Firewall Dumpfile: " $IPT -L -nvx > /var/log/firewall-dump-`date+%d.%m.%Y"-"%H:%M:%S`.log $IPT -Z echo -e "done." ;; *) N=/etc/init.d/$NAME # echo "Usage: $N {start|stop|reload-server|reload-forward|restart|force-reload}" >&2 echo "Usage: $N {start|stop|reload-server|reload-forward|restart|force-reload}" >&2 exit 1 ;; esac exit 0