[OpenSIPS-Users] Opensips behind a NAT - change record-route

John Hablitzel jjblitz071 at gmail.com
Thu Jan 11 12:16:49 EST 2018


Relatively new to OpenSIPS but have been working with Asterisk and VoIP for
several years.  We want to use the load balancer or dispatcher modules to
distribute inbound calls from a SIP provider among several Asterisk
servers.  This will be coming in from another private network that is out
of our control, therefore security is definitely required.  We won't be
using OpenSIPS to control far-end clients that are behind NAT (far-end).

I know that it is recommended in this situation that OpenSIPS be on a
public IP (or IP on the "outside" network", but the requirement in this
particular situation is that this must be behind a NAT firewall, as there
are other IP communications from servers on the the internal network that
must use this same outside IP for communications with other services.  The
outside network provider only allows us to have a single IP on their
network for everything.

I have the inbound calls mostly working now in my lab with the LB
module, using RTPProxy to anchor the media and some of the nathelper
stuff.  However am seeing issues with the ACK on the 200OK being sent to
the internal OpenSIPS IP and not the external IP on the NAT.  I believe
this is due to the Internal IP being in the record-route header on the
200OK.  Pouring through the forums and other documentation I can find, I
haven't been able to find any way to change this.

So I have 2 questions:
1) Is OpenSIPS even capable of operating in this mode?  In everything I've
read, there is a bunch of documentation about handling NAT at the far-end,
where UAC's are behind a NAT, but very little (and nothing with any
concrete solution) about using OpenSIPS server behind a NAT.
2) if it is possible, can anyone provide a sample .cfg where they are have
accomplished it?  I tried adding record_route_preset to the reply section,
but OpenSIPS complains saying it can't be added in a reply section.

Here is my setup.  Any help will be greatly appreciated.

Asterisk
PBXs<---------------------OpenSIPS<-------------------------------Firewall<---------------------------Trunk
Provider (Asterisk box)
10.95.95.235                            10.95.95.220
 10.95.95.1 - 192.168.85.252                        192.168.85.242
10.95.95.236

My .cfg.  I realize there is a bunch of extra "stuff" here, but am working
from a template at this point since I'm still going through the huge
learning curve of OpenSIPS.

####### Global Parameters #########

log_level=4 #debug
#log_level=3 #info
log_stderror=no
log_facility=LOG_LOCAL0

children=4

/* uncomment the following lines to enable debugging */
#debug_mode=yes

/* uncomment the next line to enable the auto temporary blacklisting of
   not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns
   lookup failures (default disabled) */
#dns_try_ipv6=yes

/* comment the next line to enable the auto discovery of local aliases
   based on revers DNS on IPs */
auto_aliases=no


listen=udp:10.95.95.220:5060   # CUSTOMIZE ME

#listen=tcp:10.95.95.220:5060   # CUSTOMIZE ME


####### Modules Section ########

#set module path
mpath="/usr/local/lib64/opensips/modules/"

#### SIGNALING module
loadmodule "signaling.so"

#### StateLess module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)

#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)

#### MAX ForWarD module
loadmodule "maxfwd.so"

#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"

#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)

#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode",   0)

#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)

#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
   if you enable this parameter, be sure the enable "append_fromtag"
   in "rr" module */
modparam("acc", "detect_direction", 0)


####  NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger at 192.168.85.252")
#CUSTOMIZE ME
modparam("nathelper", "received_avp", "$avp(received_nh)")

loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:7722") # CUSTOMIZE ME

loadmodule "proto_udp.so"

#loadmodule "proto_tcp.so"

loadmodule "db_mysql.so"

loadmodule "dialog.so"
modparam("dialog", "db_mode", 1)
modparam("dialog", "db_url", "mysql://opensips:opensips@localhost/opensips")

loadmodule "load_balancer.so"
modparam("load_balancer", "db_url", "mysql://opensips:opensips@localhost
/opensips")
modparam("load_balancer", "probing_method", "OPTIONS")
modparam("load_balancer", "probing_interval", 10)


####### Routing Logic ########

# main request routing logic

route{
xlog("starting route\n");
force_rport();
if (nat_uac_test("23")) {
xlog("we have a NAT\n");
if (is_method("REGISTER")) {
fix_nated_register();
setbflag(NAT);
} else {
fix_nated_contact();
setflag(NAT);
}
}

if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}

if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
xlog("has_totag\n");
if (loose_route()) {
xlog("loose_route\n");
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
} else if (is_method("INVITE")) {
# even if in most of the cases is useless, do RR for
# re-INVITEs alos, as some buggy clients do change route set
# during the dialog.
record_route();
}

if (check_route_param("nat=yes"))
setflag(NAT);

# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
} else {
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after
# a 487 or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ->
# ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}

# OPTIONS processing - don't forward
if (is_method("OPTIONS")) {
sl_send_reply("200", "OK");
xlog("OPTIONS received\n");
exit;
}
# CANCEL processing
if (is_method("CANCEL"))
{
xlog("CANCEL received\n");
if (t_check_trans())
t_relay();
exit;
}

t_check_trans();

/* if ( !(is_method("REGISTER")  ) ) {
xlog("check_trans - to=$tu/from=$fu/request=$ru\n");
if (from_uri==myself){
}
else {
# if caller is not local, then called number must be local
if (!uri==myself) {
send_reply("403","Relay forbidden");
exit;
}
}
}*/

# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
sl_send_reply("403","Preload Route denied");
exit;
}

# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();

# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log");
}

if (!uri==myself) {
append_hf("P-hint: outbound\r\n");
route(relay);
}

# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE"))
{
sl_send_reply("503", "Service Unavailable");
exit;
}

if (is_method("REGISTER"))
{

if ( proto==TCP ||  0 ) setflag(TCP_PERSISTENT);

if (isflagset(NAT)) {
setbflag(SIP_PING_FLAG);
}

if (!save("location"))
sl_reply_error();

exit;
}

if ($rU==NULL) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}


# do lookup with method filtering
if (!lookup("location","m")) {
t_newtran();
t_reply("404", "Not Found");
exit;
}

if (isbflagset(NAT)) setflag(NAT);

# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}


route[relay] {
if (isflagset(NAT)) {
xlog("adding rr_param\n");
add_rr_param(";nat=yes");
}

# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
xlog("incoming INVITE\n");
if (isflagset(NAT)) {
xlog("incoming INVITE with NAT\n");
rtpproxy_offer("ro");
}

t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");

xlog("calling lb_start_or_next\n");
lb_start_or_next("1","pstn","r");
if ($retcode<0) {
             xlog("calling lb_start_or_next\n");
sl_send_reply("500","Internal Error");
             exit;
}
xlog("Selected destination is: $du\n");
# send it out
if (!t_relay()) {
xlog("relay failed\n");
sl_reply_error();
}
}
else {
xlog("reply\n");
t_on_failure("missed_call");
t_relay();
exit;
}
xlog("exiting route-relay\n");
exit;
}


branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}


onreply_route[handle_nat] {
xlog("onreply_route-handle nat\n");

if (nat_uac_test("1")) {
xlog("nat test yes\n");
fix_nated_contact();
}
if ( isflagset(NAT) ) {
xlog("nat flag set-doing rtpproxy answer\n");
rtpproxy_answer("ro");
}
}


failure_route[missed_call] {
xlog("failure route - trying next destination\n");
lb_disable_dst();
if (lb_start_or_next("1","pstn","r")) {
t_on_failure("missed_call");
t_relay();
}
else {
xlog("no destinations available\n");
t_reply("503", "Service Unavailable");
}
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply("404","Not found");
## exit;
##}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opensips.org/pipermail/users/attachments/20180111/306cfe21/attachment-0001.html>


More information about the Users mailing list