How to Run a VoIP Server on a VPS with FreePBX and Asterisk
Running your own VoIP (Voice over IP) phone system on a VPS gives small businesses and teams a professional private branch exchange (PBX) at a fraction of the cost of hosted PBX services. Asterisk is the world’s most widely used open-source PBX engine, and FreePBX provides the browser-based management interface on top of it β together they power millions of business phone systems worldwide.
This guide installs FreePBX with Asterisk on an Ubuntu VPS, configures SIP extensions, sets up a SIP trunk for real phone calls, adds voicemail, and hardens the installation against VoIP fraud.
What You Can Build
- Internal extensions for your team (100, 101, 102…)
- Real inbound/outbound phone numbers via SIP trunk
- Voicemail with email delivery
- Call queues and IVR menus (“Press 1 for sales…”)
- Conference rooms
- Call recording
- Ring groups (call multiple phones simultaneously)
VPS Requirements for VoIP
| Concurrent calls | RAM | CPU | Notes |
|---|---|---|---|
| Up to 10 | 2 GB | 1β2 vCPU | Small team |
| 10β30 | 4 GB | 2 vCPU | Small business |
| 30β100 | 8 GB | 4 vCPU | Medium business |
π‘ Important: VoIP requires low latency. Choose a VPS location close to your team. For US-based teams, VPS.DO’s USA VPS is ideal. For Asia-Pacific teams, use Hong Kong VPS. View Plans β
Step 1: Prepare Ubuntu VPS
sudo apt update && sudo apt upgrade -y
# FreePBX works best on a minimal install
# Disable AppArmor (FreePBX requires this)
sudo systemctl stop apparmor
sudo systemctl disable apparmor
# Set hostname
sudo hostnamectl set-hostname pbx.yourdomain.com
Step 2: Install Dependencies
sudo apt install -y \
build-essential git curl wget \
apache2 mariadb-server mariadb-client \
php8.1 php8.1-cli php8.1-mysql php8.1-curl \
php8.1-mbstring php8.1-xml php8.1-zip \
libapache2-mod-php8.1 \
sox libsox-fmt-mp3 \
ffmpeg lame mpg123 \
nodejs npm \
unixodbc libodbc1
sudo systemctl enable apache2 mariadb
sudo mysql_secure_installation
Step 3: Install Asterisk
cd /usr/src
# Download Asterisk 20 LTS
wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-20-current.tar.gz
tar xvfz asterisk-20-current.tar.gz
cd asterisk-20*/
# Install prerequisites
sudo contrib/scripts/install_prereq install
# Configure and compile
./configure --with-jansson-bundled
make menuselect # Select desired modules (accept defaults for basic setup)
make -j$(nproc)
sudo make install
sudo make config
sudo make install-logrotation
# Start Asterisk
sudo systemctl enable asterisk
sudo systemctl start asterisk
# Verify
sudo asterisk -rx "core show version"
Step 4: Install FreePBX
cd /usr/src
# Download FreePBX
wget http://mirror.freepbx.org/modules/packages/freepbx/freepbx-17.0-latest.tgz
tar xvfz freepbx-*.tgz
cd freepbx/
# Create asterisk user
sudo useradd -m asterisk
sudo chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk \
/var/log/asterisk /var/spool/asterisk /usr/lib/asterisk
# Run FreePBX installer
sudo ./install --webroot=/var/www/html \
--dbengine=mariadb \
--dbname=freepbx \
--cdrdbname=asteriskcdrdb
# Enable FreePBX service
sudo systemctl enable freepbx
sudo fwconsole start
Step 5: Configure Apache for FreePBX
sudo nano /etc/apache2/sites-available/freepbx.conf
ServerName pbx.yourdomain.com
DocumentRoot /var/www/html
Options -Indexes
AllowOverride All
Require all granted
sudo a2ensite freepbx
sudo a2enmod rewrite
sudo systemctl restart apache2
Access FreePBX at http://YOUR_VPS_IP/admin to complete the web-based setup. β
Step 6: Create SIP Extensions
In the FreePBX web interface:
- Go to Applications β Extensions β Add Extension
- Select PJSIP Extension
- Configure:
- User Extension:
100 - Display Name: Alice Smith
- Secret: (auto-generated secure password)
- User Extension:
- Click Submit β Apply Config
Repeat for each team member (101, 102, 103…).
Connect a SIP softphone
Use any SIP client (Zoiper, Linphone, 3CX mobile app) with these settings:
| Setting | Value |
|---|---|
| SIP Server | YOUR_VPS_IP |
| Username | 100 (extension number) |
| Password | The extension secret |
| Port | 5060 |
Step 7: Add a SIP Trunk (Real Phone Numbers)
To make and receive calls to/from regular phone numbers, you need a SIP trunk provider. Popular options: Twilio, VoIP.ms, Telnyx, Vonage.
Configure a SIP trunk in FreePBX
- Connectivity β Trunks β Add Trunk β PJSIP Trunk
- Trunk Name: MyProvider
- Under PJSIP Settings:
- Username: your SIP provider username
- Password: your SIP provider password
- SIP Server: sip.yourprovider.com
Set up outbound route
- Connectivity β Outbound Routes β Add Route
- Route Name: International Calls
- Trunk Sequence: MyProvider
- Dial Pattern:
NXXNXXXXXX(matches US 10-digit numbers)
Set up inbound route
- Connectivity β Inbound Routes β Add Route
- DID Number: your purchased phone number
- Set Destination: Extension 100 (or IVR, ring group, etc.)
Step 8: Configure Voicemail
- Edit any extension β Voicemail tab
- Enable voicemail: Yes
- Voicemail password: 1234 (user can change)
- Email address: alice@yourcompany.com
- Email attachment: Yes (receive voicemail as audio file)
Configure email delivery in Admin β System Admin β Notifications.
Step 9: Security Hardening (Critical for VoIP)
VoIP servers are actively targeted by attackers who hijack them to make expensive international calls. This section is not optional.
Firewall rules
# Allow SIP (UDP/TCP)
sudo ufw allow 5060/udp
sudo ufw allow 5060/tcp
sudo ufw allow 5061/tcp # SIP TLS
# Allow RTP media streams
sudo ufw allow 10000:20000/udp
# Allow HTTP/HTTPS for FreePBX admin
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# RESTRICT admin access to your IP only
sudo ufw allow from YOUR_OFFICE_IP to any port 80
sudo ufw allow from YOUR_OFFICE_IP to any port 443
sudo ufw delete allow 80/tcp # Remove unrestricted rules after adding IP-restricted ones
sudo ufw reload
Enable Fail2ban for Asterisk
sudo apt install fail2ban -y
sudo nano /etc/fail2ban/jail.local
[asterisk]
enabled = true
filter = asterisk
logpath = /var/log/asterisk/messages
maxretry = 5
bantime = 86400
findtime = 3600
sudo systemctl restart fail2ban
Restrict SIP access by IP
In FreePBX β Admin β Firewall, enable the FreePBX Firewall module and whitelist only your office/team IP ranges for SIP access.
Enable SIP TLS
In FreePBX β Admin β SIP Settings β TLS/SRTP, enable TLS for encrypted SIP signaling. Generate a certificate with Certbot and configure Asterisk to use it.
Monitor for fraud
# Watch for unusual call volume or destinations
sudo asterisk -rx "core show channels"
sudo asterisk -rx "sip show peers"
# Check CDR (call detail records) for anomalies
sudo mysql -u root -e "SELECT src, dst, duration, billsec FROM asteriskcdrdb.cdr ORDER BY calldate DESC LIMIT 20;"
Step 10: SSL for FreePBX Admin
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d pbx.yourdomain.com
Access your FreePBX admin interface securely at https://pbx.yourdomain.com/admin. β
Cost Comparison: Self-Hosted vs Hosted PBX
| Self-hosted (VPS + FreePBX) | Hosted PBX (RingCentral, Vonage) | |
|---|---|---|
| Setup cost | 2β4 hours | Minutes |
| Monthly infrastructure | $20β50/month (VPS) | $25β50/user/month |
| 10-user team total | ~$50/month | $250β500/month |
| Call recording | Unlimited, local storage | Extra charge |
| Custom IVR | Full control | Limited templates |
| Data ownership | Your server | Provider’s servers |