- backup.sh: weekly PostgreSQL dump + FreeSWITCH/nginx/fail2ban configs - restore.sh: 10-phase interactive restore wizard - README.md: full rebuild guide, PBX reference, SSH relay instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FusionPBX Config Backup & Restore
Weekly backup of the FusionPBX/FreeSWITCH PBX server (fusion, 134.209.72.226).
Debian 12, FreeSWITCH, FusionPBX, PostgreSQL 18, nginx, PHP 8.2.
Critical: The Database IS the Config
FusionPBX stores everything in PostgreSQL (fusionpbx database):
- Extensions, voicemail boxes, passwords
- Dialplans and call routing
- SIP gateways (SignalWire trunk)
- IVR menus
- Ring groups
- Device provisioning (Yealink T48S settings)
- Users and permissions
- Call recordings index
The database/fusionpbx.sql dump in this repo is the heart of the backup.
What's Backed Up
| Directory | Source | Contents |
|---|---|---|
database/ |
pg_dump fusionpbx |
Complete FusionPBX database — extensions, dialplans, SIP, IVR, everything |
database/postgres_globals.sql |
pg_dumpall --globals |
PostgreSQL roles and passwords |
freeswitch/ |
/etc/freeswitch/ |
vars.xml, sip_profiles, key autoload configs |
fusionpbx-app/ |
/var/www/fusionpbx/resources/ |
config.php (DB credentials) |
nginx/ |
/etc/nginx/sites-enabled/ |
fusionpbx nginx config (incl. all provisioning URL rewrites) |
fail2ban/ |
/etc/fail2ban/ |
jail.local (trusted IPs: 107.178.2.130, 97.154.109.245) |
network/ |
/etc/netplan/ |
50-cloud-init.yaml, hosts, hostname |
systemd/ |
/etc/systemd/system/ |
All FusionPBX service units |
ssh/ |
/root/.ssh/ |
authorized_keys |
recordings/ |
/var/lib/freeswitch/recordings/ |
Call recordings (~3.7MB) |
Backup schedule: Every Sunday at 5:00 AM
Log: /var/log/fusionpbx-backup.log
Manual trigger: /usr/local/bin/fusionpbx-backup
SSH Access — Important
Port 22 is firewalled from the internet. Only accessible from:
107.178.2.130(your home FortiGate external IP)97.154.109.245(FortiGate secondary)
From anywhere else, relay through DO:
ssh root@165.22.1.228 # DO server (always accessible)
ssh root@134.209.72.226 # then hop to FusionPBX
Disaster Recovery — Full Rebuild
Estimated time: 30–45 minutes
Step 1 — New Debian 12 Droplet
Create a fresh Debian 12 droplet on DigitalOcean, same region as original.
Get SSH access, then relay via the DO server if needed.
Step 2 — Clone this repo and run restore
apt update && apt install -y git
git clone https://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@github.com/myronblair/fusionpbx-config.git /opt/fusionpbx-config
bash /opt/fusionpbx-config/restore.sh
The restore script walks through all phases interactively.
Step 3 — Update fail2ban trusted IPs if FortiGate IP changed
The FortiGate DDNS (orbisne.fortiddns.com) resolves to your home IP.
If your external IP changed, update fail2ban/jail.local:
ignoreip = 127.0.0.1/8 ::1 <new-home-ip> 97.154.109.245
Step 4 — Update Yealink provisioning URL if server IP changed
If the new droplet has a different IP, update the Yealink T48S provisioning:
Old URL: http://134.209.72.226/app/provision/?mac={mac}
New URL: http://<new-ip>/app/provision/?mac={mac}
Set via Yealink web UI or FusionPBX → Apps → Provision → Devices.
PBX Quick Reference
| Item | Value |
|---|---|
| FusionPBX web | https://fusion.orbishosting.com |
| Admin login | admin / fY7XP5swgtpbzrYLhkeVYkA4744 |
| Root SSH | root / Joker1974!@# |
| PostgreSQL DB | fusionpbx (user: fusionpbx) |
| FreeSWITCH CLI | fs_cli |
| SIP trunk | SignalWire (mod_signalwire) |
| SIP profile | Use internal profile on port 5060 |
| NAT setting | aggressive-nat-detection=true |
Extensions
| Ext | Name | Device | Location |
|---|---|---|---|
| 1000 | Myron | Yealink T48S | 10.48.200.43 (FortiGate LAN) |
| 1001 | Tommy | Softphone | Remote |
| 1002 | (spare) | — | — |
| 900 | IVR | Main number auto-attendant | — |
Key Commands
# FreeSWITCH CLI
fs_cli
# Inside fs_cli:
sofia status # show SIP profiles
sofia status gateway # show gateway registrations
show registrations # show registered extensions
reload mod_sofia # reload SIP after config change
reloadxml # reload dialplan XML
# Force FusionPBX to regenerate FreeSWITCH XML cache
rm /var/cache/fusionpbx/FusionPBX.configuration.sofia.conf
systemctl restart freeswitch
# Check all FusionPBX services
systemctl status active_calls active_conferences email_queue event_guard \
fax_queue system_status transcribe_queue websockets xml_cdr
# Logs
journalctl -u freeswitch -f
tail -f /var/log/freeswitch/freeswitch.log
tail -f /var/log/nginx/access.log
What Is NOT Backed Up
| Item | Notes |
|---|---|
| SSL certs | /etc/letsencrypt/ — re-issue: certbot --nginx -d fusion.orbishosting.com |
| FusionPBX web app | /var/www/fusionpbx/ — reinstalled by official installer |
| FreeSWITCH binary | Installed by FusionPBX installer |
| Voicemail audio files | /var/lib/freeswitch/storage/voicemail/ — small, not critical |
Architecture Notes
- FusionPBX uses a Lua XML handler — FreeSWITCH queries PostgreSQL via PHP/Lua for all routing decisions. No static XML dialplan files in production.
- SignalWire SIP trunk uses
transport=udp— critical, TCP caused re-INVITE issues. - ext 1000 (Yealink T48S) registers from behind FortiGate using
aggressive-nat-detection=trueon port 5080 to bypass SIP ALG. - FusionPBX cache:
/var/cache/fusionpbx/FusionPBX.configuration.sofia.conf— delete this file to force a full Sofia reload after changes.