How To

Install FreeSWITCH PBX on Ubuntu 24.04

FreeSWITCH is an open-source telephony platform designed for routing and interconnecting voice, video, and text communication protocols. It handles SIP, WebRTC, PSTN gateways, IVR systems, conference bridges, and more. The current stable release is FreeSWITCH 1.10.12, and SignalWire maintains pre-built Debian/Ubuntu packages that make installation straightforward.

Original content from computingforgeeks.com - post 64008

This guide walks through a complete FreeSWITCH PBX installation on Ubuntu 24.04 using the official SignalWire repository. You will set up the repo with a Personal Access Token, install the packages, verify the service, configure your firewall, and run a basic dialplan test.

Prerequisites

Before starting, make sure you have the following in place:

  • A fresh Ubuntu 24.04 server with at least 2 GB RAM and 2 CPU cores
  • Root or sudo access
  • A SignalWire Personal Access Token (PAT) – free to create at id.signalwire.com/personal_access_tokens
  • Ports 5060/UDP (SIP), 5080/UDP (external SIP profile), and 8021/TCP (Event Socket) available
  • A public IP or properly configured NAT if this is a production PBX

Step 1: Get a SignalWire Personal Access Token

SignalWire requires authentication to access the FreeSWITCH package repository. You need a free Personal Access Token (PAT) before adding the repo.

Go to https://id.signalwire.com/personal_access_tokens and create a free SignalWire account if you do not have one. Once logged in, generate a new Personal Access Token. Copy the token and keep it safe – you will need it in the next step.

Step 2: Update the System

Start by updating existing packages and installing dependencies needed for the repository setup.

sudo apt update && sudo apt upgrade -y

Install the required packages for HTTPS repo access and GPG key handling.

sudo apt install -y gnupg2 wget lsb-release software-properties-common apt-transport-https curl

Step 3: Add the SignalWire FreeSWITCH Repository

Set your SignalWire Personal Access Token as an environment variable. Replace your_signalwire_pat_here with the actual token you generated.

TOKEN=your_signalwire_pat_here

Download and install the SignalWire GPG signing key. This authenticates the packages from the repository.

curl --http1.1 -fsSL https://freeswitch.signalwire.com/repo/deb/debian-release/signalwire-freeswitch-repo.gpg | sudo gpg --dearmor -o /usr/share/keyrings/signalwire-freeswitch-repo.gpg

Store your token in a file so apt can authenticate with the repository during updates.

echo "machine freeswitch.signalwire.com login signalwire password $TOKEN" | sudo tee /etc/apt/auth.conf.d/freeswitch.conf
sudo chmod 600 /etc/apt/auth.conf.d/freeswitch.conf

Add the FreeSWITCH repository to your apt sources. The SignalWire repo uses Debian Bookworm packages which are compatible with Ubuntu 24.04.

echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ bookworm main" | sudo tee /etc/apt/sources.list.d/freeswitch.list

Update the package index to pull in the FreeSWITCH packages from the new repo.

sudo apt update

If the update runs without authentication errors, the token and repo configuration are correct.

Step 4: Install FreeSWITCH

Install the FreeSWITCH meta package along with commonly needed modules. The freeswitch-meta-all package pulls in the core daemon plus a full set of modules for codecs, applications, dialplan handling, and more.

sudo apt install -y freeswitch-meta-all

This installs a substantial number of packages. If you prefer a minimal installation, use freeswitch-meta-vanilla instead, which installs only the core modules needed for basic SIP calling.

sudo apt install -y freeswitch-meta-vanilla

For production systems where you know exactly which modules you need, you can also install them individually. Some common packages include:

  • freeswitch – the core daemon
  • freeswitch-mod-commands – API commands
  • freeswitch-mod-sofia – SIP module
  • freeswitch-mod-dptools – dialplan tools
  • freeswitch-mod-dialplan-xml – XML dialplan engine
  • freeswitch-mod-console – console logging
  • freeswitch-sounds-en-us-callie – English sound files
  • freeswitch-music-default – hold music

Step 5: Enable and Start FreeSWITCH

Enable the FreeSWITCH service to start on boot and start it immediately.

sudo systemctl enable --now freeswitch

Verify the service is running. You should see active (running) in the output.

sudo systemctl status freeswitch

The output confirms the daemon is up and listening for connections:

● freeswitch.service - freeswitch
     Loaded: loaded (/lib/systemd/system/freeswitch.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-03-24 10:15:32 UTC; 5s ago
   Main PID: 4521 (freeswitch)
      Tasks: 35 (limit: 4557)
     Memory: 68.2M
        CPU: 2.145s
     CGroup: /system.slice/freeswitch.service
             └─4521 /usr/bin/freeswitch -u freeswitch -g freeswitch -ncwait

Step 6: Verify with fs_cli

FreeSWITCH ships with fs_cli, a command-line client that connects to the running instance through the Event Socket Layer (ESL) on port 8021. Use it to confirm the installation is working properly.

sudo fs_cli -x "version"

You should see the installed FreeSWITCH version confirmed:

FreeSWITCH Version 1.10.12-release~64bit (-release 64bit)

Check the status of the running instance with more detail.

sudo fs_cli -x "status"

This shows uptime, session counts, and the stack size:

UP 0 years, 0 days, 0 hours, 2 minutes, 15 seconds, 342 milliseconds, 128 microseconds
FreeSWITCH (Version 1.10.12-release 64bit) is ready
0 session(s) since startup
0 session(s) - peak 0, last 5min 0
0 session(s) per Sec out of max 30, peak 0, last 5min 0
1000 session(s) max
min idle cpu 0.00/100.00
Current Stack Size/Max 240K/8192K

To enter the interactive FreeSWITCH console, run fs_cli without the -x flag.

sudo fs_cli

Type /quit or press Ctrl+D to exit the console.

You can also list all loaded modules to verify everything initialized correctly.

sudo fs_cli -x "show modules"

Check that the SIP module (mod_sofia) is loaded and listening.

sudo fs_cli -x "sofia status"

You should see the internal and external SIP profiles listed with their listening addresses:

                     Name          Type                                       Data      State
=================================================================================================
                 internal       profile            sip:[email protected]:5060      RUNNING (0)
                 external       profile            sip:[email protected]:5080      RUNNING (0)
            external-ipv6       profile                sip:mod_sofia@[::1]:5080      RUNNING (0)
            internal-ipv6       profile                sip:mod_sofia@[::1]:5060      RUNNING (0)
=================================================================================================
4 profiles 0 aliases

Step 7: Configure the Firewall

FreeSWITCH needs several ports open for SIP signaling, RTP media, and management access. On Ubuntu, ufw is the standard firewall tool.

Open port 5060 for SIP on the internal profile (used by your phones/endpoints).

sudo ufw allow 5060/udp comment "FreeSWITCH SIP internal"
sudo ufw allow 5060/tcp comment "FreeSWITCH SIP internal TCP"

Open port 5080 for the external SIP profile (used for trunk/gateway connections).

sudo ufw allow 5080/udp comment "FreeSWITCH SIP external"
sudo ufw allow 5080/tcp comment "FreeSWITCH SIP external TCP"

Open the RTP media port range. FreeSWITCH uses UDP ports 16384 through 32768 for audio/video streams by default.

sudo ufw allow 16384:32768/udp comment "FreeSWITCH RTP media"

The Event Socket Layer (ESL) listens on port 8021. Only open this if you need remote ESL access. For local-only access (which is the default), skip this rule.

sudo ufw allow 8021/tcp comment "FreeSWITCH ESL"

Enable the firewall if it is not already active and verify the rules are in place.

sudo ufw enable
sudo ufw status verbose

The status output should show all the FreeSWITCH rules along with your SSH rule:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
5060/udp                   ALLOW       Anywhere                   # FreeSWITCH SIP internal
5060/tcp                   ALLOW       Anywhere                   # FreeSWITCH SIP internal TCP
5080/udp                   ALLOW       Anywhere                   # FreeSWITCH SIP external
5080/tcp                   ALLOW       Anywhere                   # FreeSWITCH SIP external TCP
16384:32768/udp            ALLOW       Anywhere                   # FreeSWITCH RTP media
8021/tcp                   ALLOW       Anywhere                   # FreeSWITCH ESL

In production, restrict the ESL port (8021) and SIP ports to specific IP addresses rather than allowing from anywhere. SIP scanners constantly probe port 5060 on public servers.

Step 8: Understand the FreeSWITCH Directory Structure

Knowing where FreeSWITCH keeps its files saves time when troubleshooting and customizing the system.

  • /etc/freeswitch/ – all configuration files (XML)
  • /usr/lib/freeswitch/mod/ – compiled modules (.so files)
  • /usr/share/freeswitch/sounds/ – sound files and prompts
  • /var/lib/freeswitch/ – runtime data, recordings, voicemail
  • /var/log/freeswitch/ – log files
  • /usr/bin/freeswitch – the main binary
  • /usr/bin/fs_cli – the CLI client

The main configuration entry point is /etc/freeswitch/freeswitch.xml, which includes all other XML files. The configuration is modular – SIP profiles live in /etc/freeswitch/sip_profiles/, dialplan contexts in /etc/freeswitch/dialplan/, and directory (user) definitions in /etc/freeswitch/directory/.

Step 9: Basic Configuration

The default FreeSWITCH configuration ships with a functional demo setup that includes 20 preconfigured extensions (1000-1019), conference rooms, voicemail, and IVR examples. This is useful for testing but should be replaced with your own configuration for production.

Set the Default Password

All 20 default extensions share the same password: 1234. Change this immediately, even in a lab environment. The default password is set in one place.

Open the vars.xml configuration file.

sudo vi /etc/freeswitch/vars.xml

Find the line that sets the default password and change 1234 to a strong password:

<X-PRE-PROCESS cmd="set" data="default_password=YourStr0ngP@ssword"/>

Configure the External IP Address

If your FreeSWITCH server is behind NAT (common in cloud environments), you need to set the external IP address so SIP and RTP traffic route correctly.

Open the vars.xml file again.

sudo vi /etc/freeswitch/vars.xml

Find and update the external SIP and RTP IP variables. Replace 203.0.113.50 with your actual public IP:

<X-PRE-PROCESS cmd="set" data="external_sip_ip=203.0.113.50"/>
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=203.0.113.50"/>

For servers with dynamic public IPs, you can use the auto-detection methods built into FreeSWITCH:

<X-PRE-PROCESS cmd="set" data="external_sip_ip=stun:stun.freeswitch.org"/>
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=stun:stun.freeswitch.org"/>

Change the Event Socket Password

The ESL (Event Socket Layer) uses the default password ClueCon. Change it to prevent unauthorized access to the FreeSWITCH API.

Open the Event Socket configuration.

sudo vi /etc/freeswitch/autoload_configs/event_socket.conf.xml

Change the password parameter to something unique:

<param name="password" value="YourESLpassword"/>

After making any configuration changes, reload FreeSWITCH to apply them.

sudo systemctl restart freeswitch

Verify the service is still running after the restart.

sudo systemctl status freeswitch

Step 10: Test with a Basic Dialplan Call

The default FreeSWITCH configuration includes a working dialplan with test extensions. You can verify the system works without connecting a SIP phone by using the built-in originate command to trigger a test call.

Call the default echo extension (extension 9196) which echoes back whatever audio it receives. This tests the media path.

sudo fs_cli -x "originate loopback/9196 &echo"

You should see a successful call setup confirmed:

+OK 0f3a5c6e-8b7d-4a1f-9c2e-3d5f7a8b9c0d

Check active calls to confirm the call is running.

sudo fs_cli -x "show calls"

You can also test the music-on-hold extension (9664) or the info/talking clock extension (9170). These built-in test extensions are useful for validating that codecs and audio processing work correctly.

Hang up all active test calls when done.

sudo fs_cli -x "hupall"

Register a SIP Phone

To make real calls, register a SIP softphone (like Zoiper, Linphone, or MicroSIP) using one of the preconfigured extensions. Here are the settings to use:

  • Username: 1000 (any number from 1000 to 1019)
  • Password: the password you set in vars.xml (or 1234 if unchanged)
  • Domain/Server: your FreeSWITCH server IP address
  • Transport: UDP
  • Port: 5060

Once registered, dial extension 9196 (echo test) or call between two registered extensions (e.g., 1000 calls 1001) to verify end-to-end SIP calling.

Step 11: View Logs

FreeSWITCH writes detailed logs to /var/log/freeswitch/freeswitch.log. Tail the log in real time while troubleshooting.

sudo tail -f /var/log/freeswitch/freeswitch.log

You can also change the log level from within fs_cli for more verbose output during debugging.

sudo fs_cli -x "console loglevel debug"

For SIP-specific debugging, enable SIP trace on the internal profile to see the raw SIP messages.

sudo fs_cli -x "sofia profile internal siptrace on"

Turn it off when done because SIP tracing generates a lot of output in the log files.

sudo fs_cli -x "sofia profile internal siptrace off"

Troubleshooting FreeSWITCH Installation Issues

Repository Authentication Fails

If apt update returns a 401 Unauthorized error for the SignalWire repo, your token is incorrect or expired. Verify the token at id.signalwire.com and update the auth file.

sudo cat /etc/apt/auth.conf.d/freeswitch.conf

Make sure the file contains the correct format with no extra spaces or line breaks:

machine freeswitch.signalwire.com login signalwire password pat_YOUR_ACTUAL_TOKEN

FreeSWITCH Fails to Start

Check the journal for startup errors.

sudo journalctl -u freeswitch -n 50 --no-pager

Common causes include another process already using port 5060 (like Asterisk or another SIP daemon) or incorrect XML syntax in the configuration files. Check for port conflicts with:

sudo ss -tulnp | grep -E "5060|5080|8021"

fs_cli Cannot Connect

If fs_cli returns a connection refused error, the Event Socket module may not be loaded or FreeSWITCH is not running. First confirm the service is up.

sudo systemctl status freeswitch

If the service is running but fs_cli still fails, check that the Event Socket module is configured to listen on localhost. Verify the ESL configuration.

sudo cat /etc/freeswitch/autoload_configs/event_socket.conf.xml

The listen-ip parameter should be :: or 127.0.0.1. If you changed the ESL password, pass it to fs_cli explicitly.

sudo fs_cli -p YourESLpassword

SIP Phone Cannot Register

If a softphone cannot register, check the following:

  • Firewall ports 5060/UDP and 5060/TCP are open
  • The phone is pointed at the correct IP and port
  • The extension password matches what is configured in vars.xml
  • Enable SIP trace to see the registration attempt and any error responses

No Audio on Calls (One-Way or No-Way Audio)

Audio issues are almost always NAT-related. Make sure:

  • The external_sip_ip and external_rtp_ip variables in vars.xml are set to your public IP
  • The RTP port range (16384-32768/UDP) is open in the firewall and forwarded through any NAT device
  • Your SIP phone has STUN enabled or is configured for the correct NAT traversal method

Managing FreeSWITCH

Here are the common service management commands you will use day to day.

Stop the FreeSWITCH service.

sudo systemctl stop freeswitch

Restart FreeSWITCH to apply configuration changes.

sudo systemctl restart freeswitch

Reload the XML configuration without a full restart. This is faster and does not drop active calls.

sudo fs_cli -x "reloadxml"

Reload a specific module without restarting the entire daemon.

sudo fs_cli -x "reload mod_sofia"

Frequently Asked Questions

Is the SignalWire Personal Access Token free?

Yes. You can create a free SignalWire account and generate a Personal Access Token at no cost. The token is only required to authenticate with the FreeSWITCH package repository. You do not need a paid SignalWire plan to use FreeSWITCH.

Can FreeSWITCH handle production call volumes?

FreeSWITCH is built for high-performance telephony. A single server with adequate resources (8 cores, 16 GB RAM) can handle thousands of concurrent calls. The actual capacity depends on your codec choices (G.711 uses more CPU than G.729 with hardware transcoding), whether you are doing transcoding, and how complex your dialplan logic is.

What is the difference between the internal and external SIP profiles?

The internal profile (port 5060) is for your local endpoints – IP phones, softphones, and internal devices that register with FreeSWITCH. The external profile (port 5080) is for connections to SIP trunks, PSTN gateways, and other SIP servers that do not register locally. Keep this separation to apply different security policies to each.

How do I upgrade FreeSWITCH?

Since FreeSWITCH is installed from the SignalWire apt repository, upgrading is a standard apt operation. Always back up your configuration first.

sudo cp -r /etc/freeswitch /etc/freeswitch.bak
sudo apt update && sudo apt upgrade -y
sudo systemctl restart freeswitch

Check the FreeSWITCH release notes before upgrading to understand any breaking changes.

Related Articles

Php How To Install PHP 8.1 on Ubuntu 22.04|20.04|18.04 Debian Install froxlor Server Management Panel on Ubuntu 22.04 Monitoring How To Install Nagios on Ubuntu 24.04 (Noble Numbat) Ubuntu Disable systemd-networkd on Ubuntu Linux

Leave a Comment

Press ESC to close