Interconnettere un pre-esistente PBX Asterisk ad OpenSIPS

Attenzione ! Questo articolo è stato scritto più di due anni fa. Ti prego quindi di considerare che le informazioni riportate potrebbero non essere aggiornate o non più valide.

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:

voip_network

Topologia di Rete

Le connessioni in colore blu sono telefoniche mentre quelle in nero sulla rete TCP/IP di Ateneo.

[sociallocker]

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):

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:pinger@172.20.1.4")
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

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

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

OpenSIPS dr_gateways table

Adesso andiamo ad impostare il gateway, nella tabella dr_gateway, dove inserisco l’ID nel capo gwidtrunkmed1” 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 manualeUsing 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

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:5001@voip.unisi.it:5060/voip.unisi.it/sip:7119@voip.unisi.it: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):

voip_call_flow

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).

[/sociallocker]

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

Michele Pinassi

Blogger, appassionato di tecnologia, società e politica. Attualmente Responsabile del Sistema telefonico di Ateneo presso l'Università degli Studi di Siena ed esperto di sicurezza informatica nello staff del DPO. Utilizza quasi esclusivamente software libero.

Potrebbero interessarti anche...

Rispondi

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

%d blogger hanno fatto clic su Mi Piace per questo: