These scripts allow you to configure VoIP service for customers who have replaced their ISP router with a Unifi gateway based on UnifiOS (Cloud Gateways (UCG-XX), Gateways (UXG-XX), Dream routers (UDM-XX), etc...).
Since it is currently impossible to configure via the Unifi GUI a WAN interface with multiple VLANs, as someone would expect from such prosumer products to have, in contrast to 10$ devices and default isp ONTs.. a new interface is created with your desired VLAN ID, which handles VoIP traffic routing to your local network.
Tested on Unifi Cloud Gateway Fiber (UCG-Fiber) with UnifiOS.
- A UniFi gateway running UniFiOS (UCG-Fiber, UCG-Max, UDM-Pro, UXG-Pro, etc.)
- SSH access to the gateway
- Your ISP's VoIP delivered on a VLAN tag on the same WAN port as internet (common with FTTH IMS/SIP services)
- A SIP softphone or ATA on your LAN (e.g. MicroSIP, Grandstream, Cisco SPA)
As previously mentioned, SSH access to the gateway is required.
On the gateway, download this repository into the /data/voip directory (the /data content is preserved during reboots and firmware upgrades):
cd /data
curl -sL https://github.com/maverick-bytes/voip/archive/refs/heads/main.tar.gz | tar -xvz
mv voip-main voip
cd voipMake the scripts executable:
chmod +x voip voipdInstall by running:
cd /data/voip
./voip install
./voip install-ui
You can then open <gateway-ip>/voip in your browser to configure the VoIP service using the Web UI (recommended), or manually edit the configuration file:
vi /data/voip/voipd.confA full example configuration with all available options is available in voipd.conf.example.

| Mode | Description |
|---|---|
b2bua_netns |
Default (recommended). A sandboxed SIP Back-to-Back User Agent running inside a Linux network namespace, connected to the router via a veth pair. All SIP traffic traverses the UniFiOS ALIEN/TOR threat intelligence blocking and IPS (via the FORWARD chain), and security inspection chains before reaching the IMS network. Requires VOIP_B2BUA_USER, VOIP_B2BUA_PASS, VOIP_B2BUA_DOMAIN, and PCSCF_HOSTNAME to be set. |
b2bua |
(Deprecated.) Non-sandboxed SIP Back-to-Back User Agent running directly on the router. Upstream SIP/RTP is router-originated (OUTPUT chain) so ALIEN/TOR blocking and IPS do not apply. PCSCF_HOSTNAME is not required. Kept for compatibility — use b2bua_netns for new deployments. |
pbr |
Policy-Based Routing. Creates a dedicated routing table and ip rules so IMS traffic always exits via the voip interface, regardless of UniFiOS default WAN priority. LAN clients register directly to the ISP's SIP proxy. |
forward |
Routes IMS traffic through one or more existing VLAN interfaces (VOIP_FORWARD_INTERFACE). Use if you want to steer traffic through a different port or pre-existing VLAN. |
Common settings (all modes)
-
VOIP_WAN_INTERFACE: Physical WAN port the VoIP VLAN is attached toeth4oreth6on UCG-Fibereth9on some UDM models
-
VOIP_WAN_VLAN: VLAN ID your ISP uses for VoIP traffic (verify with your ISP or ONT) -
PCSCF_HOSTNAME: Your ISP's SIP proxy hostname — resolved at startup using DNS from the VoIP DHCP lease
B2BUA NETNS mode settings (ROUTING_MODE="b2bua_netns") (recommended)
Note:
b2bua_netnsrequires a validPCSCF_HOSTNAMEso the daemon can resolve the P-CSCF address and route SIP inside the network namespace. Make sure this is set correctly before starting the service.
-
PCSCF_HOSTNAME: Your ISP's P-CSCF hostname — resolved at startup using DNS from the VoIP DHCP lease. Required in this mode. -
VOIP_B2BUA_USER/VOIP_B2BUA_PASS/VOIP_B2BUA_DOMAIN: ISP SIP credentials the B2BUA uses to register upstream to the IMS network -
VOIP_B2BUA_LISTEN_PORT: Local SIP port (UDP + TCP) that LAN clients register to — default5060 -
VOIP_B2BUA_LOCAL_USER/VOIP_B2BUA_LOCAL_PASS: Optional credentials to require from LAN clients when registering. Leave empty to allow any LAN client without authentication. -
VOIP_B2BUA_REG_EXPIRES: REGISTER refresh interval in seconds — default600
In B2BUA NETNS mode, configure your SIP softphone or ATA as follows:
- SIP Server / Registrar: your gateway IP address (shown in the web UI Status page)
- SIP Username: your local username (or your ISP number if no local auth is set)
- SIP Password: your local password (or your ISP password if no local auth is set)
- Transport: UDP or TCP
B2BUA mode settings (ROUTING_MODE="b2bua") (deprecated — use b2bua_netns)
-
VOIP_B2BUA_USER/VOIP_B2BUA_PASS/VOIP_B2BUA_DOMAIN: ISP SIP credentials the B2BUA uses to register upstream to the IMS network -
VOIP_B2BUA_LISTEN_PORT: Local SIP port (UDP + TCP) that LAN clients register to — default5060 -
VOIP_B2BUA_LOCAL_USER/VOIP_B2BUA_LOCAL_PASS: Optional credentials to require from LAN clients when registering. Leave empty to allow any LAN client without authentication. -
VOIP_B2BUA_REG_EXPIRES: REGISTER refresh interval in seconds — default600
In B2BUA mode, configure your SIP softphone or ATA as follows:
- SIP Server / Registrar: your gateway IP address (shown in the web UI Status page)
- SIP Username: your local username (or your ISP number if no local auth is set)
- SIP Password: your local password (or your ISP password if no local auth is set)
- Transport: UDP or TCP
PBR mode settings (ROUTING_MODE="pbr")
In PBR mode, configure your SIP softphone or ATA as follows:
- SIP Server / Registrar: the P-CSCF IP shown in the status banner / web UI
- SIP Username / Password: your ISP-provided credentials
- Transport: UDP/TCP/TLS
Forward mode settings (ROUTING_MODE="forward")
VOIP_FORWARD_INTERFACE: The VLAN interface(s) to route IMS traffic throughbr0= default LAN bridgebr102= VLAN 102 bridge- Multiple interfaces:
"br0 br102"
VPN / WireGuard support (optional)
VOIP_VPN_INTERFACES: Space-separated WireGuard interface names to allow VoIP traffic from. Enables SIP/RTP over Teleport or the built-in WireGuard VPN server. Disabled by default — opt-in only.- Find your WireGuard interface:
ip link show type wireguard - UniFi naming convention:
wgsrv1(VPN Server),wgcli1(VPN Client),wgs2s1(Site-to-Site) - Example:
VOIP_VPN_INTERFACES="wgsrv1" - Can also be configured from the web UI under Config → VPN Support
- Find your WireGuard interface:
The script auto-detects the IMS subnet from the DHCP-assigned IP on the voip interface:
| First octet | Subnet used |
|---|---|
10.x.x.x |
10.0.0.0/8 |
100.x.x.x |
100.64.0.0/10 |
172.x.x.x |
172.16.0.0/12 |
192.x.x.x |
192.168.0.0/16 |
| Other | 10.0.0.0/8 (fallback) |
To override: set VOIP_IMS_SUBNET="x.x.x.x/y" in voipd.conf.
After running ./voip install-ui, the web interface is accessible at https://<gateway-ip>/voip.
It provides:
- Status page: service state, VoIP IP, gateway, routing mode, IMS subnet, and the SIP registrar address to use in your client
- Config page: all settings including routing mode, B2BUA credentials, VPN support — save triggers an automatic service restart
- Logs page: live journalctl output with colour-coded log levels
- Commands page: install, reinstall, update and uninstall actions with full output returned in the browser
Check the service is running:
systemctl status voipdView logs and confirm the SIP address:
journalctl -u voipd -fThe status banner shows everything you need. In B2BUA NETNS mode:
==========================================================
VoIP -- Running
==========================================================
Interface : voip (VLAN 11 on <wan-port>)
VoIP IP : 10.x.x.x
Gateway : 10.x.x.1
Routing : b2bua_netns (sandboxed SIP proxy via veth/netns)
IMS subnet: 10.0.0.0/8
NAT : MASQUERADE in UBIOS_POSTROUTING_USER_HOOK
----------------------------------------------------------
SIP Proxy : 10.x.x.x (upstream P-CSCF, used by B2BUA)
SIP Client: register to 192.168.x.1:5060 (local B2BUA)
==========================================================
In PBR mode:
==========================================================
VoIP -- Running
==========================================================
Interface : voip (VLAN 11 on <wan-port>)
VoIP IP : 10.x.x.x
Gateway : 10.x.x.1
Routing : PBR -> table <n> (voip)
IMS subnet: 10.0.0.0/8
NAT : MASQUERADE in UBIOS_POSTROUTING_USER_HOOK
----------------------------------------------------------
SIP Proxy : 10.x.x.x <-- use this in your SIP client / ATA
==========================================================
Verify routing is correct (PBR and B2BUA modes):
# Routing table (replace <n> with your VOIP_RT_TABLE value)
ip route show table <n>
# Policy rules (two entries at priority 100/101)
ip rule show | grep -E "100:|101:"
# Confirm IMS traffic exits via voip
ip route get <your-ISP-SIP-proxy-IP>The /data directory persists across reboots and firmware upgrades on UniFiOS. The systemd service file in /etc/systemd/system/ does not persist after a firmware upgrade. Reinstall it with:
cd /data/voip
./voip install
./voip install-uicd /data/voip
./voip updateThis downloads the latest release, replaces all scripts (including b2bua.py), and restarts the service. Your voipd.conf is preserved.
cd /data/voip
./voip uninstall
chmod +x uninstall.sh && ./uninstall.sh
./voip uninstall-ui
rm -rf /data/voipip addr show voip
journalctl -u systemd-networkd -n 30The VLAN ID or WAN interface name may be wrong for your device model.
The script reads the DNS server from the DHCP lease file at /run/systemd/netif/leases/<index>. Verify:
IFIDX=$(ip link show voip | awk -F': ' 'NR==1{print $1}')
cat /run/systemd/netif/leases/$IFIDXYou should see a DNS= line. Then test manually:
DNS=$(grep "^DNS=" /run/systemd/netif/leases/$IFIDX | cut -d= -f2 | awk '{print $1}')
nslookup <your-pcscf-hostname> $DNSCheck the B2BUA log:
cat /var/run/voipd/b2bua.logCommon causes:
VOIP_B2BUA_USER,VOIP_B2BUA_PASSorVOIP_B2BUA_DOMAINnot set invoipd.conf- P-CSCF hostname not resolved — check the DNS troubleshooting step above
- ISP credentials incorrect — verify with your ISP
Enable debug logging by setting VOIP_DEBUG="true" in voipd.conf and restarting the service.
Monitor SIP traffic on both interfaces simultaneously:
# Terminal 1 — traffic leaving to ISP
tcpdump -i voip -n port 5060
# Terminal 2 — traffic reaching your LAN
tcpdump -i br0 -n port 5060If packets appear on voip but replies don't appear on your LAN bridge, check conntrack:
conntrack -L 2>/dev/null | grep <SIP-proxy-IP>The reply direction dst should be your voip IP, not your internet IP.
Do not load nf_nat_sip or nf_conntrack_sip. These modules rewrite SDP in-flight and corrupt SRTP key material. Modern IMS networks use symmetric RTP and do not need SIP ALG.
# Confirm these are NOT loaded
lsmod | grep sip
# Expected: no outputBy default VPN clients cannot reach the VoIP network. Set VOIP_VPN_INTERFACES to your WireGuard interface name:
ip link show type wireguardThen either set it in voipd.conf:
VOIP_VPN_INTERFACES="wgsrv1"Or enable it from the web UI under Config → VPN Support, tick the interface, and save.
Q: What VLAN ID should I use? A: See the local VLAN ID in your area — the default in this script is VLAN 11. You can verify by checking your ISP ONT web-ui WAN page or using OMCI commands via telnet from your aftermarket ONT unit.
Q: What is the difference between B2BUA NETNS, B2BUA, and PBR mode? A: B2BUA NETNS (recommended): your LAN clients register to the gateway using a local account, and the gateway handles the upstream IMS registration inside a sandboxed network namespace. Upstream SIP/RTP passes through the FORWARD chain where UniFi applies ALIEN/TOR threat intelligence blocking and IPS unconditionally (the voip interface is not auto-zoned, but ALIEN and IPS are zone-independent FORWARD-chain rules). Requires a P-CSCF hostname to be set. B2BUA (deprecated): same SIP proxy concept but the process runs directly on the router without sandboxing — SIP traffic bypasses the firewall and security chains. PBR: clients register directly to the ISP's SIP proxy — the gateway only handles routing so packets take the correct path.
Q: Does B2BUA add latency? A: No. The B2BUA only processes SIP signaling (REGISTER, INVITE, BYE, etc.). RTP media flows directly between your SIP client and the ISP's media servers — the gateway is not in the media path at all.
Q: Can multiple SIP clients register at the same time in B2BUA mode? A: Yes. Multiple LAN clients can register simultaneously. Inbound calls are delivered to the first registered client. Outbound calls from any registered client are forwarded upstream.
Q: Does this support IPv6? A: Currently, this script only configures IPv4. IPv6 support can be added if needed.
Q: Will this survive a reboot? A: Yes, the systemd service is enabled to start automatically on boot.
Q: Will this survive a firmware upgrade?
A: The /data/voip directory and your voipd.conf survive firmware upgrades. The systemd service registration does not — run ./voip install && ./voip install-ui after a firmware upgrade to restore it.
Q: Can I use VoIP over VPN (Teleport / WireGuard)?
A: Yes. Set VOIP_VPN_INTERFACES to your WireGuard interface name (e.g. "wgsrv1") in voipd.conf, or enable it from the web UI under Config → VPN Support. It is disabled by default. Works with all three routing modes.
GNU General Public License v2.0 — see LICENSE.