Protocol Support
SIP, PJSIP, IAX2, WebRTC, H.323, and PSTN integration
Asterisk is the world’s most powerful open-source communications platform. Originally created by Mark Spencer in 1999, Asterisk has become the backbone of millions of telephony installations worldwide, from small business phone systems to large-scale call centers handling thousands of simultaneous calls.
As a software PBX (Private Branch Exchange), Asterisk transforms standard computing hardware into a sophisticated communications server. It supports a wide range of telephony protocols including SIP, IAX2, H.323, and integrates with traditional PSTN lines through hardware gateways.
Protocol Support
SIP, PJSIP, IAX2, WebRTC, H.323, and PSTN integration
Modern Architecture
Built on res_pjsip for robust SIP communications
Extensible Platform
ARI, AMI, AGI interfaces for custom integrations
Active Community
96.8% C codebase with GPL-2.0 license
Asterisk provides enterprise-grade telephony capabilities that scale from home offices to enterprise deployments:
| Feature | Description |
|---|---|
| VoIP Gateway | Bridge between IP networks and traditional telephony |
| IVR Systems | Interactive Voice Response with custom menus |
| Conference Bridges | Multi-party audio and video conferencing |
| Voicemail | Full-featured voicemail with email integration |
| Call Recording | Automatic and on-demand call recording |
| Queue Management | ACD with skill-based routing and callbacks |
| WebRTC Support | Browser-based calling without plugins |
| Call Detail Records | Comprehensive CDR for billing and analytics |
Before deploying Asterisk on Klutch.sh, ensure you have:
Organize your Asterisk deployment with proper configuration management:
Create a Dockerfile for your Asterisk deployment:
FROM andrius/asterisk:stable
# Set Asterisk user/group IDsENV ASTERISK_UID=1000ENV ASTERISK_GID=1000
# Copy custom configurationsCOPY config/ /etc/asterisk/
# Expose SIP and RTP portsEXPOSE 5060/udp 5060/tcpEXPOSE 5038/tcpEXPOSE 10000-10500/udp
# Default command runs Asterisk in foregroundCMD ["asterisk", "-f", "-vvv"]Create your SIP configuration in config/pjsip.conf:
; Transport configuration[transport-udp]type=transportprotocol=udpbind=0.0.0.0:5060external_media_address=YOUR_EXTERNAL_IPexternal_signaling_address=YOUR_EXTERNAL_IPlocal_net=10.0.0.0/8local_net=172.16.0.0/12local_net=192.168.0.0/16
; WebSocket transport for WebRTC[transport-wss]type=transportprotocol=wssbind=0.0.0.0:8089
; Template for authenticated endpoints[endpoint-auth](!)type=endpointtransport=transport-udpcontext=internaldisallow=allallow=ulawallow=alawallow=g722allow=opusdirect_media=nortp_symmetric=yesforce_rport=yesrewrite_contact=yes
; Template for authentication[auth-userpass](!)type=authauth_type=userpass
; Template for AOR (Address of Record)[aor-single-reg](!)type=aormax_contacts=1remove_existing=yesqualify_frequency=60
; Example extension 1001[1001](endpoint-auth)auth=1001-authaors=1001-aorcallerid="User One" <1001>
[1001-auth](auth-userpass)username=1001password=securepassword123
[1001-aor](aor-single-reg)
; Example extension 1002[1002](endpoint-auth)auth=1002-authaors=1002-aorcallerid="User Two" <1002>
[1002-auth](auth-userpass)username=1002password=securepassword456
[1002-aor](aor-single-reg)Create your dialplan in config/extensions.conf:
[general]static=yeswriteprotect=noclearglobalvars=no
[globals]OPERATOR=1001VOICEMAIL_CONTEXT=default
[internal]; Internal extension dialing (1XXX)exten => _1XXX,1,NoOp(Calling internal extension ${EXTEN}) same => n,Set(CALLERID(name)=${CALLERID(name)}) same => n,Dial(PJSIP/${EXTEN},30,tTrR) same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail) same => n(busy),VoiceMail(${EXTEN}@default,b) same => n,Hangup() same => n(unavail),VoiceMail(${EXTEN}@default,u) same => n,Hangup()
; Voicemail accessexten => *98,1,NoOp(Voicemail Menu) same => n,VoiceMailMain(${CALLERID(num)}@default) same => n,Hangup()
; Echo testexten => *43,1,NoOp(Echo Test) same => n,Answer() same => n,Playback(demo-echotest) same => n,Echo() same => n,Playback(demo-echodone) same => n,Hangup()
; Conference roomexten => *300,1,NoOp(Conference Room) same => n,Answer() same => n,ConfBridge(1) same => n,Hangup()
; Speaking clockexten => *60,1,NoOp(Speaking Clock) same => n,Answer() same => n,SayUnixTime(,,IMp) same => n,Hangup()
; Invalid extension handlerexten => i,1,NoOp(Invalid Extension) same => n,Playback(invalid) same => n,Hangup()Configure RTP media ports in config/rtp.conf:
[general]rtpstart=10000rtpend=10500rtpchecksums=nodtmftimeout=3000rtcpinterval=5000
; ICE support for WebRTCicesupport=yesstunaddr=stun.l.google.com:19302Control module loading in config/modules.conf:
[modules]autoload=yes
; Core SIP moduleload = res_pjsip.soload = res_pjsip_transport_websocket.soload = res_pjsip_authenticator_digest.soload = res_pjsip_endpoint_identifier_ip.soload = res_pjsip_session.soload = res_pjsip_sdp_rtp.soload = res_pjsip_dtmf_info.soload = chan_pjsip.so
; Applicationsload = app_dial.soload = app_playback.soload = app_voicemail.soload = app_confbridge.soload = app_queue.soload = app_record.so
; Disable legacy SIP drivernoload = chan_sip.so
; Disable unused modulesnoload = chan_alsa.sonoload = chan_console.sonoload = chan_oss.sonoload = chan_phone.sonoload = chan_skinny.sonoload = chan_unistim.sonoload = chan_modem.soSet up voicemail in config/voicemail.conf:
[general]format=wav49|wavserveremail=asterisk@yourdomain.comattach=yesskipms=3000maxsilence=10silencethreshold=128maxlogins=3emaildateformat=%A, %B %d, %Y at %rpagerdateformat=%A, %B %d, %Y at %rsendvoicemail=yesenvelope=yesdelete=nominmessage=3maxmessage=180
[default]1001 => 1234,User One,user1@example.com1002 => 1234,User Two,user2@example.comTest your configuration locally with Docker Compose:
services: asterisk: build: . container_name: asterisk-pbx hostname: asterisk restart: unless-stopped ports: - "5060:5060/udp" - "5060:5060/tcp" - "5038:5038/tcp" - "10000-10500:10000-10500/udp" volumes: - ./config:/etc/asterisk - asterisk-data:/var/lib/asterisk - asterisk-logs:/var/log/asterisk - asterisk-spool:/var/spool/asterisk environment: - ASTERISK_UID=1000 - ASTERISK_GID=1000 cap_add: - NET_ADMIN - SYS_PTRACE
volumes: asterisk-data: asterisk-logs: asterisk-spool:Push your repository to GitHub
Commit your Dockerfile and configuration files to your GitHub repository:
git add .git commit -m "Initial Asterisk PBX configuration"git push origin mainCreate a new app on Klutch.sh
Navigate to your Klutch.sh project dashboard and create a new app. Connect your GitHub repository containing the Asterisk configuration.
Configure the build settings
Klutch.sh will automatically detect your Dockerfile. Verify the following settings:
./Dockerfile.Set up persistent storage
Add volumes for data persistence:
/etc/asterisk, Size: 1 GB/var/lib/asterisk, Size: 5 GB/var/log/asterisk, Size: 2 GB/var/spool/asterisk, Size: 10 GBConfigure networking
In the app settings, configure the network:
Deploy the application
Click the Deploy button to build and launch your Asterisk PBX. Monitor the build logs for any configuration issues.
Connect to a VoIP provider for PSTN calling:
; SIP Trunk to VoIP Provider[trunk-provider]type=endpointtransport=transport-udpcontext=from-trunkdisallow=allallow=ulawallow=alawdirect_media=nofrom_domain=sip.provider.comoutbound_auth=trunk-authaors=trunk-aor
[trunk-auth]type=authauth_type=userpassusername=your_accountpassword=your_password
[trunk-aor]type=aorcontact=sip:sip.provider.com:5060
[trunk-identify]type=identifyendpoint=trunk-providermatch=sip.provider.com
[trunk-registration]type=registrationtransport=transport-udpoutbound_auth=trunk-authserver_uri=sip:sip.provider.comclient_uri=sip:your_account@sip.provider.comretry_interval=60Add outbound routing to your dialplan:
; Outbound calling via trunk[internal]; US numbers (10 digit)exten => _NXXNXXXXXX,1,NoOp(Outbound Call to ${EXTEN}) same => n,Set(CALLERID(num)=YOUR_DID) same => n,Dial(PJSIP/${EXTEN}@trunk-provider,60) same => n,Hangup()
; US numbers with 1 prefixexten => _1NXXNXXXXXX,1,NoOp(Outbound Call to ${EXTEN}) same => n,Set(CALLERID(num)=YOUR_DID) same => n,Dial(PJSIP/${EXTEN}@trunk-provider,60) same => n,Hangup()Enable AMI for external integrations:
[general]enabled=yesport=5038bindaddr=0.0.0.0
[admin]secret=your_ami_passworddeny=0.0.0.0/0.0.0.0permit=10.0.0.0/255.0.0.0permit=172.16.0.0/255.240.0.0permit=192.168.0.0/255.255.0.0read=allwrite=allwritetimeout=5000Enable browser-based calling with WebRTC:
[general]enabled=yesbindaddr=0.0.0.0bindport=8088tlsenable=yestlsbindaddr=0.0.0.0:8089tlscertfile=/etc/asterisk/keys/asterisk.pemtlsprivatekey=/etc/asterisk/keys/asterisk.key[webrtc-phones](!)type=endpointtransport=transport-wsscontext=internaldisallow=allallow=opusallow=ulawdtls_auto_generate_cert=yeswebrtc=yesuse_avpf=yesice_support=yesmedia_encryption=dtlsdtls_verify=fingerprintdtls_setup=actpassrtcp_mux=yes
[webrtc-user](webrtc-phones)auth=webrtc-user-authaors=webrtc-user-aorcallerid="WebRTC User" <2001>
[webrtc-user-auth]type=authauth_type=userpassusername=webrtcuserpassword=webrtcpass
[webrtc-user-aor]type=aormax_contacts=5remove_existing=yesAccess the Asterisk CLI for management:
| Command | Description |
|---|---|
pjsip show endpoints | List all SIP endpoints |
pjsip show registrations | Show trunk registrations |
core show channels | Display active calls |
queue show | Show call queue status |
voicemail show users | List voicemail accounts |
module show | Show loaded modules |
sip set debug on | Enable SIP debugging |
Monitor your Asterisk instance:
# Check if Asterisk is runningdocker exec asterisk-pbx asterisk -rx "core show version"
# View active callsdocker exec asterisk-pbx asterisk -rx "core show channels"
# Check endpoint statusdocker exec asterisk-pbx asterisk -rx "pjsip show endpoints"
# View recent callsdocker exec asterisk-pbx asterisk -rx "cdr show"Strong Passwords
Use complex passwords for all SIP accounts and change defaults immediately
Firewall Rules
Restrict SIP access to known IP ranges and VPN connections
Fail2ban Integration
Implement Fail2ban to block brute force attempts on SIP
TLS/SRTP
Enable encryption for signaling and media when possible
Security hardening recommendations:
; Reject requests from unknown endpoints[global]type=globalendpoint_identifier_order=ip,usernamedefault_from_user=asteriskkeep_alive_interval=90
; IP-based access control[acl]type=acldeny=0.0.0.0/0.0.0.0permit=10.0.0.0/255.0.0.0permit=192.168.0.0/255.255.0.0
; Apply ACL to transport[transport-udp]type=transportprotocol=udpbind=0.0.0.0:5060allow_reload=yesCommon issues and solutions:
| Issue | Cause | Solution |
|---|---|---|
| Registration failures | Wrong credentials or network | Check pjsip.conf auth settings and firewall |
| No audio (one-way) | NAT traversal issues | Configure external_media_address in transport |
| Echo or delay | Codec mismatch or network latency | Use consistent codecs, check network QoS |
| Calls drop after 30 seconds | SIP timeout or session timer | Disable session timers or increase timeout |
| DTMF not working | Wrong DTMF mode | Set dtmf_mode=rfc4733 in endpoint config |
Enable verbose debugging:
[general]exec_after_rotate=gzip -9 ${filename}.2
[logfiles]console => notice,warning,error,debugmessages => notice,warning,errorsecurity => securitydebug => debug