Communication between the User Agent and the home proxy is encrypted using TLS.
We enable end-users of domain A to communicate with their home proxy based on TLS:
User Agent A -> proxy domainA
This example is based on
Note that the compiled version puts openser in different directory compared to the openser package. The config file is in |
This example config shows the necessary minimal elements:
#----------- global configuration parameters ----------------------- debug=3 fork=yes log_stderror=no children=4 sip_warning=yes # disable these if you do not allow UDP. UDP is obligatory # in the SIP RFC listen=<sip server IP address> port=5060 disable_tls = 0 listen = tls:<sip server IP address>:5061 tls_verify_server = 1 tls_verify_client = 1 tls_require_client_certificate = 0 tls_method = TLSv1 tls_certificate = "/usr/local/etc/openser/tls/user/user-cert.pem" tls_private_key = "/usr/local/etc/openser/tls/user/user-privkey.pem" tls_ca_list = "/usr/local/etc/openser/tls/user/user-calist.pem" alias="domainA.net" mpath="/usr/local/lib/openser/modules/" loadmodule "mysql.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_db.so" loadmodule "auth.so" loadmodule "auth_db.so" loadmodule "xlog.so" loadmodule "tlsops.so" # ----------------- setting module-specific parameters --------------- modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo") # change the read-write mysql account password and adjust this line: modparam("usrloc", "db_mode", 2) modparam("usrloc", "db_url", "mysql://openser:openserrw@localhost/openser") # change the read-only mysql account password and adjust this line: modparam("auth_db", "db_url", "mysql://openserro:openserro@localhost/openser") modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password") 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"); exit; }; if (msg:len >= 2048 ) { sl_send_reply("513", "Message too big"); exit; }; # if somene claims to belong to our domain in From, # challenge him (skip REGISTERs -- we will chalenge them later) if (from_uri==myself) { setflag(1); if ( (method=="INVITE" || method=="SUBSCRIBE" || method=="MESSAGE") && !(src_ip==myself) ) { if (!(proxy_authorize("domainA", "subscriber" ))) { proxy_challenge("domainA","0"); exit; }; if (!check_from()) { log("LOG: From Cheating attempt in INVITE"); sl_send_reply("403", "That is ugly -- use From=id next time (OB)"); exit; }; }; } else if ( method=="INVITE" && uri!=myself ) { sl_send_reply("403", "No relaying"); exit; }; # 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(); #extra TLS testing and logging, tlsops module needed if (proto==TLS) { if (is_peer_verified()) { xlog("L_INFO","request from verified TLS peer RM [$rm] RU [$ru] From[$fu] TO[$tu] \n"); xlog("L_INFO","$$tls_peer_subject_cn = '$tls_peer_subject_cn'\n"); xlog("L_INFO","$$tls_peer_issuer_cn = '$tls_peer_issuer_cn'\n"); } else { xlog("L_INFO","request not verified [$rm] ru[$ru] fu[$fu] \n"); } } # 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); }; # check for requests targeted out of our domain # see recipe on proxy-proxy TLS # if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri==myself) { if (method=="REGISTER") { # digest authentication if (!www_authorize("domainA", "subscriber")) { www_challenge("domainA", "0"); exit; }; save("location"); exit; }; lookup("aliases"); if (!uri==myself) { append_hf("P-hint: outbound alias\r\n"); route(1); }; }; route(1) } route[1] { if (!t_relay()) { sl_reply_error(); }; exit; } |
Make sure that the certificate chain (CA list) is installed on the UA. For instance, when using Eyebeam 1.5 under MS Windows, import the chain (in PEM format with file extension .cer) into the windows certificate store by double clicking.
Configure a UA to use TLS. Under MS Windows, good examples are Eyebeam 1.5 or Phoner. Make sure to choose 'TLS' as the protocol in the settings and register with the proxy. Use the diagnostic tools of the UA to see if any problems occur. Common problems are:
Reminder: this example is based on a compiled version of openSER where the config is in /usr/local/etc/openser and the certificates are in /usr/local/etc/openser/tls/user, which might differ when installed from packages.
This recipe is based on the tutorial in http://www.voipuser.org/forum_topic_7222.html with adjustments for the openser version. See also http://www.openser.org/docs/tls.html#TLS-EXAMPLE for hints on TLS and examples of how to differentiate ring tones of the UA based on the source of a call to let the end-user know if the call can be trusted or not.