I have been trying to configure SER w/MediaProxy module/server to be a
drop in NAT solution in front of asterisk. With the twist that I want
to have asterisk continue acting as a registrar rather than SER.
Outbound calls from natted clients works perfectly currently. The
problem I'm having is with SER passing the REGISTERS through to
asterisk. SER/MP isn't rewriting the address in the packets to go back
through SER, but instead sets it to be the NAT'd IP of the client.
So, when asterisk receives a call, and tries to send it to the external
nat'd IP of the client, there is no open session from asterisk, so the
firewall denies the request.
What I need to happen, is for SER/MP to rewrite the packet with it's own
IP, so that asterisk sends it back to SER, and SER forwards it back down
to the client, from a source IP which has an open firewall session.
Any help would be greatly appreciated, hopefully it's just a matter of
me having an extraneous function call somewhere, or being ignorant of
the right function to use.
Or, in ascii diagram form:
NAT_IP client --- EXTERNAL_FW_IP ----- SER_IP ----- ASTERISK
SER is giving asterisk the EXTERNAL_FW_IP for Registers, and I want it
to give Asterisk the SER IP.
Something that would make SER rewrite *all* register packets to it's own
IP would even work, since clients that don't need NAT won't be sent to
SER in the first place.
My ser.cfg and mediaproxy.ini follow. Lemme know if you need any more
info from me. And extra thanks to anyone who has taken the time reading
this, I truly appreciate it.
kyle.
# ### ser.cfg ###
#
# ----------- global configuration parameters ------------------------
debug=3 # debug level (cmd line: -dddddddddd)
fork=yes
log_stderror=no # (cmd line: -E)
/* Uncomment these lines to enter debugging mode
fork=no
log_stderror=yes
*/
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
port=5070
#children=4
fifo="/tmp/ser_fifo"
#fifo_db_url="mysql://ser:ser/ser"
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/dbtext.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
#loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
loadmodule "/usr/local/lib/ser/modules/domain.so"
# !!! Media Proxy
loadmodule "/usr/local/lib/ser/modules/mediaproxy.so"
#modparam("mediaproxy", "mediaproxy_socket",
"/var/run/proxydispatcher.sock")
modparam("mediaproxy", "mediaproxy_socket",
"/var/run/mediaproxy.sock")
#modparam("mediaproxy", "sip_asymmetrics",
"/usr/local/etc/ser/sip-asymmetric-clients")
#modparam("mediaproxy", "rtp_asymmetrics",
"/usr/local/etc/ser/rtp-asymmetric-clients")
modparam("mediaproxy", "natping_interval", 20)
# ----------------- setting module-specific parameters ---------------
# -- usrloc params --
modparam("usrloc", "db_mode", 0)
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# ------------------------- request routing logic -------------------
# main routing logic
route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
break;
};
if (msg:len >= max_len ) {
sl_send_reply("513", "Message too big");
break;
};
if (client_nat_test("3")) {
# Allow RR-ed requests, as these may indicate that
# a NAT-enabled proxy takes care of it; unless it is
# a REGISTER
fix_contact(); # Rewrite contact with source IP of signalling
force_rport(); # Add rport parameter to topmost Via
setflag(6); # Mark as NATed
# use_media_proxy();
};
# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
# if (!method=="REGISTER") record_route();
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);
break;
};
if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
break;
};
route(1);
}
route[1]
{
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");
break;
};
# if client or server know to be behind a NAT, enable relay
if (isflagset(6)) {
use_media_proxy();
};
# NAT processing of replies; apply to all transactions (for example,
# re-INVITEs from public to private UA are hard to identify as
# NATed at the moment of request processing); look at replies
t_on_reply("1");
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
onreply_route[1] {
# NATed transaction ?
if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
use_media_proxy();
# otherwise, is it a transaction behind a NAT and we did not
# know at time of request processing ? (RFC1918 contacts)
} else if (client_nat_test("1")) {
fix_contact();
use_media_proxy();
};
}
;
; Configuration file for MediaProxy
;
[Dispatcher]
start = yes
socket = /var/run/proxydispatcher.sock
;group = ser
defaultProxy = /var/run/mediaproxy.sock
[MediaProxy]
start = yes
socket = /var/run/mediaproxy.sock
;group = ser
;listen = None
;allow = None
;proxyIP = 127.0.0.1
portRange = 35000:65000
;TOS = 0xb8
;idleTimeout = 60
;holdTimeout = 3600
;forceClose = 0
accounting = off
[Accounting]
user = dbuser
password = dbpass
host = dbhost
database = radius
table = radacct