SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

Server VoIP self-hosted: Asterisk o FreePBX

Configura Asterisk o FreePBX su un VPS: trunk SIP, porte RTP, regole firewall contro gli scanner e segnali di toll fraud prima che generi costi.

Che cos’è un server VoIP self-hosted

Un server VoIP self-hosted è un server SIP eseguito su un VPS sotto il tuo controllo. Le chiamate vengono quindi instradate dalla tua macchina, invece che da un servizio telefonico in hosting. VoIP (voice over IP) trasporta la voce sotto forma di pacchetti UDP. SIP (session initiation protocol) è il protocollo di segnalazione che avvia e termina una chiamata. L’audio non passa attraverso SIP. Questo fatto è all’origine della maggior parte dei problemi descritti di seguito.

Per ottenere un sistema funzionante servono quattro componenti.

  • Il software PBX (private branch exchange). Asterisk è la scelta più comune. Gestisce gli interni e il dialplan.
  • Gli endpoint. Sono telefoni da scrivania o softphone che si registrano al PBX con un nome utente e un secret.
  • Il trunk SIP. È un account a pagamento presso un provider che collega il sistema alla rete telefonica pubblica e assegna numeri di telefono reali.
  • Il percorso multimediale. I flussi RTP (real-time transport protocol) trasportano l’audio usando porte UDP proprie.

Gestire il PBX in self-hosting non significa gestire anche i numeri di telefono in self-hosting. I numeri vengono forniti da un carrier, e continui a pagare per ogni numero e per ogni minuto. Quello che controlli sono l’instradamento delle chiamate, la segreteria telefonica, le registrazioni e l’elenco degli interni. Sei inoltre responsabile della sicurezza di un servizio che gli aggressori prendono di mira per ottenere denaro.

Quali porte richiede un server VoIP self-hosted?

La segnalazione SIP usa la porta 5060 per UDP e TCP e la porta 5061 per SIP over TLS (Transport Layer Security). Queste porte gestiscono soltanto l’impostazione delle chiamate. L’audio di ogni chiamata usa un flusso UDP separato, inviato a una porta scelta dall’intervallo RTP. Asterisk include un esempio rtp.conf che imposta rtpstart=10000 e rtpend=20000; i valori predefiniti incorporati sono 5000 e 31000. Ogni chiamata usa due porte di questo intervallo: una per RTP e una per RTCP (RTP Control Protocol).

È questa separazione a causare la maggior parte dei problemi nei primi tentativi. La chiamata viene stabilita, entrambi i telefoni la mostrano come risposta, ma nessuno sente l’interlocutore perché il firewall consente 5060 e scarta tutti i pacchetti RTP. Segnalazione e media usano flussi separati, quindi richiedono regole firewall separate. Se questa distinzione non è ancora chiara, vale la pena leggere come funzionano le porte e i socket in ascolto su Linux prima di aprire qualsiasi porta.

Riduci l’intervallo prima di aprirlo. Ventimila porte sono molte più di quelle necessarie a un sistema di piccole dimensioni. Poiché ogni chiamata usa due porte, un intervallo di duecento porte consente di gestire contemporaneamente cento chiamate.

[general]
rtpstart=10000
rtpend=10200

Applica la configurazione con sudo asterisk -rx "core reload".

È meglio installare Asterisk o FreePBX?

Asterisk è il motore. Si configura tramite file di testo in /etc/asterisk e il dialplan viene scritto manualmente. FreePBX è un'interfaccia web scritta in PHP e JavaScript che opera sopra Asterisk, genera quei file e aggiunge moduli per la segreteria telefonica e le code di chiamata.

Su un VPS, la differenza importante riguarda chi controlla il server. Ad agosto 2026, il programma di installazione ufficiale di FreePBX 17 si aspetta un sistema Debian 12 minimale e installa Asterisk, un web server, un database server e PHP. Se lo si esegue su un server che fornisce già altri servizi, il risultato sarà problematico. Dedicate a FreePBX un VPS separato.

wget https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh -O /tmp/sng_freepbx_debian_install.sh
sudo bash /tmp/sng_freepbx_debian_install.sh

Il log dell'installazione viene salvato in /var/log/pbx/freepbx17-install.log. È il primo file da controllare quando lo script si interrompe nelle fasi iniziali.

FreePBX controlla i file di configurazione che genera. Se modificate manualmente pjsip.conf su un server FreePBX, la modifica scompare la volta successiva che la GUI scrive quel file. FreePBX legge i file separati che contengono _custom nel nome per la configurazione scritta manualmente e non li modifica.

Il compromesso è chiaro. FreePBX offre una GUI e pubblica su Internet una pagina di accesso al sistema telefonico. Asterisk senza FreePBX non espone alcuna interfaccia web. Ogni impostazione è una direttiva documentata, leggibile in un file e archiviabile in git. Se installate FreePBX, limitate l'accesso alla sua porta web al vostro indirizzo IP oppure accedete tramite una VPN. Una GUI amministrativa per un PBX è un obiettivo che consente di raggiungere direttamente sistemi e risorse con implicazioni economiche.

Nota sulle versioni, aggiornata ad agosto 2026: Asterisk 22 è la versione corrente con supporto a lungo termine, pubblicata a ottobre 2024 e con aggiornamenti di sicurezza previsti fino a ottobre 2028. Asterisk 23 è la versione standard. Ubuntu 24.04 include Asterisk 20.6.0 nel repository universe.

Installare Asterisk su Ubuntu 24.04

Il pacchetto della distribuzione è il percorso più rapido. Ubuntu lo aggiorna con le proprie patch e lo avvia automaticamente tramite systemd.

sudo apt update
sudo apt install -y asterisk
sudo asterisk -rx "core show version"

La compilazione dal codice sorgente consente invece di usare la versione corrente con supporto a lungo termine.

sudo apt update
sudo apt install -y build-essential wget
cd /usr/local/src
sudo wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
sudo tar -xzf asterisk-22-current.tar.gz
cd asterisk-22.*
sudo contrib/scripts/install_prereq install
sudo ./configure
sudo make menuselect
sudo make -j"$(nproc)"
sudo make install
sudo make samples
sudo make config
sudo ldconfig

install_prereq install installa le dipendenze di compilazione per la distribuzione in uso, mentre install_prereq test mostra i comandi che verrebbero eseguiti senza apportare modifiche. make menuselect apre il selettore dei moduli, in cui è possibile abilitare codec_opus nella sezione Codec Translators. Esegui make samples solo su una nuova installazione, perché scrive la configurazione di esempio in /etc/asterisk. make config installa lo script di init in /etc/init.d/asterisk e systemd lo gestisce tramite il proprio livello di compatibilità SysV; quindi sudo systemctl enable --now asterisk funziona successivamente.

Indipendentemente dal percorso scelto, sudo asterisk -rvvv si collega al daemon in esecuzione e fornisce la CLI. Eseguendo core show version al suo interno viene mostrato ciò che è stato effettivamente installato.

Configurare un trunk SIP e un interno

PJSIP è il driver di canale SIP nelle versioni attuali di Asterisk. La sua configurazione si trova in /etc/asterisk/pjsip.conf ed è composta da piccole sezioni tipizzate che si richiamano tra loro per nome. Le sezioni di tipo diverso possono condividere lo stesso nome, per questo ogni blocco riportato di seguito si chiama mytrunk.

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0

[mytrunk]
type=registration
outbound_auth=mytrunk
server_uri=sip:sip.example.com
client_uri=sip:1234567890@sip.example.com
retry_interval=60

[mytrunk]
type=auth
auth_type=userpass
username=1234567890
password=REPLACE_WITH_A_LONG_RANDOM_SECRET

[mytrunk]
type=aor
contact=sip:sip.example.com:5060

[mytrunk]
type=endpoint
context=from-trunk
disallow=all
allow=ulaw
outbound_auth=mytrunk
aors=mytrunk

[mytrunk]
type=identify
endpoint=mytrunk
match=sip.example.com

L'oggetto registration invia il REGISTER che comunica al provider dove consegnare le chiamate. L'oggetto identify consente di associare a questo endpoint una chiamata proveniente dal provider in base all'indirizzo sorgente; in genere il provider pubblica diversi indirizzi da inserire in quell'elenco. La registrazione in uscita e l'endpoint sono oggetti distinti intenzionalmente: il primo comunica al provider dove ti trovi, il secondo stabilisce come gestire le chiamate.

Un telefono da scrivania richiede altri tre oggetti.

[6001]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth6001
aors=6001
direct_media=no

[auth6001]
type=auth
auth_type=userpass
username=6001
password=REPLACE_WITH_A_LONG_RANDOM_SECRET

[6001]
type=aor
max_contacts=1

direct_media=no mantiene Asterisk nel percorso dei flussi multimediali. Se lo ometti, Asterisk tenterà di fare in modo che i due endpoint inviino direttamente i pacchetti RTP tra loro. Questa configurazione non funziona quando il telefono si trova dietro il NAT (network address translation) del router domestico. Non usare mai come secret lo stesso valore del numero dell'interno. L'esempio upstream usa password=6001 per l'interno 6001, così il codice resta leggibile, ma gli scanner provano per primi esattamente questo schema.

Il dialplan in /etc/asterisk/extensions.conf stabilisce quali operazioni ogni contesto può eseguire.

[internal]
exten => 6001,1,Dial(PJSIP/6001,20)
exten => _9X.,1,Dial(PJSIP/${EXTEN:1}@mytrunk,60)

[from-trunk]
exten => 1234567890,1,Dial(PJSIP/6001,20)
same => n,Hangup()

Questi due contesti costituiscono un confine di sicurezza. from-trunk gestisce le chiamate provenienti dal provider e può far squillare soltanto l'interno 6001. Non può raggiungere il pattern _9X., quindi una chiamata esterna non può comporre un numero in uscita attraverso il tuo trunk. Se unisci i contesti, crei il percorso classico per le frodi telefoniche: un estraneo chiama il tuo numero, il dialplan effettua una chiamata in uscita usando il tuo account e il costo viene addebitato a te.

Applica la configurazione e controllala.

sudo asterisk -rx "pjsip reload"
sudo asterisk -rx "pjsip show registrations"
sudo asterisk -rx "pjsip show endpoints"

pjsip show registrations dovrebbe elencare mytrunk con lo stato Registered. Rejected significa che il provider ha rifiutato le tue credenziali. Unregistered significa che il tuo REGISTER non riceve risposta; controlla quindi il firewall.

Regole firewall per SIP e RTP

La segnalazione e il traffico multimediale richiedono trattamenti diversi perché presentano rischi differenti. Limitare la porta 5060 agli indirizzi effettivamente utilizzati dal provider e alle reti in cui si trovano i telefoni.

sudo ufw allow proto udp from 203.0.113.10 to any port 5060
sudo ufw allow proto tcp from 203.0.113.10 to any port 5060
sudo ufw allow 10000:10200/udp
sudo ufw status verbose

L'intervallo RTP è la parte che non si può restringere altrettanto, perché il traffico multimediale spesso proviene da un indirizzo diverso da quello della segnalazione. Chiedere al provider quali sono le subnet utilizzate per i media e limitarle a quelle, se vengono pubblicate. Mantenere l'intervallo ampio solo quanto basta per il periodo di maggiore attività. Le policy predefinite, l'ordine delle regole e il resto del modello di ufw sono descritti nella guida di base al firewall ufw per un VPS.

Controllare anche IPv6. Se IPV6=no è impostato in /etc/default/ufw, ufw non filtra affatto IPv6; di conseguenza, un daemon in ascolto su :: è raggiungibile tramite IPv6 senza applicare nessuna delle regole precedenti. Apertura delle porte IPv6 con ufw spiega le differenze tra le due famiglie. La maggior parte dei provider offre anche un firewall di rete separato nel pannello di controllo. Questo firewall viene applicato prima che i pacchetti raggiungano il VPS, quindi una porta deve essere aperta in entrambe le posizioni.

Gli attacchi brute force SIP e le frodi tariffarie non sono problemi opzionali

Se si espone la porta 5060 su un indirizzo pubblico, iniziano le scansioni. Il modello è ricorrente: richieste REGISTER e INVITE provenienti da molti indirizzi sorgente, con tentativi su numeri di interno comuni e secret comuni. Asterisk registra ogni errore. La riga ha questo formato.

Request 'REGISTER' from '<sip:1000@198.51.100.20>' failed for '198.51.100.20:5060' (callid: 5f1a5c0d) - No matching endpoint found

Questo problema richiede interventi concreti per una ragione economica. Un interno sottratto viene usato per effettuare chiamate internazionali costose, spesso verso numeri a tariffa maggiorata che riconoscono all'attaccante una quota. Il costo ricade su di voi perché le chiamate usano le vostre credenziali. L'attacco procede alla velocità della macchina e di solito continua durante la notte.

Sei controlli sono obbligatori, non misure di hardening facoltative.

  • Non create mai un interno il cui secret sia uguale al numero dell'interno o a una parola breve. Generatene uno con openssl rand -base64 24 e incollatelo.
  • Lasciate disabilitate le chiamate anonime in ingresso. PJSIP rifiuta per impostazione predefinita le chiamate non identificate e le accetta soltanto se create un endpoint denominato anonymous. Non createlo.
  • Mantenete separato il context del trunk da qualsiasi context che possa effettuare chiamate in uscita, come mostrato sopra.
  • Limitate la segnalazione in base all'indirizzo sorgente, sia in ufw sia nel firewall di rete del provider.
  • Impostate un limite di spesa con il provider del trunk SIP e disabilitate le destinazioni internazionali che non chiamate mai. Questo è l'unico controllo che limita la perdita quando gli altri falliscono.
  • Eseguite fail2ban sui log di Asterisk.

Asterisk può inoltre generare un evento di sicurezza dopo richieste non corrispondenti ripetute provenienti dallo stesso indirizzo. La sezione [global] di pjsip.conf accetta unidentified_request_count, che per impostazione predefinita è 5, e unidentified_request_period, che per impostazione predefinita è 5 secondi. Insieme, questi valori indicano che cinque richieste non corrispondenti dallo stesso indirizzo nell'arco di cinque secondi generano un evento di sicurezza su cui fail2ban può intervenire.

Blocca gli scanner con fail2ban

fail2ban include già una jail asterisk. Copre le porte 5060 e 5061, legge /var/log/asterisk/messages e usa maxretry = 10 come valore predefinito. La jail resta disattivata finché non la abiliti in /etc/fail2ban/jail.local.

[asterisk]
enabled = true
maxretry = 5
findtime = 600
bantime = 86400
sudo systemctl restart fail2ban
sudo fail2ban-client status asterisk

Un risultato corretto mostra il file di log della jail e il numero di indirizzi attualmente bloccati. Su una porta 5060 esposta pubblicamente, questo numero smette di essere zero entro un giorno. Il filtro incluso intercetta gli avvisi No matching endpoint found riportati sopra e anche le righe strutturate SecurityEvent di Asterisk. Questi eventi vengono scritti in un canale di log separato, commentato in /etc/asterisk/logger.conf. Per includerli, abilita quel canale e aggiungi il file a logpath della jail.

[logfiles]
console => notice,warning,error
messages.log => notice,warning,error
security.log => security

Ricarica il logger con sudo asterisk -rx "logger reload". Il filtro include anche un journalmatch per asterisk.service, quindi puoi usare un backend journal se preferisci non conservare file di log. L'installazione, la struttura jail.local e la rimozione del blocco per un indirizzo che hai escluso sono descritte nella guida a fail2ban per Ubuntu 24.04.

Latenza e scelta del codec su un VPS distante

La latenza dipende dalla distanza geografica e non può essere eliminata con la configurazione. ITU-T G.114 raccomanda di mantenere la latenza unidirezionale sotto 150 ms per una conversazione normale e considera ancora utilizzabili valori fino a circa 400 ms. L’audio proveniente da un telefono raggiunge il VPS e da lì il provider del trunk, quindi un VPS nella regione sbagliata percorre quella distanza due volte. Posizionalo vicino ai telefoni o al provider. Se le due opzioni sono in conflitto, preferisci la vicinanza ai telefoni, perché quel collegamento passa di solito su Internet consumer, dove il jitter è maggiore.

La scelta del codec determina la larghezza di banda per chiamata. Ogni codec qui invia un pacchetto ogni 20 ms, cioè 50 pacchetti al secondo. Ogni pacchetto contiene 40 byte di header IP, UDP e RTP oltre al payload audio.

ChartBandwidth per concurrent call, one direction, 20 ms packets
The data behind this chart
[
  {
    "label": "G.711 ulaw",
    "payload_kbps": 64,
    "ip_kbps": 80
  },
  {
    "label": "G.722",
    "payload_kbps": 64,
    "ip_kbps": 80
  },
  {
    "label": "Opus at 24 kbps",
    "payload_kbps": 24,
    "ip_kbps": 40
  },
  {
    "label": "G.729",
    "payload_kbps": 8,
    "ip_kbps": 24
  }
]

G.711 ulaw è il codec predefinito sulla maggior parte dei trunk. Il suo payload è di 64 kbps. Con gli header, una chiamata in corso utilizza 80 kbps in ciascuna direzione. Opus a 24 kbps utilizza 40 kbps, mentre G.729 scende a 24 kbps, a scapito della qualità audio e del tempo CPU. Questi valori sono calcoli degli header, non misurazioni: velocità del payload più 40 byte per pacchetto a 50 pacchetti al secondo. L’incapsulamento Ethernet o VLAN aggiunge una quantità leggermente maggiore di dati trasmessi.

La transcodifica utilizza CPU. Se i telefoni e il trunk usano entrambi ulaw, consenti solo ulaw e Asterisk inoltra l’audio senza modificarlo. Opus mantiene una buona qualità sui collegamenti soggetti a perdita di pacchetti, ma la transcodifica tra Opus e G.711 richiede il modulo esterno codec_opus. Selezionalo in make menuselect. Il modulo non viene compilato per impostazione predefinita.

Cosa non funziona e quale stringa verrà visualizzata

La chiamata si connette, ma nessuno sente nulla. RTP non arriva. Verifica che l'intervallo in rtp.conf corrisponda a quello aperto nel firewall, quindi monitora i pacchetti con sudo tcpdump -ni any udp portrange 10000-10200 mentre effettui una chiamata. Se non arriva alcun pacchetto, il firewall locale o il firewall di rete del provider li sta bloccando.

L'audio è disponibile in una sola direzione. Un lato invia RTP a un indirizzo che non può riceverlo. Il problema riguarda l'indirizzo, non la porta. Se il VPS ha l'indirizzo pubblico direttamente sulla propria interfaccia, non è necessaria alcuna gestione NAT. Se il provider assegna al VPS un indirizzo privato con una mappatura pubblica uno a uno, imposta l'indirizzo pubblico sul transport e indica l'intervallo privato in local_net.

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
local_net=10.0.0.0/8
external_media_address=198.51.100.5
external_signaling_address=198.51.100.5

Nel log compare No matching endpoint found. La richiesta non corrispondeva ad alcun endpoint in base all'indirizzo IP o al nome utente. Se proviene da uno scanner, è normale e fail2ban la gestirà. Se proviene dal tuo provider, significa che la sezione identify non contiene l'indirizzo da cui il provider effettua le chiamate verso di te.

Lo stato della registrazione è Rejected. Il provider ha rifiutato le credenziali nella sezione auth. Esegui pjsip set logger on nella CLI, monitora un messaggio REGISTER e la relativa risposta, quindi confronta client_uri e username con i valori forniti dal provider.

Nel log non compare nulla di utile. Per impostazione predefinita, Asterisk scrive nel log i messaggi di livello notice e superiori in messages.log. Aumenta il livello con core set verbose 4 e pjsip set logger on mentre riproduci il problema, quindi disabilita entrambe le opzioni, perché il logger SIP scrive ogni pacchetto.

Prima di esporlo

Un PBX non è come gli altri servizi self-hosted. Un'applicazione web non funzionante rende una pagina non disponibile. Un PBX non funzionante può generare costi telefonici elevati nel giro di poche ore, mentre dormi. Eseguilo su un VPS dedicato, limita la porta 5060 agli indirizzi noti, assegna a ogni interno un secret casuale e imposta un limite di spesa sull'account del trunk. Il resto del server richiede la stessa configurazione di base di qualsiasi server esposto, descritta in questa panoramica sulla sicurezza reale dell'hosting VPS.

FAQ

Quali porte devo aprire per un server VoIP self-hosted?

La porta 5060 per la segnalazione SIP su UDP e TCP, la porta 5061 se usi SIP su TLS e un intervallo di porte UDP per i media RTP. Il file di esempio di Asterisk rtp.conf usa l'intervallo da 10000 a 20000, mentre i valori predefiniti compilati sono da 5000 a 31000. Ogni chiamata usa due porte dell'intervallo, quindi un intervallo di duecento porte gestisce cento chiamate simultanee. Apri l'intervallo RTP come UDP e limita la porta 5060 agli indirizzi del provider e alle tue reti, invece di lasciarla aperta a chiunque.

Devo installare Asterisk da solo o usare FreePBX?

Installa Asterisk senza componenti aggiuntivi quando vuoi una superficie di attacco ridotta, file di configurazione che puoi mantenere in git e sei disposto a scrivere il dialplan. Installa FreePBX quando vuoi una GUI per interni, caselle vocali e code di chiamata. Ad agosto 2026, l'installer di FreePBX 17 richiede una macchina Debian 12 standard e installa Asterisk, un web server, un database server e PHP, quindi assegnagli un VPS dedicato. FreePBX rigenera i file di configurazione che gestisce, quindi le modifiche manuali devono essere applicate ai relativi file _custom.

Perché non c'è audio dopo la connessione della chiamata?

La segnalazione ha funzionato, ma i media no. SIP ha stabilito la chiamata sulla porta 5060, mentre l'audio usa un flusso UDP separato verso una porta dell'intervallo RTP che viene bloccato. Verifica che l'intervallo in rtp.conf corrisponda a quello aperto nel firewall e controlla anche il firewall di rete del provider, oltre a quello del server. Esegui sudo tcpdump -ni any udp portrange 10000-10200 durante una chiamata: se non arrivano pacchetti, significa che vengono bloccati prima di raggiungere il server.

Come posso fermare gli attacchi brute force contro SIP e le frodi telefoniche?

Assegna a ogni interno un secret lungo e casuale, che non corrisponda mai al numero dell'interno. Mantieni separato il context usato dal trunk da qualsiasi context che può effettuare chiamate in uscita, in modo che una chiamata in ingresso non possa richiamare l'esterno usando il tuo account. Limita la porta 5060 agli indirizzi del provider. Abilita il jail asterisk in fail2ban: legge /var/log/asterisk/messages e blocca gli indirizzi che producono No matching endpoint found errori. Imposta quindi un limite di spesa e blocca le destinazioni internazionali inutilizzate presso il provider, perché questo è l'unico controllo che limita la perdita se tutti gli altri meccanismi falliscono.

Un VPS in una regione lontana peggiora la qualità delle chiamate?

Sì, perché l'audio percorre due tratte: dal telefono al VPS e dal VPS al provider del trunk. ITU-T G.114 raccomanda un ritardo unidirezionale inferiore a 150 ms, e un VPS scelto in una posizione inadeguata può consumare gran parte di questo margine soltanto a causa della distanza. Scegli una regione vicina ai telefoni, perché questa tratta passa di solito su una connessione Internet consumer, dove il jitter è maggiore. La scelta del codec non elimina il ritardo, ma modifica soltanto la larghezza di banda: G.729 riduce il numero di byte, ma non risolve un percorso da 200 ms.

#voip#asterisk#freepbx#sip#self-hosting