Asterisk PBX Installation and Configuration
Asterisk is the world's most widely deployed open-source PBX (Private Branch Exchange) platform that powers VoIP telephony systems ranging from small offices to large call centers, supporting SIP trunks, extensions, dialplans, IVR menus, voicemail, and conferencing. This guide covers installing Asterisk on Linux, configuring SIP trunks, setting up extensions, building dialplans, and security hardening.
Prerequisites
- Ubuntu 20.04+ or CentOS 8+ / Rocky Linux 8+
- 1 GB RAM minimum (2+ GB for production)
- A SIP trunk provider account (VoIP.ms, Twilio, Bandwidth, etc.)
- SIP-capable phones or softphones (Zoiper, Linphone, X-Lite, etc.)
- Static public IP address or DynDNS (for external SIP access)
- Root or sudo access
Installing Asterisk
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y asterisk asterisk-modules
# CentOS/Rocky Linux (from EPEL or compile from source)
sudo dnf install -y epel-release
sudo dnf install -y asterisk asterisk-configs
# Or compile from source for the latest version (recommended for production)
# Install build dependencies
sudo apt-get install -y build-essential pkg-config libssl-dev \
libncurses5-dev libnewt-dev libxml2-dev libsqlite3-dev \
uuid-dev libedit-dev libjansson-dev libsrtp2-dev
# Download and compile
ASTERISK_VERSION="21.3.0"
wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-${ASTERISK_VERSION}.tar.gz
tar xzf asterisk-${ASTERISK_VERSION}.tar.gz
cd asterisk-${ASTERISK_VERSION}
# Install pjproject (SIP library)
contrib/scripts/install_prereq install
./configure
make menuselect # Select modules (enable codec_opus if needed)
make -j$(nproc)
sudo make install
sudo make samples # Install sample configs
sudo make config # Install init scripts
# Verify
asterisk -V
# Enable and start
sudo systemctl enable --now asterisk
sudo asterisk -rvvv # Connect to running Asterisk CLI
Basic Configuration Files
Asterisk configuration lives in /etc/asterisk/. Key files:
/etc/asterisk/
├── asterisk.conf # Global settings
├── pjsip.conf # SIP endpoints (modern, preferred)
├── extensions.conf # Dialplan
├── voicemail.conf # Voicemail settings
├── musiconhold.conf # Hold music
└── modules.conf # Which modules to load
Edit asterisk.conf for basic settings:
# /etc/asterisk/asterisk.conf
[directories]
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk
astdbdir => /var/lib/asterisk
astkeydir => /var/lib/asterisk
astdatadir => /var/lib/asterisk
astagidir => /var/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk
[options]
verbose = 3
debug = 0
Configuring SIP Trunks
Asterisk 13+ recommends PJSIP over the legacy chan_sip. Edit /etc/asterisk/pjsip.conf:
# /etc/asterisk/pjsip.conf
; === TRANSPORT ===
[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
[transport-tls]
type = transport
protocol = tls
bind = 0.0.0.0:5061
cert_file = /etc/asterisk/keys/asterisk.crt
priv_key_file = /etc/asterisk/keys/asterisk.key
method = tlsv1_2
; === SIP TRUNK (example: VoIP.ms) ===
[voipms-registration]
type = registration
server_uri = sip:[email protected]
client_uri = sip:[email protected]
password = yourpassword
retry_interval = 60
expiration = 3600
[voipms-auth]
type = auth
auth_type = userpass
username = youraccount
password = yourpassword
[voipms-aor]
type = aor
contact = sip:server1.voip.ms
qualify_frequency = 60
[voipms-endpoint]
type = endpoint
context = from-trunk ; dialplan context for incoming calls
allow = !all,ulaw,alaw,g722 ; allowed codecs
outbound_auth = voipms-auth
aors = voipms-aor
dtmf_mode = rfc4733
direct_media = no
Reload PJSIP after changes:
sudo asterisk -rx "pjsip reload"
sudo asterisk -rx "pjsip show registrations" # Verify registration status
Configuring Extensions (Endpoints)
SIP phones (extensions) also go in pjsip.conf:
; === EXTENSION 101 ===
[101]
type = endpoint
context = internal ; dialplan context for this extension
allow = !all,ulaw,alaw,g722
auth = 101-auth
aors = 101-aor
callerid = "Alice Smith" <101>
mailboxes = 101@default
dtmf_mode = rfc4733
direct_media = no
[101-auth]
type = auth
auth_type = userpass
username = 101
password = SecurePassword101
[101-aor]
type = aor
max_contacts = 1
remove_existing = yes
; === EXTENSION 102 ===
[102]
type = endpoint
context = internal
allow = !all,ulaw,alaw,g722
auth = 102-auth
aors = 102-aor
callerid = "Bob Jones" <102>
mailboxes = 102@default
dtmf_mode = rfc4733
direct_media = no
[102-auth]
type = auth
auth_type = userpass
username = 102
password = SecurePassword102
[102-aor]
type = aor
max_contacts = 2
remove_existing = yes
Configure softphone (Zoiper example):
- Account:
101 - Host:
your-server-ip:5060 - Password:
SecurePassword101 - Transport: UDP or TLS
Building a Dialplan
The dialplan in /etc/asterisk/extensions.conf routes calls:
# /etc/asterisk/extensions.conf
; Include all sub-configurations
#include extensions_internal.conf
#include extensions_trunks.conf
[globals]
VOICEMAIL_TIMEOUT=20 ; seconds before forwarding to voicemail
; === INTERNAL CALLS ===
[internal]
; Dial extension 1xx
exten => _1XX,1,NoOp(Internal call to ${EXTEN})
same => n,Set(CALLERID(name)=${CALLERID(name)})
same => n,Dial(PJSIP/${EXTEN},20)
same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy)
same => n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?noanswer)
same => n,Hangup()
same => n(busy),VoiceMail(${EXTEN}@default,b) ; b = busy greeting
same => n,Hangup()
same => n(noanswer),VoiceMail(${EXTEN}@default,u) ; u = unavailable greeting
same => n,Hangup()
; Voicemail check (*98)
exten => *98,1,VoiceMailMain(${CALLERID(num)}@default)
same => n,Hangup()
; === OUTBOUND CALLS THROUGH TRUNK ===
[from-internal-outbound]
; 10-digit NANP calls (US/Canada)
exten => _NXXNXXXXXX,1,NoOp(Outbound call to ${EXTEN})
same => n,Set(CALLERID(num)=+12125551234) ; your DID
same => n,Dial(PJSIP/${EXTEN}@voipms-endpoint)
same => n,Hangup()
; International calls (011 + country code)
exten => _011.,1,NoOp(International call to ${EXTEN})
same => n,Dial(PJSIP/${EXTEN:3}@voipms-endpoint)
same => n,Hangup()
; Emergency (911)
exten => 911,1,Dial(PJSIP/911@voipms-endpoint)
same => n,Hangup()
; === INCOMING FROM TRUNK ===
[from-trunk]
exten => s,1,Answer()
same => n,Goto(ivr-main,s,1)
; DID routing (if you have multiple DIDs)
exten => _+1XXXXXXXXXX,1,Goto(ivr-main,s,1)
Reload the dialplan:
sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "dialplan show internal" # Verify it loaded
Voicemail
Configure /etc/asterisk/voicemail.conf:
# /etc/asterisk/voicemail.conf
[general]
format = wav49|gsm|wav
serveremail = [email protected]
attach = yes
skipms = 3000
maxsilence = 10
silencethreshold = 128
maxlogins = 3
emaildateformat = %A, %B %d, %Y at %r
emailbody = Dear ${VM_NAME}:\n\n\tYou have a new voicemail message (${VM_MSGNUM})\nin mailbox ${VM_MAILBOX}.\n\n\t\t\t\t--Asterisk\n
emailsubject = [PBX]: New message ${VM_MSGNUM} in mailbox ${VM_MAILBOX}
[zonemessages]
eastern = America/New_York|'vm-received' Q 'digits/at' IMp
[default]
101 => 1234,Alice Smith,[email protected],,delete=yes|emailsubject=New voicemail from ${VM_CALLERID}
102 => 5678,Bob Jones,[email protected],,delete=no
IVR Menus
Build an IVR (Interactive Voice Response) in extensions.conf:
[ivr-main]
; Answer and play welcome message
exten => s,1,Answer()
same => n,Wait(1)
same => n,BackGround(custom/welcome-message) ; play /var/lib/asterisk/sounds/custom/welcome-message.wav
same => n,WaitExten(5) ; wait 5 seconds for DTMF input
; DTMF options
exten => 1,1,NoOp(Sales)
same => n,Dial(PJSIP/101,20)
same => n,VoiceMail(101@default,u)
same => n,Hangup()
exten => 2,1,NoOp(Support)
same => n,Dial(PJSIP/102,20)
same => n,VoiceMail(102@default,u)
same => n,Hangup()
exten => 3,1,NoOp(Directory)
same => n,Directory(default) ; spell-by-name directory
same => n,Hangup()
exten => 0,1,NoOp(Operator)
same => n,Dial(PJSIP/101&PJSIP/102,30) ; ring both extensions
same => n,Hangup()
; Timeout - no input
exten => t,1,Goto(s,1)
; Invalid input
exten => i,1,Playback(invalid)
same => n,Goto(s,1)
Record IVR prompts using Asterisk (call extension *99):
; Add to [internal] context for recording prompts
exten => *99,1,Answer()
same => n,Record(/var/lib/asterisk/sounds/custom/welcome-message:wav)
same => n,Playback(/var/lib/asterisk/sounds/custom/welcome-message)
same => n,Hangup()
Security Hardening
# 1. Bind Asterisk to specific interfaces only
# In pjsip.conf - change transport bind:
# bind = 192.168.1.10:5060 (private IP only)
# 2. Fail2ban to block SIP brute force attacks
sudo apt-get install -y fail2ban
cat > /etc/fail2ban/filter.d/asterisk.conf << 'EOF'
[Definition]
failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>.*' - Wrong password
NOTICE.* .*: Registration from '.*' failed for '<HOST>.*' - No matching endpoint found
NOTICE.* .*: Registration from '.*' failed for '<HOST>.*' - Username/auth name mismatch
ignoreregex =
EOF
cat > /etc/fail2ban/jail.d/asterisk.conf << 'EOF'
[asterisk]
enabled = true
port = 5060,5061
protocol = udp,tcp
filter = asterisk
logpath = /var/log/asterisk/messages
maxretry = 5
bantime = 3600
findtime = 600
EOF
sudo systemctl restart fail2ban
# 3. Firewall - only allow SIP from known IPs when possible
sudo ufw allow from YOUR_SIP_PROVIDER_IP to any port 5060 proto udp
sudo ufw allow from YOUR_OFFICE_IP to any port 5060 proto udp
# 4. Use strong extension passwords (in pjsip.conf)
# Never use extension number as password
# 5. Disable unused codecs and features
# In pjsip.conf endpoint section:
# allow = !all,ulaw,alaw (only allow needed codecs)
# 6. Enable TLS for SIPS
# Use transport-tls and configure TLS certificates
Troubleshooting
SIP registration failing:
sudo asterisk -rvvv
# In Asterisk CLI:
pjsip show registrations
pjsip show endpoints
# Enable debug logging for PJSIP
pjsip set logger on
# Try registering from phone and watch logs
One-way audio:
# Usually a NAT issue - add to pjsip.conf endpoint:
# direct_media=no
# force_rport=yes
# ice_support=yes (for STUN/ICE)
# Or set in pjsip.conf [transport-udp]:
# external_media_address=YOUR_PUBLIC_IP
# external_signaling_address=YOUR_PUBLIC_IP
# local_net=192.168.0.0/24
Calls dropping after 30 seconds:
# Usually a NAT timer issue - SIP OPTIONS/keepalive not working
# Add to pjsip.conf endpoint:
# qualify_frequency=60
# qualify_timeout=3.0
Check active calls:
sudo asterisk -rx "core show channels"
sudo asterisk -rx "pjsip show channels"
Conclusion
Asterisk provides a complete, highly customizable PBX that handles everything from a simple two-extension office setup to complex multi-site call center configurations. The PJSIP stack offers modern SIP support with TLS and SRTP, while the dialplan language gives granular control over call routing. Always enable Fail2ban and configure firewall rules from day one, as Asterisk servers on public IPs are high-value targets for toll fraud attacks. Start with a minimal configuration and add features incrementally to keep the system manageable.


