#!/bin/sh # # SIP DoS mitigation script using Linux iptables/netfilter # WILL NOT WORK WITH SIP TLS, FOR OBVIOUS REASONS... # Copyright 2008 Kristian Kielhofner # This program is distributed under the terms of the GNU Public License V2 # # TODO: Use the state module for TCP (maybe even UDP)? # TODO: Evaluate string matching algorithms and offsets # TODO: Better matching for URIs (support tel:)? # TODO: Tweak and/or provide configuration for hashlimit expires and bursts # TODO: Support configuration of INVITE/REGISTER/etc limits and methods # TODO: Don't always clear INPUT/FORWARD tables - allow for other rulesets # TODO: Testing? # INVITE rate, per host. Remember a successful (authenticated) call requires 2 INVITEs- # Initial INVITE, 407 auth required (w/ nonce), INVITE with nonce and authentication. IRATE=4/minute # REGISTER rate, per host. RRATE=2/minute # All other SIP methods rate, per host. Be careful with SUBSCRIBEs, OPTIONS, CANCELs, etc. ORATE=10/minute # Methods for this script to ignore. These SIP methods are always allowed. IGMETH="OPTIONS" # Burst BURST=1 # Interface(s) to protect on INPUT. Seperate multiple interfaces with spaces. # This will protect SIP services on THIS HOST. IFACE="eth0" # Reject/drop action - usually something like DROP or REJECT. # Use ACCEPT to use this script to not filter traffic but still collect statistics. DACTION=DROP # Protocol(s) to filter - can be either tcp or udp or both. Seperate multiples with spaces. PROTOCOLS="udp tcp" # Enable logging. #LOG=YES # Block tel: URIs completely? # P.S. - tel: sucks! BLOCKTEL=yes # Interface(s) to protect on FORWARD. Seperate multiple interfaces with spaces. # The same hashtable will protect the entire network from the same host(s). # Destination IP is NOT taken into consideration. # This will protect any SIP services running on the network that uses this machine # as a router (as long as you get the interfaces right). #FIFACE="eth0" # Location of iptables binary. IPTABLES=`which iptables` # Search packet to this location. A larger offset looks further into the packet # and takes more time but could catch more attacks (and false alarms). # Remember, the method to match on is always in the beginning of the packet. OFFSET=65 # SIP port SPORT=5060 if [ ! "$1" ] then echo "SIP DoS/DDoS mitigation script for iptables See top of script for configuration Usage: $0 [start|stop|status]" exit 1 fi if [ "$1" = "status" ] then $IPTABLES -L -v -n exit fi # Setup iptables $IPTABLES -F sipdos 2> /dev/null $IPTABLES -X sipdos 2> /dev/null $IPTABLES -N sipdos 2> /dev/null if [ "$1" = "stop" ] then echo "Clearing iptables rules..." if [ "$FIFACE" ] then $IPTABLES -F FORWARD 2> /dev/null fi $IPTABLES -F INPUT 2> /dev/null exit fi # Send the right traffic through our chain for i in $IFACE do for l in $PROTOCOLS do $IPTABLES -A INPUT -i $i -m $l -p $l --dport $SPORT -j sipdos done done # Send the right forwarded traffic through our chain if [ "$FIFACE" ] then for j in $FIFACE do for l in $PROTOCOLS do $IPTABLES -A FORWARD -i $j -m $l -p $l --dport $SPORT -j sipdos done done fi # "Handle" tel: URIs if [ "$BLOCKTEL" ] then $IPTABLES -A sipdos -m string --string "tel:" --algo bm --to $OFFSET -j $DACTION fi # Ignore certain (configured) methods if [ "$IGMETH" ] then for k in $IGMETH do $IPTABLES -A sipdos -m string --string "$k sip:" --algo bm --to $OFFSET -j ACCEPT done fi # Finally set some limits... # INVITE limit $IPTABLES -A sipdos -m string --string "INVITE sip:" --algo bm --to $OFFSET \ -m hashlimit --hashlimit $IRATE --hashlimit-burst $BURST \ --hashlimit-mode srcip,dstport --hashlimit-name sip_i_limit -j ACCEPT # REGISTER limit $IPTABLES -A sipdos -m string --string "REGISTER sip:" --algo bm --to $OFFSET \ -m hashlimit --hashlimit $RRATE --hashlimit-burst $BURST \ --hashlimit-mode srcip,dstport --hashlimit-name sip_r_limit -j ACCEPT # All other SIP packets... $IPTABLES -A sipdos -m hashlimit --hashlimit $ORATE --hashlimit-burst $BURST \ --hashlimit-mode srcip,dstport --hashlimit-name sip_o_limit -j ACCEPT # Take action on everything else if [ $LOG ] then $IPTABLES -A sipdos -j LOG fi $IPTABLES -A sipdos -j $DACTION