Kamailio e dSIPRouter davanti ad Asterisk: progettare un SBC VoIP

Guida pratica a Kamailio/dSIPRouter davanti ad Asterisk: listener SIP/TLS, routing verso PBX, RTPengine, NAT, mTLS, carrier, diagnostica e verifiche operative.

Un PBX piccolo può tranquillamente parlare direttamente con qualche telefono e con un carrier. Il problema nasce quando crescono i domini, i clienti, gli endpoint remoti, le chiamate concorrenti e le regole che devono distinguere un trunk affidabile da un telefono dietro NAT. A quel punto Asterisk rischia di diventare il posto in cui finiscono tutte le responsabilità dell’infrastruttura.

Per capire perché Kamailio è utile bisogna prima distinguere due ruoli. Asterisk è principalmente un B2BUA: termina una dialog SIP e ne crea un’altra, applicando logica telefonica, dialplan, code, interni e applicazioni. Kamailio è invece un SIP proxy/router: riceve messaggi SIP, li analizza e decide dove inviarli mantenendo un costo molto più basso per ogni transazione.

Separare il confine dalla logica telefonica

Mettere il proxy SIP davanti al PBX crea una frontiera. Internet, carrier e PBX remoti parlano con l’Edge; l’Edge decide se quella sorgente è ammessa, a quale dominio appartiene, quale backend deve ricevere la richiesta e quale policy applicare. Asterisk vede quindi un traffico molto più prevedibile e non deve conoscere tutti i dettagli del mondo esterno.

dSIPRouter non cambia il principio: fornisce un livello di gestione sopra Kamailio, utile per modellare domini, PBX/endpoint, carrier e route senza dover trasformare ogni variazione operativa in una modifica manuale del file di configurazione.

SIP non trasporta l’audio

Un’altra distinzione fondamentale è quella tra signalling e media. REGISTER, INVITE, 200 OK e BYE sono messaggi SIP. L’audio viaggia normalmente su flussi RTP separati, spesso su porte UDP dinamiche. È perfettamente possibile avere una chiamata che si instaura correttamente ma non ha audio: in quel caso il signalling ha funzionato e il problema va cercato nel percorso RTP, nell’SDP, nel NAT o nel firewall.

RTPengine entra proprio qui. Kamailio controlla la segnalazione e chiede al media proxy di riscrivere gli indirizzi SDP e di stare nel percorso dei flussi RTP. Questo è particolarmente utile quando il bordo possiede un indirizzo privato e uno pubblico, quando gli endpoint sono dietro NAT o quando dobbiamo fare bridging tra RTP e SRTP.

SBC: non soltanto “un proxy davanti”

Nel linguaggio pratico chiamiamo questo livello SBC perché svolge funzioni di confine: controllo delle sorgenti, normalizzazione, TLS, policy per carrier ed endpoint, limiti, routing e media anchoring. Non esiste però una singola direttiva che “attiva l’SBC”: è l’insieme coerente di queste funzioni a costruire il bordo.

Perché carrier ed endpoint vanno trattati diversamente

Un carrier ha indirizzi e modalità operative relativamente stabili e può essere autorizzato tramite reti note, autenticazione specifica e route dedicate. Un telefono remoto cambia rete, attraversa NAT, mantiene una registrazione, usa credenziali e può essere rubato o compromesso. Mettere entrambi nello stesso profilo significa rinunciare a informazioni che abbiamo già e che possono ridurre drasticamente la superficie di attacco.

Ora possiamo tradurre questa architettura in configurazione concreta.

Topologia

Internet / Carrier / PBX remoti
          |
          | UDP 5060 / TLS 5061
          v
Kamailio + dSIPRouter
          |
          +---- RTPengine 127.0.0.1:2223
          |
          +---- PBX backend via TCP/TLS
                  |
                  v
             Asterisk / FreePBX

Nel nostro Edge Kamailio ascolta su UDP 5060 e TLS 5061. La configurazione aggiuntiva è separata in /etc/kamailio/newvoip/tenants.cfg e /etc/kamailio/newvoip/routing.cfg.

Validare Kamailio

kamailio -c -f /etc/kamailio/kamailio.cfg
systemctl status kamailio
ss -lntup | grep -E ':5060|:5061'

Il controllo -c verifica la sintassi, non la raggiungibilità del database o dei peer.

Dominio → backend

dSIPRouter espone Domains, PBX/Endpoints, Carrier Groups, Inbound DID Mapping e Global Outbound Routes. La logica fondamentale è stabilire a quale tenant appartiene il dominio SIP e quale backend deve ricevere la richiesta. In configurazioni più articolate possiamo spostare queste informazioni in database e usarle da Kamailio tramite sqlops, dispatcher, permissions o drouting.

RTPengine

# /etc/rtpengine/rtpengine.conf
interface = 213.226.106.252!172.16.0.150
listen-ng = 127.0.0.1:2223
port-min = 30000
port-max = 40000

La sintassi pubblico!privato permette di usare l’indirizzo locale sul server ma pubblicizzare nell’SDP quello raggiungibile dall’esterno.

rtpengine_manage("replace-origin replace-session-connection");

systemctl status rtpengine
ss -lunp | grep 2223
tcpdump -ni any udp portrange 30000-40000

TLS e mTLS

Per i trunk interni possiamo usare TLS e, quando serve, autenticazione mutua a certificato. Sul lato Asterisk un transport PJSIP tipico è legato alla rete SIP e verifica il certificato del server.

bind=10.0.10.10:5061
cert_file=/etc/asterisk/keys/pbx-newvoip.crt
priv_key_file=/etc/asterisk/keys/pbx-newvoip.key
ca_list_file=/etc/ssl/certs/ca-certificates.crt
verify_server=yes

Sul bordo la CA per i client SIP può essere separata dalle CA pubbliche: un certificato TLS valido non equivale automaticamente a un client autorizzato.

openssl s_client   -connect edge.example.net:5061   -cert client.crt   -key client.key   -CAfile newvoip-sip-client-ca.crt

PBX statico, non necessariamente REGISTER

In una architettura PBX-to-Edge fidata non è obbligatorio far registrare il PBX a dSIPRouter. Un tentativo di REGISTER dal backend può ricevere 404 se l’Edge è configurato per routing statico/trusted.

asterisk -rx "pjsip show registrations"
asterisk -rx "pjsip show endpoints"
asterisk -rx "pjsip show endpoint Linea_Principale"

Carrier, ACL e antifrode

Carrier ed endpoint non devono condividere automaticamente la stessa policy. I carrier possono avere allowlist IP e route dedicate; gli endpoint remoti hanno autenticazione, NAT, limiti e profili antifrode. Prima del provisioning conviene verificare DNS, raggiungibilità, certificati, ACL e profilo associato.

Diagnostica

# Segnalazione in chiaro
ngrep -d any -W byline port 5060

# TLS
tcpdump -ni any tcp port 5061

# Media
tcpdump -ni any udp portrange 30000-40000

# Log
journalctl -u kamailio -f
journalctl -u rtpengine -f

Un INVITE che non raggiunge Asterisk è un problema di routing SIP. Una chiamata che si instaura ma ha audio monodirezionale porta invece a controllare SDP, NAT, RTPengine e firewall sul range RTP.

Riferimenti

Kamailio Documentation · dSIPRouter · RTPengine manual.