In a SIP environment interoperability issues are unfortunately an expected reality. Sometimes vendor X will not interoperate fully with vendor Y and neither are willing or able to change their product. Equally some vendors may no longer be providing software updates.
So how can this be fixed most of the time with a quick, cheap and importantly still performant solution?
Enter SIP interceptor!
SIP Interceptor is a Linux userspace application. The purpose of SIP interceptor is to intercept and modify SIP packets (actually any IP packet) on the wire and to modify it before it reaches the application layer (userspace program) or after it has been sent from the application layer. SIP interceptor is built on the Linux “libnetfilter_queue” library. In userspace SIP interceptor uses “libnetfilter_queue” to connect to queue 0 (the default one) and get packets from the kernel. It modifies each packet if required, passes the packet back to the kernel (SIP Interceptor operates in NFQNL_COPY_PACKET mode) and finally issues a verdict on the packet (NF_ACCEPT the packet).
Regular expressions are used to specify how SIP messages should be modified and this gives SIP Interceptor great flexibility as well as minimising the packet inspection and modification overhead. For example using simple regular expressions SIP Interceptor can be used to modify SIP messages in the following way in order to quickly resolve SIP interoperability issues which it might not be possible to fix within the SIP application itself:
- Adding or removing custom SIP headers
- Removing or reordering Via: headers
- Adding a default SDP to INVITES without SDP
- Removing codecs within SDPs
- Removing multiple crypto attributes in SDPs with SRTP offered
- Manipulating P-Asserted-Identity headers on withheld numbers
- Removing non standard tags within the Call-Info header
- Translating one SIP response code to another
- Setting of QoS / Differentiated Services Code Point (DSCP) on SIP and RTP traffic
- Overwriting the Request URI header to fix redirect bugs
- Masking identities / implementing P-Asserted-Identity (PAI)
- Solving NAT headaches on SIP trunks
SIP Interceptor relies on NFQUEUE which is a Linux iptables and ip6tables target that delegates the decision on packets to a userspace application. The following command will pass all outgoing ICMP messages to SIP interceptor or, more correctly, it passes them to queue 0 on which SIP interceptor installs itself:
iptables -A OUTPUT -p icmp -j NFQUEUE --queue-num 0
This installs a rule in the OUTPUT chain to direct ICMP traffic to NFQUEUE and tells NFQUEUE to shunt them into queue 0. Note that if nothing is installed on the queue to set ACCEPT verdicts e.g. SIP Interceptor is not running the packets will be dropped. To remove the rule:
iptables -D OUTPUT -p icmp -j NFQUEUE --queue-num 0
The following rule will ask for a decision to a listening userspace program for all packets into the server:
iptables -A INPUT -j NFQUEUE --queue-num 0
The level of granularity can be increased by specifying IP addresses, port ranges etc. etc. For example, to add a rule to pass all packets to SIP Interceptor for incoming TCP packets to port 5060 from source IP in the 192.168.1.100-192.168.1.200 range only:
iptables -A INPUT -p tcp --dport 5060 -m iprange --src-range 192.168.1.100-192.168.1.200 -j NFQUEUE --queue-num 0
iptables -A INPUT -p udp --dport 5060 -j NFQUEUE --queue-num 0
-p sets the IP protocol for the rule, which can be either icmp, tcp, udp, or all, to match every supported protocol. In addition, any protocols listed in /etc/protocols may also be used. If this option is omitted when creating a rule, the all option is the default.
For more information please see:
Of course this solution only works for UDP and TCP transports. For SIP over TLS (and Windows OS for that matter) we would need to consider something a bit more complex like reSIProcate (http://www.resiprocate.org).
But hopefully this is a good start and you can see SIP Interceptor in action below.