SIP DoS/DDoS Mitigation
From Etel
Contents |
[edit]
Title
SIP DoS/DDoS Mitigation
[edit]
Problem
Almost any SIP implementation is vulnerable to DoS/DDoS attacks, brute force login attemps, and excessive calling.
[edit]
Solution
This script uses iptables and Linux/netfilter to classify and rate limit SIP traffic from different IP addresses.
#!/bin/sh # # SIP DoS mitigation script using Linux iptables/netfilter # WILL NOT WORK WITH SIP TLS, FOR OBVIOUS REASONS... # Copyright 2008 Kristian Kielhofner <kkielhofner@star2star.com> # 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
[edit]
Discussion
The script uses iptables string matching to determine the method of the SIP request. It then uses the iptables hashlimit module to limit the flow of requests by source IP address and destination port. It supports various configuration options, TCP, UDP, etc. It can protect a single host or a network of SIP systems.
[edit]
See Also:
http://astbuild.star2star.com/sipdos
[edit]
Metadata
- By: Kristian Kielhofner
