Talvolta può accadere di dover interconnettere un pre-esistente centralino Asterisk che serviva un solo ufficio (con la sua rete interna e relativa numerazione 1xx) alla rete VoIP aziendale. Per limitare quanto più possibile i disagi sia all’utenza che ai colleghi, ho ritenuto importante cercare di mantenere comunque la numerazione interna pre-esistente e di implementare sul server Asterisk un trunk SIP di interconnessione con il router VoIP OpenSIPS.
La topologia di rete in cui mi sono trovato ad operare è la seguente:
Topologia di Rete
Le connessioni in colore blu sono telefoniche mentre quelle in nero sulla rete TCP/IP di Ateneo.
Dal lato Asterisk la configurazione del trunk è stata piuttosto semplice. Nel file sip.conf (generalmente nella directory /etc/asterisk/) si aggiunge la configurazione:
[VOIP] disallow=all type=peer nat=yes qualify=yes fromdomain=voip.unisi.it host=voip.unisi.it insecure=port,invite allow=alaw context=from-trunk-sip-VOIP
Avendo sul PBX Asterisk installato FreePBX, è stato ancora più facile: direttamente dal pannello di amministrazione si crea un nuovo “Trunk SIP” e la relativa “Outbound Route”, per dire al sistema quale dialpattern deve utilizzare per questo trunk “VOIP” (nel mio caso, tutti i numeri che iniziano con 50xx e 51xx):
- Aggiungi nuovo SIP trunk
- Imposta i parametri del trunk
- Configura la route di uscita verso il trunk
Sul router VoIP OpenSIPS, utilizzano i moduli drouting e dialplan, aggiungo sulle relative tabelle MySQL le impostazioni relative al gateway SIP. Anche in questo caso devo definire un pattern per reindirizzare le chiamate provenienti dai terminali della rete VoIP aziendale verso gli interni dell’ufficio gestito dal PBX Asterisk. In questo caso ho scelto il numero ’7′ come selezione per il trunk, pertanto per chiamare l’interno ’101′ dovrò digitare ’7101′ e via dicendo…
Vediamo come fare, premettendo che OpenSIPS deve essere correttamente configurato e funzionante, con i moduli drouting e diaplan caricati e configurati (opensips.cfg):
#### DYNAMIC ROUTING module loadmodule "drouting.so" modparam("drouting", "db_url", "mysql://[credenziali MySQL ]@[host MySQL]/opensips") modparam("drouting", "use_domain", 1) modparam("drouting", "probing_interval", 60) modparam("drouting", "probing_from", "sip:[email protected]") modparam("drouting", "probing_method", "OPTIONS") modparam("drouting", "probing_reply_codes", "501, 403, 404") #### DIALPLAN module loadmodule "dialplan.so" modparam("dialplan", "db_url", "mysql:///[credenziali MySQL ]@[host MySQL]/opensips") modparam("dialplan", "attrs_pvar", "$avp(dest)")
OpenSIPS Dialplan table
Nella tabella “diaplan” definiamo subito la regexp della numerazione ’7′, che nel campo match_exp sarà ‘^7[1-9][0-9].*‘ e nel campo ‘attrs’ definisco la route di uscita, ‘trunkmed’.
Si può fare anche in altri modi ma ho deciso di utilizzare questo stratagemma per impostare la variabile $avp(‘attrs’) con il nome della route al quale reindirizzare le chiamate dirette verso questo pattern, così che nella configurazione di OpenSIPS limito al minimo i trunk “hardcoded”. Successivamente, grazie alla funzione dp_translate del modulo dialplan, imposto l’avp:
if(!dp_translate("0", "$rU/$rU")) { xlog("L_ERR","420 - Invalid destination $rU\n"); sl_send_reply("420","Invalid Destination"); exit; } xlog("Context for $rU is $avp(dest)\n");
e poi:
if($avp(dest)=="trunkmed") { route(trunkmed); }
a questo punto entra in gioco il modulo drouting, che con la funzione route_to_carrier è molto comodo nel caso di più gateways ed una configurazione complessa:
route[trunkmed] { xlog("L_INFO","Route TRUNK MEDICINA [$fd/$fu/$rd/$ru/$si/]\n"); if(route_to_carrier("trunkmed")) { t_on_failure("next_gw"); t_relay(); exit; } }
OpenSIPS dr_carriers table
La configurazione di quest’ultimo modulo è però un pò più complessa. Si tratta di definire una serie di “carrier”, nella tabella dr_carriers, dove definire sia l’ID (carrierid) che l’elenco (separato da virgole) dei gateways relativi (gwlist).
Nel nostro caso definisco l’id “trunkmed” e come unico gateway “trunkmed1“.
OpenSIPS dr_gateways table
Adesso andiamo ad impostare il gateway, nella tabella dr_gateway, dove inserisco l’ID nel capo gwid “trunkmed1” e l’IP dell’PBX Asterisk nel campo “address“. Considerando che devo anche togliere dalla selezione la prima cifra (ricordate il ’7′ di selezione ?), nel campo “strip” inserisco “1“.
Abbiamo quasi finito. Adesso nella tabella dr_rules che, come dal manuale “Using different criterias (prefix, time, priority, etc), they will decide to which gateways the call will be sent.”, definiamo i criteri di uso di questa route.
OpenSIPS dr_rules table
Nel campo groupid inserisco l’ID del trunk “trunkmed“, in prefix indico il prefisso di pre-selezione “7” e nell’elenco dei gateway gwlist riporto “trunkmed1“.
Adesso riavviamo il demone opensips (“/etc/init.d/opensips restart“) e verifichiamo sul log (“/var/log/opensips.log”) la corretta impostazione del trunk verso il PBX Asterisk:
proxy-voip01: Context for 7119 is trunkmed proxy-voip01: Route TRUNK MEDICINA [voip.unisi.it/sip:[email protected]:5060/voip.unisi.it/sip:[email protected]:5060;user=phone/172.20.1.10/]
Ovviamente anche dal lato del PBX Asterisk dovrò vedere qualcosa in ingresso:
-- Executing [119@from-trunk-sip-VOIP:1] Set("SIP/VOIP-0000063e", "GROUP()=OUT_3") in new stack -- Executing [119@from-trunk-sip-VOIP:2] Goto("SIP/VOIP-0000063e", "from-trunk|119|1") in new stack
Et voilà, il vostro collegamento tra il PBX Asterisk ed il router OpenSIPS ha avuto successo !
Ricapitolando, ecco il flusso delle segnalazioni SIP che potete verificare su ogni gateway (Asterisk ed OpenSIPS):
Nel caso il flusso della segnalazione SIP sia corretto (“tcpdump -A -i eth0 -n “dst port 5060 or src port 5060″” è vostro amico) ma non riusciate a sentire nulla, probabilmente il firewall blocca i pacchetti RTP: verificate che le porte UDP dalla 10000 alla 20000 (default di Asterisk, su rtp.conf) siano aperte.
Ultima raccomandazione, visto che ho perso ore dietro questo inconveniente, assicuratevi che nella configurazione di OpenSIPS ci sia, tra i parametri globali, la riga:
mhomed=yes
che forza il riconoscimento automatico della corretta interfaccia di rete per il routing dei messaggi SIP (nel caso aveste più di una interfaccia di rete, es. pubblica/privata).
Ovviamente questo tutorial è frutto della mia esperienza pertanto potrebbe non funzionare nel vostro contesto, contenere errori o inesattezze. Sentitevi liberi di segnalare eventuali problemi o errori.
Nella foto: SNOM 760 VoIP Phone