Hi Jerry,
            I just joined so am unsure if you are good to go now but thought I would post my config as I also have a Freeswitch environment which I have placed Kamailio in front of to act as a load-balancing proxy. I also managed to get RTPEngine proxying through it too.


Here is the config, which I have created from Daniel’s default kamailio config.  I have omitted the top portions of loading the modules and their settings. My dispatcher list is just a text file. I have two groups. One for registrations and outbound calls, and one for calls inbound coming from the FreeSwitch server.

In the NATMANAGE route, I currently have RTP proxying disabled as my free switch servers have external IPs and I let them handle the rtp stream.

On Freeswitch, I made the following changes to accomodate user/pass and IPAuth reg:

Changes to the Freeswitch servers listed in the dispatcher file

Edit /usr/local/freeswitch/conf/autoload_configs/acl.conf

<list name="proxy" default="deny">
     <node type="allow" cidr=“IP address of Kamailio/32"/>
   </list>


Edit /usr/local/freeswitch/conf/sip-profiles/internal-private.xml    (or the sip-profile you need to edit in your instance)

<param name="apply-proxy-acl" value="proxy"/>  #Add this line above the one below. This tells Freeswitch to look at the X-Auth-IP header which was inserted by Kamailio.
  
<param name="apply-inbound-acl" value="domains"/>

Then, restart freeswitch (with no active calls),

service freeswitch restart     # or rescan the profile / reloadxml


I am not proxying RTP, however, I can un-comment out the stanza in the NATMANAGE route to get it to work.



The biggest gotcha for me was I was trying to use fix_nated_register when handling NAT for registrations instead of:

Fix_nated_contact() or the better set_contact_alias().

Using add_path_received(); in the Dispatcher just before sending to Freeswitch ensured all traffic returned to Kamailio too.

I am unsure of the SUBSCRIBE/PRESENCE stuff for you but the route should go out via the Kamailio proxy with this.


----------------------------
# main request routing logic

request_route {

xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
# per request initial checks
route(REQINIT);

# NAT detection
route(NATDETECT);

    if(ds_is_from_list("33")) {
    setflag(FLT_FS);
    #xlog("L_WARN", "This source $si is from the dispatcher list.\n");
     }

# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
}
exit;
}

# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}

# handle requests within SIP dialogs
route(WITHINDLG);

# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE")) {
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
xlog("L_ALERT", "Marker 1\n");
record_route();
}

# account only INVITEs
if (is_method("INVITE")) {
setflag(FLT_ACC); # do accounting
}


if (isflagset(FLT_FS)) {
                ##t_on_reply("EXTERNAL_REPLY");
                route(FROM_FS);
                exit;
        }

# handle presence related requests
route(PRESENCE);

# handle registrations
route(REGISTRAR);

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

# dispatch destinations
route(DISPATCH);

return;
}

route[FROM_FS]
{
        #record_route();
#loose_route_preloaded();
route(DLGURI);
        route(RELAY);
        exit;
}

route[RELAY] {

# enable additional event routes for forwarded requests
# - serial forking, RTP relaying handling, a.s.o.
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}

if (!t_relay()) {
sl_reply_error();
}
exit;
}

#reply_route {
#    if(status == 403) {
#        xlog("L_WARN", "Forbidden from $si:$sp blah...\n");
# xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
#    }
#}

onreply_route[LOGRPL] {
      if(status == 403) {
  xlog("L_ALERT", "$rs response. Consider banning AVP \"ipbancandidate\" is $avp(ipbancandidate) ");
      }
}

# Per SIP request initial checks
route[REQINIT] {
# no connect for sending replies
# Enable tracing for SNGREP
##sip_trace();
##setflag(24);
#
set_reply_no_connect();
# enforce symmetric signaling
# - send back replies to the source address of request
force_rport();

#!ifdef WITH_ANTIFLOOD
# flood detection from same IP and traffic ban for a while
# be sure you exclude checking trusted peers, such as pstn gateways
# - local host excluded (e.g., loop to self)
if(src_ip!=myself) {
if($sht(ipban=>$si)!=$null) {
# ip is already blocked
xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
exit;
}
if (!pike_check_req()) {
xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
$sht(ipban=>$si) = 1;
exit;
}
}
#!endif
if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent|pplsip|Hello\ SIP\ Automated") {
# silent drop for scanners - uncomment next line if want to reply
# sl_send_reply("200", "OK");
        xlog("User agent is: $ua\n");
exit;
}

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

if(is_method("OPTIONS") && uri==myself && $rU==$null) {
sl_send_reply("200","Keepalive");
exit;
}

if(!sanity_check("17895", "7")) {
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
}

# Handle requests within SIP dialogs
route[WITHINDLG] {

if (!has_totag()) return;

# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
  xlog("L_INFO", "Routing before DLGURI\n");
route(DLGURI);
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
} else if ( is_method("ACK") ) {
# ACK is forwarded statelessly
route(NATMANAGE);
} else if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
exit;
}

if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(PRESENCE);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
route(RELAY);
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
exit;
}


# Handle SIP registrations
route[REGISTRAR] {
if(!is_method("REGISTER"))
return;
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
add_path_received();
$avp(ipbancandidate) = $si;
if(isflagset(FLT_NATS)) {
setbflag(FLB_NATB);
#!ifdef WITH_NATSIPPING
# do SIP NAT pinging
setbflag(FLB_NATSIPPING);
#!endif
}
        route(DISPATCH);
if (!save("location")) {
sl_reply_error();
}
exit;
}

# Presence server route
route[PRESENCE] {
if(!is_method("PUBLISH|SUBSCRIBE"))
return;

sl_send_reply("404", "Not here");
exit;
}


# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
        if (nat_uac_test("19")) {
                if (is_method("REGISTER")) {
                        #fix_nated_register(); Disabled as we proxy registrations
                        #fix_nated_contact();
set_contact_alias();
##add_contact_alias();
#fix_nated_sdp("3");
xlog("L_ALERT", "Nat Registration nat fixed.\n");
                } else {
                        if(is_first_hop()) {
                                set_contact_alias();
xlog("L_ALERT", "Contact NAT fixed\n");
                       
}
                setflag(FLT_NATS);
xlog("L_ALERT", "FLT_NATS flag set\n");
       } 
#!endif
        return;
}

# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
#!ifdef WITH_NAT
if (is_request()) {
if(has_totag()) {
if(check_route_param("nat=yes")) {
setbflag(FLB_NATB);
}
}
}
if (nat_uac_test("3")) {
            #fix_nated_contact();
    set_contact_alias();
    ##add_contact_alias();
            force_rport();
        }
if (has_body("application/sdp") && nat_uac_test("8")) {
            fix_nated_sdp("11");
        }

if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;

###!ifdef WITH_RTPENGINE
## xlog("RTPEngine enabled\n");
## if(nat_uac_test("8")) {
## xlog("RTP 1\n");
## rtpengine_manage("SIP-source-address replace-origin replace-session-connection");
## } else {
## rtpengine_manage("replace-origin replace-session-connection");
## }
###!else
## if(nat_uac_test("8")) {
## rtpproxy_manage("co");
## } else {
## rtpproxy_manage("cor");
## }
###!endif

if (is_request()) {
if (!has_totag()) {
if(t_is_branch_route()) {
add_rr_param(";nat=yes");
xlog("Nat notation added!\n");
}
}
}
if (is_reply()) {
if(isbflagset(FLB_NATB)) {
if(is_first_hop())
#fix_nated_contact();
set_contact_alias();
#add_contact_alias();
}
}

if(isbflagset(FLB_NATB)) {
# no connect message in a dialog involving NAT traversal
if (is_request()) {
if(has_totag()) {
set_forward_no_connect();
}
}
}
#!endif
return;
}

# URI update for dialog requests
route[DLGURI] {
#!ifdef WITH_NAT
if(!isdsturiset()) {
handle_ruri_alias();
xlog("L_INFO", "Routing in-dialog $rm from $fu to $du\n");
}
#!endif
return;
}

# Dispatch requests
route[DISPATCH] {
# round robin dispatching on gateways group '1'
remove_hf_re("Subject|P-.*|X-.*");
        append_hf("X-Auth-IP: $si\r\n");
#add_rr_param(";nat=yes");
t_on_reply("LOGRPL");
if(!ds_select_dst("1", "0")) {
send_reply("404", "No destination");
exit;
}
#xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si; $RAi; $Ri;\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
}

# Try next destionations in failure route
failure_route[RTF_DISPATCH] {
if (t_is_canceled()) {
exit;
}
# next DST - only for 500 or local timeout
if (t_check_status("500")
or (t_branch_timeout() and !t_branch_replied())) {
if(ds_next_dst()) {
xdbg("--- SCRIPT: retrying to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
}
}

# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");
xlog("L_ALERT", "Marker 20\n");
route(NATMANAGE);
return;
}

# Manage incoming replies
reply_route {
if(!sanity_check("17604", "6")) {
xlog("Malformed SIP response from $si:$sp\n");
drop;
}
return;
}

# Manage incoming replies in transaction context
onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
xlog("L_ALERT", "Marker 21\n");
if(status=~"[12][0-9][0-9]") {
route(NATMANAGE);
}
# if (has_body("application/sdp")) {
#                rtpengine_manage();
#        }
return;
}

# Manage failure routing cases
failure_route[MANAGE_FAILURE] {
xlog("L_ALERT", "Marker 23\n");
route(NATMANAGE);

if (t_is_canceled()) exit;

#!ifdef WITH_BLOCK3XX
# block call redirect based on 3xx replies.
if (t_check_status("3[0-9][0-9]")) {
t_reply("404","Not found");
exit;
}
#!endif

#!ifdef WITH_BLOCK401407
# block call redirect based on 401, 407 replies.
if (t_check_status("401|407")) {
t_reply("404","Not found");
exit;
}
#!endif

#!ifdef WITH_VOICEMAIL
# serial forking
# - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
$du = $null;
route(TOVOICEMAIL);
exit;
}
#!endif
return;
}