Self-Hosting a VoIP PBX on Raspberry Pi with Asterisk and FreePBX
This site covers a long list of things a Raspberry Pi can self-host — DNS, VPNs, NAS storage, media servers, home automation — but not the one that turns a Pi into an actual phone system. Asterisk is the open-source telephony engine behind most DIY and small-business PBX deployments, and FreePBX is the web GUI that makes configuring it tolerable without memorizing its dialplan syntax. Together they let a Raspberry Pi handle internal extension-to-extension calling, route calls out through a SIP trunk provider (voice-over-IP calling without a traditional phone line), run an intercom or doorbell system, and even bridge into ham radio digital voice hardware this site already covers for MMDVM hotspots. This guide covers getting Asterisk and FreePBX running on a Pi, registering SIP extensions, and connecting an outbound trunk.
What You're Actually Building
A PBX (Private Branch Exchange) is the switchboard that used to be a room full of humans plugging in patch cords — it routes calls between internal extensions and decides how to hand off calls to the outside world. In this build, "extensions" are SIP (Session Initiation Protocol) endpoints: a softphone app on your phone, a physical desk VoIP phone, or an ATA (analog telephone adapter) that lets you plug in an old-fashioned handset. Calling out to the public phone network requires a SIP trunk — a service that bridges VoIP calls to the traditional phone network — from a provider rather than anything the Pi does on its own.
Hardware and OS Requirements
ComponentRecommendation Raspberry PiPi 4 (4GB+) or Pi 5 — Asterisk itself is light, but FreePBX's web stack (Apache/Nginx, MariaDB, PHP) benefits from more RAM than a Pi 3 comfortably offers StorageA quality SD card is workable for testing; for anything left running as a real phone system, boot from USB SSD as covered in this site's Pi power/storage guides — a PBX doing call detail record logging writes to the database on every call NetworkWired Ethernet strongly preferred — voice quality is sensitive to WiFi jitter and packet loss in a way most other self-hosted services aren't OSDebian-based (Raspberry Pi OS Lite, 64-bit) — FreePBX's installer and package ecosystem assume a Debian/RHEL-family baseInstalling Asterisk
Rather than compiling Asterisk from source, install it from a maintained ARM-compatible package repository or use the widely-used community install script for Raspberry Pi, which handles the dependency chain (build tools, DAHDI if you need analog hardware support, and the core Asterisk modules) automatically. A minimal Asterisk install with no analog telephony hardware doesn't need DAHDI at all — skip it unless you're connecting a physical PSTN line card.
Once installed, confirm the service is running and reachable on the SIP signaling port before layering FreePBX on top:
- sudo systemctl status asterisk should show active (running)
- sudo asterisk -rvvv drops you into the Asterisk console for live diagnostics — leave this open in a second terminal while testing
- Confirm UDP port 5060 (SIP signaling) is listening with sudo ss -ulnp | grep 5060
Installing FreePBX
FreePBX needs Apache (or Nginx), PHP, and MariaDB alongside Asterisk — install these first, then run the FreePBX installer against your existing Asterisk instance rather than letting it install its own Asterisk copy, since version mismatches between a manually-installed Asterisk and what FreePBX expects are the single most common source of a broken first install. After the installer finishes, FreePBX serves its configuration UI on port 80 (or 443 if you've set up TLS) — the first login creates the admin account.
From the FreePBX dashboard, the two screens that matter for a first working system are Applications → Extensions (where you create each SIP endpoint) and Connectivity → Trunks (where you configure the outbound provider, if any).
Creating Extensions
Add a new extension under Applications → Extensions, choosing "chan_pjsip" as the technology — PJSIP is the modern SIP stack in current Asterisk versions and should be preferred over the legacy chan_sip driver, which is deprecated. Set an extension number (e.g. 1001), a secret (the SIP password), and a display name. Each extension you create is one registerable endpoint — install a SIP softphone app on your phone (many free options exist) and register it against your Pi's IP address using that extension number and secret to get a first working test call.
Dial another registered extension's number from one softphone to another and confirm two-way audio — this is the entire internal-calling functionality working with zero external dependencies, and it's the right checkpoint before touching trunk configuration.
Connecting an Outbound SIP Trunk
To call real phone numbers, you need a SIP trunk from a VoIP provider — a service that terminates calls to the traditional phone network for a per-minute or flat monthly rate. Under Connectivity → Trunks, add a new PJSIP trunk with the credentials (SIP server hostname, username, and password/registration string) your chosen provider issues. Most providers publish an Asterisk or generic PJSIP configuration example directly in their documentation, which maps cleanly onto FreePBX's trunk fields.
Once the trunk shows as registered (check under Reports → Asterisk Info, or via the Asterisk console with pjsip show registrations), set up an outbound route under Connectivity → Outbound Routes matching your local dial pattern to that trunk, and an inbound route so calls to your assigned number ring the extensions you want.
Network Considerations: NAT and Firewalls
SIP is notoriously unfriendly to NAT because the protocol embeds IP addresses inside its own signaling payload, not just at the network layer — a phone behind a home router can register successfully but then have one-way or no audio because the media (RTP) stream can't find its way back through the NAT translation. In FreePBX's Asterisk SIP Settings, set the external address to your public IP (or a dynamic DNS hostname if it changes) and the local network range so Asterisk knows to rewrite SIP headers appropriately for devices on the LAN versus those calling in from outside.
- If you want extensions to register from off your home network (a phone app while traveling), forward UDP 5060 and the RTP media port range (commonly 10000-20000, configurable and worth narrowing down from the default range) through your router to the Pi.
- Exposing SIP directly to the internet without hardening is a real target for automated toll fraud bots that scan for open PBX systems — see the security section below before opening any ports.
- A VPN (WireGuard, as covered in this site's Pi VPN guides) between remote phones and the home network avoids exposing SIP to the internet at all, at the cost of needing the VPN client active on every remote device.
Security: Don't Skip This
An internet-reachable Asterisk PBX with a weak extension password is one of the most reliably abused misconfigurations in self-hosted infrastructure — automated scanners register fraudulent extensions or hijack real ones and route expensive international calls through your trunk, sometimes racking up real charges before anyone notices.
- Use long, random extension secrets, never the extension number itself or a short numeric PIN.
- Enable Fail2Ban (FreePBX's Intrusion Detection module wraps this) to automatically block IPs that fail repeated SIP registration attempts.
- Restrict outbound international/premium-rate dialing on your outbound routes unless you specifically need it — this limits the financial damage of any account that is compromised despite the above.
- Keep FreePBX and its modules updated — the module admin panel flags available security updates, and toll-fraud campaigns specifically target known-vulnerable older versions.
- Put the whole PBX on its own VLAN if you're already segmenting IoT and shop devices per this site's VLAN guide — there's no reason a phone system needs to share a broadcast domain with a 3D printer.
Beyond Basic Calling: What Else the Pi Can Do
- Intercom / doorbell integration — an ATA-connected doorbell button or a SIP-capable video doorbell can ring every registered extension simultaneously, turning any softphone into a house intercom.
- Voicemail and IVR menus — FreePBX's built-in voicemail and Interactive Voice Response modules configure through the same web UI without extra software.
- Bridging to Home Assistant — Asterisk's AMI (Asterisk Manager Interface) exposes call events that Home Assistant or Node-RED can react to, letting an incoming call trigger a smart-home announcement or a doorbell chime through existing speakers.
Asterisk and FreePBX turn a Raspberry Pi into infrastructure that used to require a dedicated appliance costing hundreds of dollars — but unlike most of the self-hosted services on this site, a misconfigured PBX has a real financial exposure if left open to the internet, not just a privacy risk. Get internal extension-to-extension calling working and confirmed first, lock down security before touching an outbound trunk, and treat the trunk credentials with the same care as any other set of billing-linked API keys.
Related Guides
- Backing Up Self-Hosted Services on Raspberry Pi with Restic and Borg
- Self-Hosting Syncthing on a Raspberry Pi: Real-Time File Sync Without the Cloud
- Running Your Own Recursive DNS Resolver on Raspberry Pi with Unbound: Full DNS Privacy Beyond Pi-hole
- Self-Hosting a Git Server on Raspberry Pi with Gitea
- Self-Hosting Jellyfin Media Server on a Raspberry Pi: Hardware Transcoding and Remote Access
- Build an AllStarLink Node with Raspberry Pi: Linking Repeaters and Hotspots Over the Internet
- How to Install Klipper on Any 3D Printer: Complete Setup Guide
- How to Set Up OpenCV Machine Vision on a Raspberry Pi