SIP topology hiding and forward proxy

Problem this snippet solves:

SIP calls from inside to outside are forward with topology hiding.

Code :

rule sip_topo_hide_fwd_proxy {

# This I-rule allows SIP calls from inside a network to a server outside.  It acts as a forward proxy
# and hides the internal IP topology by mapping the via and the from headers.  This version does not take
# any action in regards to the SDP session or the media connection.  That connection will be handled 
# separately.  Future version of this i-rule will hopefully take care of the media connection.
# This I-rule was developed in conjunction with the customer who tested it and liked it.

when SIP_REQUEST {
# Log various SIP headers for those who must see to believe.
#log -noname local0. "Incoming From:  [SIP::header From] To: [SIP::header To]"
        #log -noname local0. "Incoming URI: [SIP::uri]  - call-id: [SIP::call_id] - Via: [SIP::header Via]"

        # Save the caller IP for use in later mapping. 

        set originator_ip [IP::remote_addr]

# This I-rule works as a forward proxy.  It is applied to a virtual server with a "Network" range 
# destination address as opposed to a specific host address.  This means we do not have a specific
# node to forward the connection to.  The specific node IP and Port are captured from the datastream
# and assigned below.

# If you are using UDP instead of TCP, be sure to uncomment the UDP version and comment the TCP.

        node [IP::local_addr]:[TCP::local_port]

# UDP version
#node [IP::local_addr]:[UDP::local_port]
}

when SIP_REQUEST_SEND {
# Set SNAT IP so that we can use it later for mapping.
set snat_ip [serverside {IP::local_addr}]

# The following hides the FROM HEADER IP addressing. The caller IP is replaced with the Outside snat IP.


# Example of a SIP From header format to use as reference.
#\"4136\" <4136>;tag=3459266474-613858
    
# The following extracts the IP address out of the SIP from header.
# Sometimes this is the same as the clientside remote IP but by getting it
# out of the From header it makes it work in all cases.

set from_ip [findstr [SIP::header From] "@" 1 ">"] 

# Prepare a list for the string map containing the IP in the From/Via header and the load ballencer/self IP. 
set ip_map [list $from_ip $snat_ip] 

# Map SNAT IP to original IP found in the From header. 
set new_from_header [string map $ip_map  [SIP::header "From"]]

# Remove old From header, and insert the modified one.
SIP::header remove from
SIP::header insert from "$new_from_header"

# VIA Header is transformed similarly to FROM header.

# Reference for the SIP Via header format.
# SIP/2.0/UDP 172.16.5.28:5060;branch=z9hG4bK46efb99bd134c21a63f7a943dcb05fb7
#  :;;;


# Map SNAT IP to orignial IP in the Via Header.
set new_via_header [string map $ip_map  [SIP::header "Via"]]

# Remove old Via header, and insert the modified one.
SIP::header remove via
SIP::header insert via $new_via_header
}

when SIP_RESPONSE {

# Prepare a list for the string map containing the IP in the From/Via header and the load ballencer/self IP. 
# Please note that this list is the reverse of the one in the SIP_REQUEST event.
set ip_map [list $snat_ip $originator_ip] 

# FROM header re-mapping

# Replace SNAT IP with the SBC Node IP.
set new_from_header [string map $ip_map  [SIP::header "From"]]

# Remove old From header, and insert the modified one.
SIP::header remove from
SIP::header insert from "$new_from_header"

# VIA header re-mapping.

#log -noname local0. "Replacing IP: [lindex $ip_map 0] with IP: [lindex $ip_map 1] in Via header."
# Replace SNAT IP with the SBC Node IP. 
set new_via_header [string map $ip_map [SIP::header "Via"]]

# Remove old Via header, and insert the modified one.
SIP::header remove via
SIP::header insert via $new_via_header
}
}
Published Mar 18, 2015
Version 1.0

Was this article helpful?

1 Comment

  • Hi John, have you any advice for using the SDP::Meda conn 0 command? Can't seem to get it to correctly re-write the media IP and wondering if you have had any success with it?