
A small Linux VoIP lab lets you see how an account, a dialplan and an audio path work together. This exercise connects two desktop softphones to Asterisk, places internal calls and leaves a voicemail. It uses an isolated test network and has no telephone-network trunk.
The package-based example targets a fresh Ubuntu 24.04 LTS virtual machine with Asterisk 20. Ubuntu's Noble package record identifies its Asterisk 20.6 package and dependencies. Check your repository's actual candidate and update coverage. The upstream release schedule lists Asterisk 20's security-only transition on October 19, 2026 and end of life on October 19, 2027; distribution maintenance is a separate question.
You need Linux administration basics, a VM snapshot, two supported desktop SIP clients and control of a private lab network. The configuration below is a documentation-checked teaching example; its calls have not been executed as part of this guide's preparation. Use the checkpoints to validate your installed build. This is not a production PBX deployment recipe.
Prepare a contained network and fresh installation
Use a lab VLAN or virtual network with no public inbound access. Keep the server and both clients on the same reachable subnet. The example server address is 192.168.56.10; substitute an unused address assigned to your server. A host-only VM network may require both client machines to be VMs or otherwise explicitly attached to that network.
The examples use unencrypted SIP/UDP and RTP only inside that isolated lab. Keep the configuration off public and shared untrusted networks. Do not forward router ports or attach a paid trunk. Use a separate normal phone service for real and emergency calls.
sudo apt update
apt-cache policy asterisk
sudo apt install asterisk
sudo systemctl stop asterisk
asterisk -V
sudo cp -a /etc/asterisk /etc/asterisk.before-voip-lab
Run these commands on the new VM. If APT has no candidate, check that the official Ubuntu Universe repository is enabled; resolve that before continuing. Record the installed version. Installation may start the service, so keep the network isolated from the outset. Take a VM snapshot and retain the configuration copy before editing.
Create two accounts with separate credentials
Replace /etc/asterisk/pjsip.conf on this disposable installation with the following. Replace each password placeholder with a different long random value, then enter the matching value only in its client. The official PJSIP examples explain endpoint, authentication and address-of-record relationships.
[lab-udp]
type=transport
protocol=udp
bind=192.168.56.10:5060
[7101]
type=endpoint
transport=lab-udp
context=lab-internal
disallow=all
allow=ulaw
direct_media=no
auth=auth7101
aors=7101
[auth7101]
type=auth
auth_type=userpass
username=7101
password=REPLACE_WITH_UNIQUE_LONG_PASSWORD_A
[7101]
type=aor
max_contacts=1
[7102]
type=endpoint
transport=lab-udp
context=lab-internal
disallow=all
allow=ulaw
direct_media=no
auth=auth7102
aors=7102
[auth7102]
type=auth
auth_type=userpass
username=7102
password=REPLACE_WITH_UNIQUE_LONG_PASSWORD_B
[7102]
type=aor
max_contacts=1
The endpoint selects call behavior and the dialplan context. Its authentication object checks the client; its address of record stores the registered contact. A one-contact limit keeps each account tied to one lab client. Setting direct_media=no keeps Asterisk in the media path for this exercise.
Inspect /etc/asterisk/modules.conf. Under its existing [modules] section, retain normal module autoloading and add noload => chan_sip.so if that legacy driver is present, so it does not compete for the lab SIP port. This exercise uses PJSIP.
Define only the destinations the lab needs
Replace /etc/asterisk/extensions.conf with the following. The dialplan documentation describes contexts and ordered priorities. Here both clients enter lab-internal, which contains only internal destinations and voicemail access.
[lab-internal]
exten => 7101,1,Dial(PJSIP/7101,20)
same => n,VoiceMail(7101@lab,u)
same => n,Hangup()
exten => 7102,1,Dial(PJSIP/7102,20)
same => n,VoiceMail(7102@lab,u)
same => n,Hangup()
exten => 7199,1,Answer()
same => n,VoiceMailMain(@lab)
same => n,Hangup()
Replace /etc/asterisk/voicemail.conf with the following, using a different private numeric PIN for each mailbox. These PINs are separate from SIP passwords. VoiceMail deposits a message; VoiceMailMain provides retrieval. The retrieval example retains PIN checking.
[general]
format=wav
[lab]
7101 => REPLACE_WITH_PRIVATE_NUMERIC_PIN_A,Lab A
7102 => REPLACE_WITH_PRIVATE_NUMERIC_PIN_B,Lab B
Replace /etc/asterisk/rtp.conf with this small lab media range:
[general]
rtpstart=10000
rtpend=10100
Have the lab firewall permit SIP UDP 5060 and RTP UDP 10000–10100 only from the two client addresses. Keep unrelated inbound access closed; do not disable the firewall. The client must also permit the return traffic appropriate to its own negotiated media ports. Same-subnet placement avoids adding NAT translation to the first exercise.
Start the service and prove registration
sudo systemctl restart asterisk
sudo systemctl status asterisk --no-pager
sudo asterisk -rx "pjsip show endpoints"
sudo asterisk -rx "dialplan show lab-internal"
sudo asterisk -rx "voicemail show users for lab"
Expect endpoints 7101 and 7102, dialplan entries 7101, 7102 and 7199, and two mailboxes in context lab. If an application is unavailable, inspect the module/error log and installed sound/module packages before calling. A transport change requires the restart used above; a dialplan-only change can use dialplan reload.
In client A, enter SIP username and authentication username 7101, its new password, the server's lab IP as domain/registrar, UDP port 5060 and G.711 μ-law/PCMU audio. Client B uses 7102 and its own password. Leave provider proxies and external accounts out of this lab. If a client requires a complete identity, use sip:7101@192.168.56.10, substituting the real lab address.
sudo asterisk -rx "pjsip show contacts"
Both accounts should have a current registered contact. If one is absent, check that client's address, transport, credentials and network reachability. A registered contact still needs the audio test below.
Make calls, leave a message and diagnose by stage
- From 7101 call 7102. Answer, speak in both directions, then hang up. Reverse the test.
- Call 7102 again and let its 20-second ringing interval expire. Leave a short test message after the prompt.
- From either client dial 7199, enter mailbox 7102 and its PIN, and retrieve the message. Delete the test message afterward.
- Restart Asterisk during a quiet lab period, allow the clients to register again and repeat an internal call.
If ringing fails, inspect the endpoint and dialplan mapping. If ringing succeeds but speech fails, check selected audio devices, the agreed codec and both RTP directions. If voicemail fails, verify the mailbox context, application availability and writable voicemail storage. Use sudo journalctl -u asterisk --since "10 minutes ago" for service errors and the configured Asterisk logs for call details. Treat logs and captures as private.
Practice restoring the working state
Save the final configuration and VM snapshot with the installed version and completed tests. Voicemail recordings normally live separately under /var/spool/asterisk/voicemail; protect that data as well as configuration when practicing a full backup. Restore into a disconnected clone, verify permissions and ownership, and repeat the same checkpoints before connecting test clients.
Download the lab configuration templates and instructions. The bundle contains placeholders, not usable account secrets. For the protocol explanation behind these tests, continue with the SIP tutorial and the VoIP learning exercises.