F1
Applications Azure

FreeSWITCH on Ubuntu 24.04 on Azure User Guide

| Product: FreeSWITCH 1.10 on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of FreeSWITCH on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. FreeSWITCH is a scalable open source soft switch: a SIP PBX, VoIP gateway, conferencing bridge, IVR and voicemail platform known for carrier grade concurrency. It runs as a headless daemon controlled through the FreeSWITCH command line client (fs_cli) and the XML configuration files in /etc/freeswitch.

The image builds the pinned official FreeSWITCH 1.10.12 source release, downloaded from files.freeswitch.org and verified against its SHA256 checksum, together with the two FreeSWITCH forks the build hard requires (sofia-sip and spandsp). It runs under systemd as the unprivileged freeswitch user.

Security by design, no default SIP password. The FreeSWITCH vanilla configuration ships a well known default SIP password (1234) for its twenty demo users, which makes an exposed soft switch a toll fraud magnet: attackers register and place premium rate calls at the owner's expense. This image ships no default SIP password. The single example user, 1000, has its SIP password set to a per instance secret generated on the first boot of every VM (openssl rand -base64 24), written to /root/freeswitch-credentials.txt (mode 0600, root only). The captured image ships only a placeholder, and the soft switch never runs with that placeholder because the service is held disabled until first boot rotates the secret.

Security by design, no default Event Socket password. The FreeSWITCH Event Socket (ESL) is a full remote control channel. Its vanilla default password ClueCon, bound to all interfaces on port 8021, is a notorious remote takeover hazard. This image binds the Event Socket to loopback 127.0.0.1:8021 only and sets a per instance ESL password generated on first boot, so it is never reachable from the network and never uses a known password.

Security by design, no anonymous SIP and no toll fraud route. The internal SIP profile requires authentication and rejects unidentified requests, so there is no anonymous registration. The external, PSTN facing SIP profile and its gateway examples are removed, and the shipped dialplan contains only local test extensions (an echo test, a conference room, and local user to user calls) with no bridge to a SIP gateway and no PSTN route, so even a compromised endpoint cannot dial out and run up a bill until you deliberately add a gateway and an outbound context yourself.

What is included:

  • FreeSWITCH 1.10.12, built from the pinned official source release (SHA256 verified), run under systemd as the unprivileged freeswitch user (freeswitch.service)

  • A minimal hardened /etc/freeswitch: no default SIP password, one example 1000 user, the internal SIP profile on a UDP and TCP transport on port 5060, and a dialplan with local test extensions only

  • A per instance SIP secret for user 1000 and a per instance Event Socket password generated on first boot, documented in /root/freeswitch-credentials.txt (0600), so no image ever ships a usable or default credential

  • The Event Socket bound to loopback only (127.0.0.1:8021), and no anonymous SIP and no PSTN or gateway route in the shipped dialplan, so there is no toll fraud exposure out of the box

  • Call recordings, voicemail, the core database and CDRs on a dedicated 20 GiB Azure data disk mounted at /var/lib/freeswitch, so call state survives independently of the OS disk

  • external_rtp_ip and external_sip_ip set from the VM public IP on first boot so SIP and RTP traverse NAT correctly

  • A bundled SIP self test client (sipexer) so you can prove registration and place the echo test call from the VM itself

  • A tiny nginx on port :80 serving only an unauthenticated /healthz endpoint (HTTP 200) for Azure Load Balancer health probes, which is not a management interface

  • Ubuntu 24.04 LTS base with latest security patches applied at build time, and unattended security upgrades kept enabled

  • Azure Linux Agent for seamless cloud integration and SSH key injection

  • 24/7 cloudimg support with a guaranteed 24 hour response SLA

Prerequisites

  • Active Azure subscription, SSH public key, VNet and subnet in the target region

  • Subscription to the FreeSWITCH listing on Azure Marketplace

  • Network Security Group rules allowing TCP 22 (admin), UDP and TCP 5060 (SIP), the RTP media range UDP 16384 to 16484 (call audio), and TCP 80 (health probe)

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is a comfortable starting point for a small soft switch with a handful of concurrent calls. Scale up for heavier call volumes, transcoding, or large conferences.

Step 1: Deploy from the Azure Portal

Search FreeSWITCH in Marketplace, select the cloudimg publisher, and click Create. Configure the Network Security Group to allow TCP 22 for administration, UDP and TCP 5060 for SIP signalling, UDP 16384 to 16484 for RTP media, and TCP 80 for the health probe. Assign a public IP so remote softphones can register.

Step 2: Deploy from the Azure CLI

RG="voip-prod"; LOCATION="eastus"; VM_NAME="freeswitch1"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/freeswitch-ubuntu-24-04/versions/<version>"

az group create --name "$RG" --location "$LOCATION"

az vm create --resource-group "$RG" --name "$VM_NAME" \
  --image "$GALLERY_IMAGE_ID" --size Standard_B2s \
  --admin-username azureuser --generate-ssh-keys --public-ip-sku Standard

# SIP signalling (UDP + TCP 5060), RTP media (UDP 16384-16484), health probe (TCP 80)
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 5060 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 16384-16484 --priority 1002
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1003

The Azure Marketplace recommended NSG declares a narrowed RTP range (UDP 16384 to 16403) to stay within the platform's per rule port limit. The image and this guide use the full UDP 16384 to 16484 range; widen your NSG rule to match the range you need for your expected concurrent call volume.

Step 3: First boot

On the first boot of every VM the freeswitch-firstboot.service runs once. It resolves the VM public IP from Azure IMDS and writes it as the SIP and RTP external address, generates the per instance SIP secret for user 1000 and the per instance Event Socket password, asserts that no default password, anonymous endpoint or gateway route is present, then starts FreeSWITCH and nginx. Allow about 30 to 60 seconds after the VM is first reachable.

Step 4: Confirm the service is running

SSH in and confirm FreeSWITCH and nginx are active and FreeSWITCH is running as the unprivileged freeswitch user.

sudo systemctl is-active freeswitch nginx
sudo fs_cli -x "version"
sudo fs_cli -x "status"
curl -s -o /dev/null -w "healthz: %{http_code}\n" http://127.0.0.1/healthz

FreeSWITCH 1.10.12 running under systemd with the freeswitch and nginx services both active, fs_cli version reporting FreeSWITCH 1.10.12, status reporting the switch is UP, and the process running as the unprivileged freeswitch user

Step 5: Inspect the SIP profile

FreeSWITCH listens for SIP on UDP and TCP port 5060 through the internal profile, which must be in the RUNNING state.

sudo fs_cli -x "sofia status"
sudo fs_cli -x "sofia status profile internal"

FreeSWITCH sofia status showing the internal SIP profile bound to port 5060 in the RUNNING state, with the external profile deliberately absent so there is no PSTN facing surface

Step 6: Register a softphone as user 1000

Read the per instance SIP secret (unique to this VM) from the root only credentials file, then register. The bundled sipexer client lets you prove registration from the VM itself; a desktop or mobile softphone (for example Zoiper, Linphone or MicroSIP) registers the same way from your network.

sudo cat /root/freeswitch-credentials.txt
# register as user 1000 using the per instance secret (substitute the value from the file above).
# use the VM private IP as the SIP domain (FreeSWITCH sets $${domain} to the local IP).
IP=$(hostname -I | awk '{print $1}')
sudo /usr/local/bin/sipexer -register -fuser 1000 -au 1000 -ap '<SIP_SECRET>' -ex 300 udp:$IP:5060
sudo fs_cli -x "sofia status profile internal reg"

To register a softphone from your own device, point it at the VM public IP on port 5060, username 1000, and the secret from the file above. A wrong secret is rejected, and an unauthenticated registration is refused, because there is no anonymous SIP.

A SIP REGISTER as user 1000 using the per instance secret returning 200 OK, a wrong secret being rejected with 401 or 403, and an authenticated call to echo test extension 9196 answering with 200 OK

Step 7: Place the echo test call

With the softphone registered, dial 9196 for the announced echo test, or *43 for the bare echo test. You will hear your own audio played back, which proves registration, call setup and two way RTP media all work. Dial 3000 for a local conference room.

# authenticated self call to the echo test extension (from the VM, using the bundled client)
IP=$(hostname -I | awk '{print $1}')
sudo /usr/local/bin/sipexer --register-first --invite -fuser 1000 -au 1000 -ap '<SIP_SECRET>' -tuser 9196 udp:$IP:5060 2>&1 \
  | grep -aE 'SIP/2.0 (100|180|200)' || true

Step 8: The hardened, no toll fraud configuration

The shipped configuration is deliberately minimal. User 1000 requires authentication with the per instance secret, the secret itself lives in a root only vars.d include outside the main file, the Event Socket is bound to loopback with a per instance password, and the dialplan has only local test extensions with no gateway bridge and no PSTN route.

# the Event Socket is bound to loopback only, with a per instance password (redacted)
sudo grep -E 'listen-ip|listen-port' /etc/freeswitch/autoload_configs/event_socket.conf.xml
sudo ss -ltn | grep 8021

# the dialplan has only local test extensions, no sofia/gateway bridge
sudo grep -E 'destination_number|application="bridge"' /etc/freeswitch/dialplan/default.xml

# the external, PSTN facing profile is absent
ls /etc/freeswitch/sip_profiles/

The hardened configuration: the Event Socket bound to loopback 127.0.0.1 port 8021 with a redacted per instance password, the dialplan showing only local test extensions with no gateway bridge, and the sip_profiles directory containing only the internal profile with no external PSTN facing profile

Step 9: Add your own users, gateways and outbound dialing

To build a real soft switch, add your own users in /etc/freeswitch/directory/default, and add a SIP gateway and an outbound context when you are ready to make external calls. Keep outbound dialing in its own context that only trusted, authenticated users can reach, and always restrict the patterns a gateway will dial.

# example: add a new user 1001 (edit as root, then reload)
sudo tee /etc/freeswitch/directory/default/1001.xml >/dev/null <<'EOF'
<include>
  <user id="1001">
    <params>
      <param name="password" value="<new-strong-password>"/>
      <param name="vm-password" value="<new-vm-pin>"/>
    </params>
    <variables>
      <variable name="user_context" value="default"/>
      <variable name="effective_caller_id_name" value="Extension 1001"/>
      <variable name="effective_caller_id_number" value="1001"/>
    </variables>
  </user>
</include>
EOF
sudo fs_cli -x "reloadxml"

Only introduce a bridge to a SIP gateway from a context that your trusted users reach, and never expose an outbound gateway to an unauthenticated context.

Step 10: Call state and the data disk

Call recordings, voicemail, the core database and CDRs are written under /var/lib/freeswitch, which is a dedicated 20 GiB Azure data disk, so they persist independently of the OS disk and the volume is independently resizable.

findmnt /var/lib/freeswitch
sudo ls -la /var/lib/freeswitch

Step 11: NAT, TLS, SRTP and WebRTC for production

First boot sets the SIP and RTP external addresses to the VM public IP so calls traverse NAT. For production, add a TLS transport on port 5061 and enable SRTP so signalling and media are encrypted, and consider enabling WebRTC (the Verto or SIP over WebSocket profiles) with a certificate for your own domain.

  • Keep UDP and TCP 5060 and the RTP range open only to the networks that need them, and prefer TLS on 5061 for remote phones

  • Use strong, unique secrets for every user, and never reuse the 1000 credential in production

  • Restrict outbound dialing patterns on every gateway to limit the blast radius of any compromised endpoint

Step 12: Support and Licensing

FreeSWITCH is licensed under the Mozilla Public License 1.1 (MPL 1.1). This image bundles the official FreeSWITCH release plus a minimal hardened configuration and the open source sipexer self test client (MIT). cloudimg provides the packaging, hardening and Azure integration, with 24/7 support and a guaranteed 24 hour response SLA.

Trademark notice. FreeSWITCH is a mark of SignalWire. cloudimg is not affiliated with or endorsed by SignalWire. This image packages the open source FreeSWITCH software for convenient deployment on Azure.

Deploy on Azure

Find FreeSWITCH on Ubuntu 24.04 LTS by cloudimg on the Azure Marketplace and click Create, or deploy from the Azure CLI as shown above.

Need Help?

Contact cloudimg support at support@cloudimg.co.uk for deployment assistance, configuration guidance, or licensing questions.