Installing and configuring Asterisk on Ubuntu 24.x
This guide walks through building a VoIP system on Ubuntu 24.x, from installing Asterisk to configuring pjsip.conf and extensions.conf and testing with Linphone on Android.
Installing Asterisk and basic setup
sudo apt update
sudo apt install asterisk
sudo systemctl start asterisk
sudo systemctl enable asterisk
Installing from source
Download the Asterisk source.
sudo apt install wget build-essential subversion
cd /usr/src/
sudo wget https://github.com/asterisk/asterisk/releases/download/21.3.1/asterisk-21.3.1.tar.gz
sudo tar zxvf asterisk-21.3.1.tar.gz
sudo rm asterisk-21.3.1.tar.gz
cd asterisk-21.3.1
sudo contrib/scripts/get_mp3_source.sh
sudo contrib/scripts/install_prereq install
sudo ./configure
sudo make menuselect # select the "format_mp3" option
sudo make -j2
sudo make install
sudo make samples
sudo make basic-pbx
sudo make config
sudo ldconfig
sudo adduser --system --group --home /var/lib/asterisk --no-create-home --gecos "Asterisk PBX" asterisk
sudo vi /etc/default/asterisk
# /etc/default/asterisk
AST_USER="asterisk"
AST_GROUP="asterisk"
Add the user to the required groups.
sudo usermod -a -G dialout,audio asterisk
Set ownership and permissions.
sudo chown -R asterisk: /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk
sudo chmod -R 750 /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk
Open the firewall ports you need (5060/udp, 5061/tcp).
Installing a STUN server (optional)
coturn is an open source TURN (Traversal Using Relay NAT) and STUN (Session Traversal Utilities for NAT) server. In plain terms, it is server software that makes P2P (Peer-to-Peer) communication work inside a NAT (Network Address Translation) environment. You may need to run it alongside Asterisk.
Install coturn.
sudo apt-get update
sudo apt-get install coturn
Edit /etc/turnserver.conf.
listening-port=3478
tls-listening-port=5349
# external IP address (the WAN IP when behind a router)
external-ip=YOUR_PUBLIC_IP
# enable logging
verbose
fingerprint
lt-cred-mech
# credentials (realm, username, password)
realm=YOUR_REALM
user=YOUR_USERNAME:YOUR_PASSWORDStart coturn.
sudo systemctl start coturn
sudo systemctl enable coturn
Open the ports it needs (UDP/TCP 3478, 5349).
sudo ufw allow 3478/udp
sudo ufw allow 3478/tcp
sudo ufw allow 5349/udp
sudo ufw allow 5349/tcp
Configuring pjsip.conf
Here are the settings added for extensions 701 through 703.
[701]
type=aor
max_contacts=1
contact=sip:701@{{PUBLIC_IP}}:5060
[701]
type=auth
auth_type=userpass
username=701
password={{PASSWORD}}
[701]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw,alaw
aors=701
auth=701
subscribe_context=state-hints
rtp_symmetric=yes
force_rport=yes
[701]
type=registration
transport=transport-udp
outbound_auth=701
server_uri=sip:{{PUBLIC_IP}}:5060
client_uri=sip:701@{{PRIVATE_IP}}:5060
retry_interval=60
max_retries=10
[702]
type=aor
max_contacts=1
contact=sip:702@{{PUBLIC_IP}}:5060
[702]
type=auth
auth_type=userpass
username=702
password={{PASSWORD}}
[702]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw,alaw
aors=702
auth=702
subscribe_context=state-hints
rtp_symmetric=yes
force_rport=yes
[702]
type=registration
transport=transport-udp
outbound_auth=702
server_uri=sip:{{PUBLIC_IP}}:5060
client_uri=sip:702@{{PRIVATE_IP}}:5060
retry_interval=60
max_retries=10The block above is the pjsip.conf content for an Asterisk PBX, showing how extensions 701, 702, and 703 are configured and registered. Each extension follows the same shape and consists of a few core pieces.
AOR (Address of Record):
type=aor: defines the AOR object.max_contacts=1: limits how many contacts are allowed.contact=sip:70x@{{PUBLIC_IP}}:5060: the SIP address for that extension. Replace {{PUBLIC_IP}} with your public IP address.
Auth (Authentication):
type=auth: defines the authentication object.auth_type=userpass: uses username and password authentication.username=70x: sets the username to match the extension number.password={{PASSWORD}}: the password for that extension. Replace {{PASSWORD}} with a real password.
Endpoint:
type=endpoint: defines the endpoint object.transport=transport-udp: uses the UDP transport.context=default: uses the default dial plan context.disallow=all: disables every codec by default.allow=ulaw,alaw: allows only the ulaw and alaw codecs.aors=70x: links the AOR for that extension.auth=70x: links the credentials for that extension.subscribe_context=state-hints: sets the context used for state subscriptions.rtp_symmetric=yes: enables symmetric RTP.force_rport=yes: forces use of the remote port for the RTP media stream.
Registration:
type=registration: defines the registration object.transport=transport-udp: uses the UDP transport.outbound_auth=70x: uses that extension’s credentials for outbound authentication.server_uri=sip:{{PUBLIC_IP}}:5060: the URI of the SIP server to register with.client_uri=sip:70x@{{PRIVATE_IP}}:5060: the client URI for the extension. Replace {{PRIVATE_IP}} with your private IP address.retry_interval=60: retries registration every 60 seconds.max_retries=10: gives up after 10 registration attempts.
This is a basic extension setup, and you can add or change options as needed.
Replace {{PUBLIC_IP}} and {{PRIVATE_IP}} with real IP addresses, and make {{PASSWORD}} a strong password.
To add more extensions, copy the blocks and change 701, 702, and 703 to the extension numbers you want.
Configuring extensions.conf
The extensions.conf setup is a dial plan that routes a call to the matching extension and falls through to voicemail when nobody answers.
[default]
exten => 701,1,NoOp(Calling 701)
same => n,Dial(PJSIP/701,20)
same => n,VoiceMail(701@default,u)
same => n,Hangup()
exten => 702,1,NoOp(Calling 702)
... (omitted)
exten => 703,1,NoOp(Calling 703)
... (omitted)Config generation script (optional)
A script that sets up channels from 1000 through 2000.
#!/bin/bash
# settings
START_EXTENSION=1000
END_EXTENSION=2000
EXTERNAL_SIGNALING_ADDRESS="YOUR_PUBLIC_IP"
LOCAL_IP_ADDRESS="YOUR_PRIVATE_IP"
MAX_CONTACTS=5
PASSWORD=PASSWORD
STUN_SERVER="YOUR_PUBLIC_IP:5349"
# reset pjsip.conf (optional)
echo "" > /etc/asterisk/pjsip.conf
# base configuration
cat <<EOF >> /etc/asterisk/pjsip.conf
[general]
;context=default
;bindport=5060
;bindaddr=0.0.0.0
;rtpstart=10000
;rtpend=20000
;disallow=all
;allow=ulaw,alaw
;externip=$EXTERNAL_SIGNALING_ADDRESS
;nat=force_rport,comedia
;disallow=all
;allow=ulaw,alaw,g722
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
;ice_support=yes
;local_net=$LOCAL_IP_ADDRESS/24
;external_signaling_address=$EXTERNAL_SIGNALING_ADDRESS
;external_media_address=$EXTERNAL_SIGNALING_ADDRESS
[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0
EOF
# generate the channel blocks
for (( extension=$START_EXTENSION; extension<=$END_EXTENSION; extension++ )); do
cat <<EOF >> /etc/asterisk/pjsip.conf
[$extension]
type=aor
max_contacts=$MAX_CONTACTS
contact=sip:$extension@$EXTERNAL_SIGNALING_ADDRESS:5060
[$extension]
type=auth
auth_type=userpass
username=$extension
password=$PASSWORD
[$extension]
type=endpoint
transport=transport-udp
context=default
dtmf_mode=rfc4733
disallow=all
allow=ulaw
allow=alaw
allow=h264
ice_support=yes
;direct_media=no
force_rport=yes
rtp_symmetric=yes
;rewrite_contact=yes
aors=$extension
auth=$extension
;subscribe_context=state-hints
;[$extension]
;type=endpoint
;transport=transport-udp
;context=default
;disallow=all
;allow=ulaw,alaw
;aors=$extension
;auth=$extension
;media_encryption=sdes
;ice_support=yes
;use_avpf=yes
;media_use_received_transport=yes
;rtcp_mux=yes
;[$extension]
;type=identify
;endpoint=$extension
;match=$EXTERNAL_SIGNALING_ADDRESS
[$extension]
type=registration
transport=transport-udp
outbound_auth=$extension
server_uri=sip:$EXTERNAL_SIGNALING_ADDRESS:5060
client_uri=sip:$extension@$LOCAL_IP_ADDRESS:5060
retry_interval=60
max_retries=10
EOF
done
rm /var/lib/asterisk/astdb.sqlite3 # clears active channels and registered users
service asterisk restart # restartOpening the firewall
These are the firewall rules that concern Asterisk. The relevant ports are the ones handling SIP traffic and RTP traffic.
UDP port 5060
- IP address: 0.0.0.0/0
- Description: allows access to UDP port 5060 from any IP address. This port normally carries SIP traffic.
TCP ports 5060 to 5061
- IP address: 0.0.0.0/0
- Description: allows access to TCP ports 5060 through 5061 from any IP address. These ports carry SIP traffic.
UDP ports 10000 to 20000
- IP address: 0.0.0.0/0
- Description: allows access to UDP ports 10000 through 20000 from any IP address. This range mainly carries RTP traffic.
These rules let the Asterisk server handle inbound SIP requests and RTP media streams. The SIP port (5060) and the RTP ports (10000-20000) are both required for VoIP calls.
Testing with Linphone on Android
- Install Linphone: get the Linphone app from the Google Play Store.
- Set up the account: create a new SIP account in the Linphone app.
- Username: the extension number set in
pjsip.conf(for example, 701) - Password: the password set in
pjsip.conf - Domain: the
IPaddress or domain name of theAsteriskserver
- Username: the extension number set in
- Test a call: place and answer calls to another extension and check the audio quality.
Further settings and things to consider
- NAT environments: behind NAT you may need extra options in
pjsip.conf, such asextern_host,extern_refresh, anddirect_media. - Security: set up TLS encryption and use strong usernames and passwords.
- Advanced features: the Asterisk system extends with call forwarding, call recording, IVR (Interactive Voice Response), and more.
- Troubleshooting Linphone: if audio codec problems appear in Linphone, check the
allowentries inpjsip.confand enable the same codecs in Linphone’s settings.