John,
You just need to tell OpenSIPS to use the public IP in messaging instead of the
private IP. You can do this a few ways depending on your scenario and your
requirements.
If you can use the public IP always, when sending both to Asterisk and the SIP
provider, then you can use the global parameter set_advertised_address [1].
This will cover all messaging and is the easiest method.
If the Asterisk side must use the private IP, then one way is to have two
separate interfaces, and set the advertised address of the public-facing one to
the Public NAT IP using the “as” function of the “listen” parameter [2]. Then
you can use routing rules on the host or the force_send_socket() [3] function
to send messages out the appropriate interface for internal or external.
OpenSIPS should use the appropriate address in messaging, including (I believe)
the necessary double record-routing, although this may require the setting of
the mhomed [4] parameter, I am not sure.
If you only have one interface available on the machine, then you can use the
record_route_preset() [5] function but you can’t use it in a reply, as you say.
Record-Route headers are added as the Request passes through, not on the reply.
You will also have to double record-route so there will be a record for each
interface the message traverses (public and private). So on an initial request
from the public network, you will record route the private first, then the
public, like so:
record_route_preset("PRIVATE_ADDRESS:LOCAL_PORT", "PUBLIC_ADDRESS:LOCAL_PORT");
add_rr_param(";r2=on");
On a request from the private to public network, you would reverse the order of
the addresses in the record-route. The “r2=on” parameter is necessary to let
OpenSIPS know that double record-routing was used, so that both Route headers
will be removed when loose_route() is called for sequential requests. This is
the way I have implemented it as neither of the other two options would work
for me.
There are probably also a few other ways to do it too. ☺
[1] - http://www.opensips.org/Documentation/Script-CoreParameters-2-3#toc25
[2] - http://www.opensips.org/Documentation/Script-CoreParameters-2-3#toc63
[3] - http://www.opensips.org/Documentation/Script-CoreFunctions-2-3#toc16
[4] - http://www.opensips.org/Documentation/Script-CoreParameters-2-3#toc78
[5] - http://www.opensips.org/html/docs/modules/2.3.x/rr.html#idp5595248
Ben Newlin
From: Users <[email protected]> on behalf of John Hablitzel
<[email protected]>
Reply-To: OpenSIPS users mailling list <[email protected]>
Date: Thursday, January 11, 2018 at 12:18 PM
To: "[email protected]" <[email protected]>
Subject: [OpenSIPS-Users] Opensips behind a NAT - change record-route
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<http://10.95.95.220:5060> # CUSTOMIZE ME
#listen=tcp:10.95.95.220:5060<http://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:[email protected]<mailto:sip%[email protected]>") #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;
##}
_______________________________________________
Users mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users