#!/bin/sh # set -e ### BEGIN INIT INFO # Provides: firewall # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start iptables based firewall # Description: Start IPv4 and IPv6 firewall ### END INIT INFO # Version: @(#)firewall 1.0.1 2006-01-22 tehpeh-web@tty1.net First version IPv4 only # 1.2.0 2011-05-28 tehpeh-web@tty1.net Added IPv6 support # PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=firewall iptables4=/sbin/iptables iptables6=/sbin/ip6tables pub_if=eth0 # public interface, e.g. eth0 pub_ipv4=70.85.16.194 # public IPv4 address pub_ipv6=2600:3c00::f03c:91ff:fe96:d898 # public IPv6 address test -x $iptables4 || exit 0 test -x $iptables6 || exit 0 firewall_flush() { # flush rules $iptables4 -F $iptables6 -F $iptables4 -F -t mangle $iptables6 -F -t mangle $iptables4 -X -t mangle $iptables6 -X -t mangle $iptables4 -F -t nat $iptables4 -X -t nat $iptables4 -X $iptables6 -X } firewall_default() { default=$1 # apply default rules $iptables4 -P INPUT $default $iptables6 -P INPUT $default $iptables4 -P FORWARD $default $iptables6 -P FORWARD $default $iptables4 -P OUTPUT $default $iptables6 -P OUTPUT $default } firewall_start() { # default policy firewall_default DROP # accept everything from loopback $iptables4 -A INPUT -i lo -j ACCEPT $iptables6 -A INPUT -i lo -j ACCEPT $iptables4 -A OUTPUT -o lo -j ACCEPT $iptables6 -A OUTPUT -o lo -j ACCEPT # Allow Link-Local addresses $iptables6 -A INPUT -s fe80::/10 -j ACCEPT $iptables6 -A OUTPUT -s fe80::/10 -j ACCEPT # drop Bad Guys $iptables4 -A INPUT -m recent --update --seconds 60 -j DROP $iptables6 -A INPUT -m recent --update --seconds 60 -j DROP # Filter all packets that have RH0 headers: $iptables6 -A INPUT -m rt --rt-type 0 -j DROP $iptables6 -A FORWARD -m rt --rt-type 0 -j DROP $iptables6 -A OUTPUT -m rt --rt-type 0 -j DROP # drop spoofed packets (i.e. packets with local source addresses coming from outside etc.), mark as Bad Guy $iptables4 -A INPUT -i $pub_if -s $pub_ipv4 -m recent --set -j DROP $iptables6 -A INPUT -i $pub_if -s $pub_ipv6 -m recent --set -j DROP # accept ICMP packets (ping et.al.) $iptables4 -A INPUT -p icmp -j ACCEPT $iptables6 -A INPUT -p icmpv6 -j ACCEPT $iptables6 -A OUTPUT -p icmpv6 -j ACCEPT $iptables6 -A FORWARD -p icmpv6 -j ACCEPT # internet (established and out) $iptables4 -A OUTPUT -o $pub_if -j ACCEPT $iptables6 -A OUTPUT -o $pub_if -j ACCEPT $iptables4 -A INPUT -i $pub_if -m state --state ESTABLISHED,RELATED -j ACCEPT $iptables6 -A INPUT -i $pub_if -m state --state ESTABLISHED,RELATED -j ACCEPT # allow public services $iptables4 -A INPUT -i $pub_if -p tcp -d $pub_ipv4 -m multiport --dports 25,80,143,443,465,993,8000 -j ACCEPT $iptables6 -A INPUT -i $pub_if -p tcp -d $pub_ipv6 -m multiport --dports 25,80,143,443,465,993,8000 -j ACCEPT # accept ssh connections (max 2/minute from the same IP address) $iptables4 -A INPUT -p tcp --dport 22 -m recent --update --seconds 300 --hitcount 10 --name SSH -j DROP $iptables6 -A INPUT -p tcp --dport 22 -m recent --update --seconds 300 --hitcount 10 --name SSH -j DROP $iptables4 -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH -j ACCEPT $iptables6 -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH -j ACCEPT # reject everything else in INPUT $iptables4 -A INPUT -j REJECT $iptables6 -A INPUT -j REJECT } firewall_stop() { # flush rules firewall_flush # default policy firewall_default ACCEPT } case "$1" in start) echo -n "Starting $NAME: " firewall_start echo "OK." ;; stop) echo -n "Stopping $NAME: " firewall_stop echo "OK." ;; restart|reload) echo -n "Restarting $NAME: " firewall_stop sleep 1 firewall_start echo "OK." ;; *) echo "Usage: /etc/init.d/$NAME {start|stop|restart|reload}" >&2 exit 1 ;; esac exit 0