#!/bin/sh # a well thought out iptables script for Asterisk # 2011.02.03 Jeremy Kister # change trusted array and RTPRANGE below to match your needs # (get RTPRANGE from /etc/asterisk/rtp.conf) # it's probably a good idea for North American users of this code to # block the rest of the world from talking to your asterisk box. to # do this, download http://jeremy.kister.net/code/iptables/make-non-na.pl # run it once, and then run this code again (e.g., /etc/init.d/iptables start) # if you get an error about "iptables: Invalid argument", do this once (debian): # echo 'options ipt_recent ip_pkt_list_tot=100' > /etc/modprobe.d/ipt_recent # /etc/init.d/iptables clear # modprobe -r ipt_recent # modprobe ipt_recent # /etc/init.d/iptables start RTPRANGE="5000:31001" # from /etc/asterisk/rtp.conf THROTTLE=1 trusted=( 10.0.0.0/24 # local network 10.0.1.0/29 # VPN users ) siprtp=( 64.21.13.0/24 # rapidvox 64.154.41.0/24 # myipcomms 184.72.221.84/32 # acrobits @ aws ec2 nva #1 184.73.248.111/32 # acrobits @ aws ec2 nva #2 2011.04.11 75.101.138.128 # google @ aws ec2 nva 72.14.204.118 # voice.l.google.com (a) 64.233.169.118 # voice.l.google.com (b) 74.125.93.118 # voice.l.google.com (c) 2011.02.03 74.125.91.118 # voice.l.google.com (d) 2011.02.03 ) monitor=( monitoring_host1.example.net monitoring_host2.example.net ) override=( 86.59.118.153 # volatile.debian.org for apt-get ) lusers=( 209.128.81.170/32 # 1Mb/s sip registers 20100922 216.182.224.0/20 # AWS EC2 NVA 72.44.32.0/19 # AWS EC2 NVA 67.202.0.0/18 # AWS EC2 NVA 75.101.128.0/17 # AWS EC2 NVA 174.129.0.0/16 # AWS EC2 NVA 204.236.224.0/19 # AWS EC2 NVA 204.236.128.0/18 # AWS EC2 NCA 184.72.0.0/15 # AWS EC2 NCA 79.125.0.0/17 # AWS EC2 IRE 68.67.128.0/18 # AppNexus 8.12.224.0/20 # AppNexus 8.19.16.0/20 # AppNexus 72.32.0.0/16 # RackSpace 65.61.128.0/18 # RackSpace 69.20.0.0/17 # RackSpace ) PATH=/sbin:$PATH PRE="iptables" LOGOPTS="--log-level 4 --log-tcp-sequence --log-tcp-options --log-ip-options --log-prefix" if [ "$1" = "stop" ] ; then echo "$0 - nothing to stop" exit elif [ "$1" = "start" ] ; then # Drop ICMP echo-request messages sent to broadcast or multicast addresses echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts # Drop source routed packets echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route # Enable TCP SYN cookie protection from SYN floods echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 'Loading iptables ruleset: load "active"' iptables --flush iptables -X SYN_FLOOD 2>/dev/null iptables -X THROTTLE 2>/dev/null # Set default policies iptables --policy INPUT DROP iptables --policy FORWARD DROP iptables --policy OUTPUT ACCEPT # Allow unlimited traffic on the loopback interface iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # 127/8 traffic ONLY belongs on lo iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j LOG $LOGOPTS "$PRE public 127! " iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j DROP for net in "${trusted[@]}" ; do iptables -A INPUT -s $net -j ACCEPT done # we are a dhcp server iptables -A INPUT -p udp -s 169.254.0.0/16 -d 255.255.255.255 -j ACCEPT iptables -A INPUT -p udp -s 0.0.0.0 --sport 68 -d 255.255.255.255 --dport 67 -j ACCEPT # allow DNS to our recursive servers so we can look up names below for ns in `awk '/nameserver/ { print $2 }' /etc/resolv.conf` ; do iptables -A INPUT -p udp -s $ns --sport 53 --dport 1024:65535 -j ACCEPT done # explicity allow these, we dont rate-limit them. # icmp for unreachables, etc. for net in "${siprtp[@]}" ; do iptables -A INPUT -p udp -s $net --sport 1024:65535 --dport 5060 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 5060 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 5061 -j ACCEPT iptables -A INPUT -p icmp -s $net -j ACCEPT done # temp hack for google voice iptables -A INPUT -p udp -s 75.101.138.128 --sport 1024:65535 --dport 1024:65535 -j ACCEPT iptables -A INPUT -p udp -s 74.125.0.0/16 --sport 1024:65535 --dport 1024:65535 -j ACCEPT for net in "${monitor[@]}" ; do iptables -A INPUT -p udp -s $net --sport 1024:65535 --dport 123 -j ACCEPT iptables -A INPUT -p udp -s $net --sport 1024:65535 --dport 161 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 4573 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 5038 -j ACCEPT iptables -A INPUT -p udp -s $net --sport 1024:65535 --dport 5060 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 5060 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 5061 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 6929 -j ACCEPT iptables -A INPUT -p tcp -s $net --sport 1024:65535 --dport 44647 -j ACCEPT done # hosts below are excluded from the large list of lusers for net in "${override[@]}" ; do iptables -A INPUT -p tcp -s $net -m state --state RELATED,ESTABLISHED -j ACCEPT done for net in ${lusers[@]} `cat /etc/iptables.non-na` ; do iptables -A INPUT -s $net -j LOG $LOGOPTS "$PRE luser " iptables -A INPUT -p udp -s $net -j DROP iptables -A INPUT -s $net -j REJECT done # established packets, unlimited outbound iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT # new incoming tcp sockets must start with syn iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOG $LOGOPTS "$PRE new tcp !syn" iptables -A INPUT -p tcp ! --syn -m state --state NEW -j REJECT # drop xmas packets iptables -A INPUT -p tcp --tcp-flags ALL ALL -j LOG $LOGOPTS "$PRE xmas packet" iptables -A INPUT -p tcp --tcp-flags ALL ALL -j REJECT # drop null packets iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOG $LOGOPTS "$PRE null tcp packet" iptables -A INPUT -p tcp --tcp-flags ALL NONE -j REJECT # syn-flooding is evil iptables -N SYN_FLOOD iptables -A INPUT -p tcp --syn -j SYN_FLOOD iptables -A SYN_FLOOD -m limit --limit 30/s --limit-burst 100 -j RETURN iptables -A SYN_FLOOD -j LOG $LOGOPTS "$PRE SYN FLOOD " iptables -A SYN_FLOOD -j REJECT # furtive port scanning #iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT # allow rate-limited ping/icmp iptables -A INPUT -p icmp -m limit --limit 20/s -j ACCEPT # DNS #iptables -A INPUT -p udp --dport 53 -j ACCEPT iptables -A INPUT -p udp --sport 53 --dport 1024:65535 -j ACCEPT # RTP iptables -A INPUT -p udp --sport 1024:65535 --dport $RTPRANGE -j ACCEPT if [ "$THROTTLE" ] ; then # hosts we get NTP from - don't throttle them for host in `awk '/^server/ { print $2 }' /etc/ntp.conf` ; do iptables -A INPUT -p udp --dport 123 --sport 123 -s $host -j ACCEPT done iptables -A INPUT -p udp --dport 5060 -j THROTTLE iptables -A INPUT -p tcp --dport 5060 -j THROTTLE iptables -A INPUT -p udp --dport 123 -j THROTTLE iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j THROTTLE iptables -A THROTTLE -m recent --set --name ABUSE iptables -A THROTTLE -m recent --update --seconds 86400 --hitcount 90 --name ABUSE -j LOG $LOGOPTS "$PRE day " iptables -A THROTTLE -m recent --rcheck --seconds 86400 --hitcount 90 --name ABUSE -j DROP iptables -A THROTTLE -m recent --update --seconds 3600 --hitcount 60 --name ABUSE -j LOG $LOGOPTS "$PRE hour " iptables -A THROTTLE -m recent --rcheck --seconds 3600 --hitcount 60 --name ABUSE -j DROP iptables -A THROTTLE -m recent --update --seconds 60 --hitcount 15 --name ABUSE -j LOG $LOGOPTS "$PRE min " iptables -A THROTTLE -m recent --rcheck --seconds 60 --hitcount 15 --name ABUSE -j DROP else echo "WARNING: not throttling exposed NTP, SSH or SIP" fi iptables -A INPUT -p tcp --dport 5060 --sport 1024:65535 -j ACCEPT iptables -A INPUT -p udp --dport 5060 --sport 1024:65535 -j ACCEPT iptables -A INPUT -p tcp --dport 22 --sport 1024:65535 -j ACCEPT iptables -A INPUT -p udp --dport 123 --sport 123 -j ACCEPT iptables -A INPUT -j LOG $LOGOPTS "$PRE " iptables -A INPUT -p udp -j DROP iptables -A INPUT -j REJECT elif [ "$1" = "clear" ] ; then iptables --flush iptables -X SYN_FLOOD 2>/dev/null iptables -X THROTTLE 2>/dev/null echo 'Loading iptables ruleset: load "inactive"' iptables -A INPUT -j ACCEPT iptables -A OUTPUT -j ACCEPT else echo "$0 [start|stop|clear]" exit 1 fi iptables-save > /root/iptables-save.out