PBX Cheat Sheet

Table of Contents

Notes on FreePBX, IncrediblePBX, and the like.


Copy the ISO to the SDHC card

Put the Pi on the network

For security reasons, do not put the Pi outside your firewall!

Boot the Pi.

Put the SDHC card in the Pi, attach the HDMI port to a monitor, and boot.

Initial configuration

In a terminal window on another machine, ssh into the PBX machine.

Configure MySQL

The docs I’ve seen don’t say what the IncrediblePBX distribution uses for the MySQL root password, and it’s useful to be able to get into MySQL. Set the root password as follows:

# /etc/init.d/mysql stop
# mysqld_safe --skip-grant-tables &
# mysql -u root
mysql> use mysql;
mysql> update user set password=PASSWORD("NEW-PASSWORD") where user='root';
mysql> flush privileges;
mysql> quit
# /etc/init.d/mysql restart
# mysql -u root -p

Change the host name

Edit /etc/hostname to reflect your desired host name. Then, run:

# hostname $(cat /etc/hostname)

Install and configure postfix

This is only necessary if you prefer postfix to the default exim.

# apt-get install postfix

A smart host relay is sufficient. Having a configured mail server allows the PBX to email voice mail audio files.

Using Gmail as a relay

First, you’ll need TLS support, which requires installing some supplementary packages.

# apt-get install libsasl2-modules

Next, add the following to /etc/postfix/main.cf

# Use Gmail as smart relay. See
# http://mhawthorne.net/posts/postfix-configuring-gmail-as-relay.html and
# http://anothersysadmin.wordpress.com/2009/02/06/postfix-as-relay-to-a-smtp-requiring-authentication/
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_password
smtp_sasl_security_options = noanonymous

smtp_use_tls = yes
smtp_tls_security_level = secure
smtp_tls_mandatory_protocols = TLSv1
smtp_tls_mandatory_ciphers = high
smtp_tls_secure_cert_match = nexthop
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

Change masquerade_domains appropriately, as well.

Finally, you have to add authentication parameters. Create /etc/postfix/sasl_password with the following contents:

[smtp.gmail.com]:587 gmailuser:gmailpassword

Replace gmailuser with your Gmail login. If you use a Google Apps domain account, use your domain email address as the user.

Then, run these commands:

# cd /etc/postfix
# postmap sasl_password
# chown postfix sasl_password*

Adjust your router’s firewall

With your Pi behind your firewall, you’ll have to open some ports. Configure your firewall to pass UDP ports 5060, 5061, and 10,000 through 20,000 to and from the Pi. If you’re using a Linux-based iptables firewall, the following rules should do the trick

EXT_IF=...   # The external, Internet visible interface (e.g., eth0)
PBX=...      # The internal IP address of your Raspberry Pi PBX machine

iptables -t nat -A PREROUTING -i $EXT_IF -p udp -m udp \
         -dport 10000:20000 -j DNAT --to-destination $PBX
iptables -t nat -A PREROUTING -i $EXT_IF -p udp -m udp \
         -dport 5060:5061 -j DNAT --to-destination $PBX

Configure the PBX

Configuring Trunks

Google Voice

Log into your Google Voice account. In Settings, set:

NOTE Disable 2-factor authentication on the account, or the PBX won’t be able to log in.

Next, set up a trunk in the PBX. Under Connectivity, select Google Voice (Motif). Create a new Google Voice trunk:

Typical Settings  
Google Voice Username google username (see Note 1)
Google Voice Password password
Google Voice Phone Number phone number (see Note 2)
Edit Trunk checked
Edit Outbound Routes checked
Send Unanswered Calls to Google Voicemail _un_checked

Leave all other settings alone.

Note 1: If you’re using a regular Gmail account with Google voice, your username should be only your username, with no “@gmail.com”. If you’re using a hosted Google Apps account, specify the username and the domain name.

Note 2: Specify the number without spaces or hyphens.

You’ll need to set an appropriate inbound route. (See below.) You can also use Google Voice as your outbound route.


Sample trunk configurations, using a subaccount


Set Maximum Channels to 2.

Set the Outbound Caller ID to the number for the DID you’re using for outbound calls.

Set the trunk name under Outgoing Settings (e.g., vitel-out).

Set PEER Details under Outgoing Settings to something like the following. Replace the username and secret to correspond to the Vitelity subaccount.



Set the trunk name under Incoming Settings (e.g., vitel-in).

Set USER Details under Incoming Settings to something like the following. Replace the username and secret with the credentials of the Vitelity subaccount you’re using.


Set the Register String. Again, replace the username and secret with the credentials of the Vitelity subaccount you’re using.


If inbound calls aren’t working, be sure to set the provider route for the DID(s) appropriately, via the DIDs page on the Vitelity customer portal.

Configuring routes

Configure your trunks. (See above)

Inbound route

Define a new incoming route and set the DID Number field to the number associated with the trunk. You must ensure that the trunk passes the associated DID number, or routing won’t work.

Be sure to define a destination (e.g., a ring group or extension.)

Google Voice Note: If you want to route from a Google Voice trunk, just create a new route and put the Google Voice number in the DID Number field.

Outbound route

Define the route as normal, but be sure to use dial patterns so that outbound calls match the route.

Configuration for a single default outbound route

Route Settings  
Route Name routename
Route Password  
Route Type [ ] Emergency [ ] Intra-Company
Music On Hold? [default]
Time Group [–Permanent Route–]
Route Position [–No Change–]
Additional Settings  
Call Recording [Allow ]
Dial Patterns that will use this Route  
(…….) + [……..] | [1NXXNXXXXXX] / …..]  
(…….) + [……..] | [N11……..] / …..]  
(…….) + [……..] | [NXXNXXXXXX.] / …..]  
(…….) + [……..] | [NXXXXXX….] / …..]  

(Dots in the above indicate blanks.)

Forwarding to an external number after so many rings

Two simple solutions:

Follow Me

  1. Applications > Follow Me
  2. Select the extension.
  3. Select hunt as the Ring Strategy.
  4. Add the number, with a trailing #, to the Follow-Me List.
  5. Optional: Adjust the ring time.

Note: If the target of an inbound route is a ring group, rather than an extension, you must include a “#” on the end of the extension in the ring group to force Follow Me behavior.

Chained ring groups

  1. Put the external number in its own ring group (e.g., ring group #601).
  2. Set the “Destination if no answer” to “Voicemail”.
  3. Put the main extension in different ring group (e.g., ring group #600), and point the inbound route at this ring group.
  4. In this primary ring group (#600), set the ring time appropriately.
  5. Set the “Destination if no answer” to go to the second ring group.

Ensuring that the original caller ID follows a forwarded call

Go into Advanced Settings and change SIP trustrpid and SIP sendrpid to yes.

Also, make sure you don’t have the Outbound CID set on the primary extension.

NOTE: This strategy may not work. The DID provider may not honor the PBX’s attempt to pass along the original caller ID. (Mine doesn’t; I always see the caller ID of the PBX’s outbound trunk.)

In that case, one solution is to modify the second ring group (#601, in the example above) so that “Confirm Calls” is checked. When the call is forwarded, the PBX (which knows the original caller ID) will play a short message (“press 1 to accept the call, 2 to reject it, 3 to listen to the caller ID information”). This approach provides a way to allow the callee to get the caller ID information, even though it’s not passed along by the telco. Be sure to configure enough ring time on the second ring group to permit the callee to listen to the message!

Ensuring that an extension only uses specific outbound routes

This is useful if you have, say, a home line and an office line on the same PBX, and you want to ensure that each one uses a specific outbound route.

Solutions proposed on the web include:

  1. Using the complicated, and unsupported, Custom Contexts module. This is a potentially dangerous module that can totally bork your PBX.
  2. Using something called Extension Routing, by SchmoozeCom; getting it requires a complicated registration procedure at SchmoozeCom, one that doesn’t appear to work with Incredible PBX.
  3. Using a dial pattern to specify individual internal extension caller IDs on each outbound route.

(I have not gotten this working yet.)

Modifying the inbound caller ID.

Hold Music

Converting the music file

FreePBX works best with 8- or 16-bit monoaural, 8,000-Hz WAV files. If you’re starting with an MP3, first convert it to a WAV file:

$ lame --decode mymusic.mp3 mymusic.wav

Then, use sox to convert it to the correct format:

$ sox mymusic.wav -r 8000 -s -b 8 -c 1 mymusic2.wav

Installing the music file

FreePBX support hold music categories. While the Settings > Music On Hold screen supports uploading files and creating new categories, it doesn’t always work. It’s easier to do the whole thing from the command line.

Using the new category

The on-hold music category is specified in the Inbound Routes configuration.

Misc. Admin

Restarting Asterisk

# amportal restart

Changing the log level

First, ensure that the FreePBX Asterisk Logfiles module is installed.

Next, adjust the logging.


Needless to say, it’s a really good idea to backup your PBX. It’s possible to screw things up beyond the point of recovery (especially using experimental modules like Custom Contexts).

To schedule a routine backup, ensure that the Backup and Restore module is installed. (By default, it should be.) Then, go to Admin > Backup. The “Full Backup” template is a reasonable place to start.

Backups are written to /var/spool/asterisk/backup. Copying this directory off to another machine is also a wise idea.


Can’t access voicemail

Password not accepted

You enter the password on the phone handset, but it isn’t accepted. Common problem: The phone isn’t a SIP phone, and you’re using an adapter, but the adapter’s DTMF method isn’t set to “SIP INFO” for that extension. Set the DTMF method to “SIP INFO” and try again.

Feature Codes

These are the default settings. To change them, use the web admin UI and go to Admin | Feature Codes.

Feature Code
Blacklist a number *30
Blacklist the last caller *32
Remove a number from the blacklist *31
Call Forward  
Call Forward All Activate *72
Call Forward All Deactivate *73
Call Forward All Prompting Activate *720
Call Forward All Prompting Deactivate *74
Call Forward Busy Activate *90
Call Forward Busy Deactivate *91
Call Forward Busy Prompting Activate *900
Call Forward Busy Prompting Deactivate *92
Call Forward No Answer/Unavailable Activate *52
Call Forward No Answer/Unavailable Deactivate *53
Call Forward No Answer/Unavailable Prompting Activate *520
Call Forward Toggle *740
Call Waiting  
Call Waiting - Activate *70
Call Waiting - Deactivate *71
Conference Status *87
Asterisk General Call Pickup *8
ChanSpy 555
Directed Call Pickup **
In-Call Asterisk Attended Transfer *2
In-Call Asterisk Blind Transfer ##
In-Call Asterisk Disconnect Code **
In-Call Asterisk Toggle Call Recording *1
Simulate Incoming Call 7777
User Logoff *12
User Logon *11
ZapBarge 888
Do-Not-Disturb (DND)  
DND Activate *78
DND Deactivate *79
DND Toggle *76
Fax Configuration  
Dial System FAX 666
Follow Me  
Findme Follow Toggle *21
Wake Up Calls  
Wake Up Calls *68
Info Services  
Call Trace *69
Echo Test *43
Speak Your Exten Number *65
Speaking Clock *60
Misc Applications  
Apps IVR Demo 3366
Time of Day *61
Parking Lot  
Pickup ParkedCall Prefix *85
Check Recording *99
Save Recording *77
Time Conditions  
All: Time Condition Override *27
Dial Voicemail *98
Direct Dial Prefix *
My Voicemail *97