[OpenSIPS-Users] Example config for NATed UACs, RTPproxy, and NATed OpenSIPS (version 1.6.4)

Damon Miller dmiller at cloudswitch.com
Mon Jan 10 01:12:08 CET 2011


All,


I've seen many requests for an example working config that shows a working RTPproxy configuration with NATed clients, but I haven't seen many responses.  I recently spent an absurd amount of time getting a working configuration in place so I thought I would post it here in case it's helpful to anyone.

Three quick points:

1.  I have only tested this with clients behind a NAT firewall, i.e. I haven't tested with clients that have a public IP.


2.  My OpenSIPS server is behind a NAT firewall itself.  To deal with this, I added the two "advertised" options, as follows:

advertised_address="xx.xx.xx.xx"
alias="xx.xx.xx.xx:5060


(Replace the "xx.xx.xx.xx" with the NAT firewall's public IP.)

I also had to use a modified version of RTPproxy that presents the firewall's public IP even though it binds to a private IP.  Here's a post which summarizes that version of RTPproxy:

http://opensips-open-sip-server.1449251.n2.nabble.com/Rtpproxy-behind-the-NAT-td5008041.html


I run RTPproxy like this:

rtpproxy -A xx.xx.xx.xx -l 192.168.20.154 -s udp:127.0.0.1:12221 -m 25000 -M 65000 -F -d DBUG:LOCAL1


3.  I had to "tell" OpenSIPS that my firewall's public IP was one of its local domains.  I'm using MySQL as you'll see in the config file so all I had to do was insert a value into the 'domain' table.  That was pretty obvious, i.e.:

mysql> insert into domain (domain) values ("xx.xx.xx.xx");

(Replace 'xx.xx.xx.xx' with your public IP.)



Here's my 'opensips.cfg' file:

--

# ----------- global configuration parameters ------------------------
debug=3
fork=yes
log_facility=LOG_LOCAL0
log_stderror=no
children=4
port=5060
dns=no
rev_dns=no

advertised_address="xx.xx.xx.xx"
alias="xx.xx.xx.xx:5060"

# ------------------ module loading ----------------------------------
mpath="/usr/local/lib64/opensips/modules/"
loadmodule "db_mysql.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
loadmodule "uri.so"
loadmodule "nathelper.so"
loadmodule "domain.so"

# ----------------- setting module-specific parameters ---------------
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("usrloc", "db_url", "mysql://opensipsrw:opensipsrw@localhost/opensips")
modparam("usrloc", "db_mode", 2)
modparam("rr", "enable_full_lr", 1)
modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:12221")
modparam("nathelper", "nortpproxy_str", "")
modparam("domain", "db_url", "mysql://opensipsrw:opensipsrw@localhost/opensips")

################## NAT ######################
modparam("usrloc", "nat_bflag", 6)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 8)
modparam("nathelper", "received_avp", "$avp(i:801)")
################## NAT ######################


# main routing logic
route {

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

    if (msg:len >=  2048 ) {
        sl_send_reply("513", "Message too big");
        exit;
    };


    ################## NAT ######################
    if (nat_uac_test("3")) {

        if (is_method("REGISTER") && !is_present_hf("Record-Route")) {

            # Rewrite contact with source IP of signalling
            fix_nated_contact();

            force_rport();
            setbflag(6); # Mark as NATed

            # if you want SIP NAT pinging
            setbflag(8);
        };
    };
    ################## NAT ######################

    if (!method=="REGISTER")
        record_route();

    # subsequent messages withing a dialog should take the
    # path determined by record-routing
    if (loose_route()) {
        # mark routing logic in request
        append_hf("P-hint: rr-enforced\r\n");
        route(1);
    };

    if (!uri==myself) {
        # mark routing logic in request
        append_hf("P-hint: outbound\r\n");
        route(1);
    };

    if (uri==myself) {
        if (method=="REGISTER") {
            save("location");
            exit;
        };
    }

    if (is_method("BYE"))
        unforce_rtp_proxy();
  
    if (!lookup("location","m")) {
        switch ($retcode) {
            case -1:
            case -3:
                t_newtran();
                t_on_failure("1");
                t_reply("404", "Not Found");
                exit;
            case -2:
                sl_send_reply("405", "Method Not Allowed");
                exit;
        }
    };

    route(1);
}



route[1] {

    ################## NAT ######################
    if (uri=~"[@:](192\.168\.10\.172\.(1[6-9]2[0-9]3[0-1])\.)" && !search("^Route:")) {
        sl_send_reply("479", "We don't forward to private IP addresses");
        exit;
    };

    # if client or server know to be behind a NAT, enable relay
    if (isbflagset(6)) {
        if (has_body("application/sdp")) {
            rtpproxy_offer("o");
        };
    };

    t_on_reply("1");
    ################## NAT ######################


    # send it out now; use stateful forwarding as it works
    # reliably even for UDP2TCP
    if (!t_relay()) {
        sl_reply_error();
    };

    exit;
}



onreply_route[1] {

    ################## NAT ######################
    if (isbflagset(6) && status =~ "(183)|2[0-9][0-9]") {
        fix_nated_contact();
        if (has_body("application/sdp")) {
            rtpproxy_answer("o");
        };

        # Is this a transaction behind a NAT and we did not
        # know at time of request processing?
    } else if (nat_uac_test("1")) {
        fix_nated_contact();
    };
    ################## NAT ######################

}

failure_route[1] {
    unforce_rtp_proxy();
}

--


I hope this saves someone some time.



Damon




More information about the Users mailing list