Skip to content

Astradial to FusionPBX — Inbound and Outbound Setup Guide

A step-by-step guide for connecting a customer FusionPBX (FreeSWITCH) to the Astradial resold Tata SIP trunk. When complete, the customer can receive calls on their allocated DIDs and place PSTN calls, authenticated by IP over a private WireGuard tunnel.

Audience Astradial provisioning engineer + the customer's FusionPBX administrator
Time ~45 minutes
Model IP-authenticated peer trunk over WireGuard. No SIP password.
Example customer Skylink — FusionPBX fpbx.skylinkonline.net, tunnel IP 10.30.0.3, DIDs 918065080710 / 918065080711, extension 6000

1. Architecture

   PSTN                                                     Customer FusionPBX
    |                                                        (FreeSWITCH)
    v                                                             |
  Tata SBC  --NNI-->  Astradial NUC  --WireGuard-->  astradial-trunk profile
                      (reseller GW)      tunnel        (bound to 10.30.0.3)
                      10.30.0.2          10.30.0.x           |
                                                             v
                                                    Inbound -> Extension
                                                    Outbound <- Extension
Element Value / role
Astradial NUC (reseller gateway) Terminates the Tata NNI; SIP endpoint on the tunnel is 10.30.0.2:5070
WireGuard tunnel NUC initiates to the customer's public listener; customer gets a /32 in 10.30.0.0/24
Authentication Source IP over the tunnel. No username/password.
Customer FusionPBX Runs a dedicated SIP profile bound to the tunnel IP; a gateway, inbound destinations, and an outbound route

Note. The NUC is a B2BUA. It terminates the customer leg and originates a fresh leg to Tata, so there is no direct IP path between the customer and the carrier. Concurrency is capped per customer (default two channels), and each customer may present only its own DIDs as caller ID.


2. Prerequisites

Requirement Detail
FusionPBX host Public IPv4, an open inbound UDP port for WireGuard (default 51821)
Allocated DIDs Provided by Astradial (e.g. 918065080710, 918065080711)
Tunnel IP Provided by Astradial (e.g. 10.30.0.3)
WireGuard keypair Generated on the FusionPBX host; send Astradial the public key only
A test extension A registered extension on the production domain (e.g. 6000)

3. Step 1 — WireGuard tunnel (FusionPBX host)

The FusionPBX host is the WireGuard listener; the Astradial NUC dials in.

  1. Install WireGuard.
apt-get install -y wireguard
  1. Generate a keypair and send Astradial the public key.
cd /etc/wireguard
wg genkey | tee astradial-trunk.key | wg pubkey > astradial-trunk.pub
cat astradial-trunk.pub        # send this to Astradial
  1. Create /etc/wireguard/astradial-trunk.conf (replace the keys):
[Interface]
Address    = 10.30.0.3/32
ListenPort = 51821
PrivateKey = <contents of astradial-trunk.key>

[Peer]
# Astradial NUC — it initiates the tunnel, so no Endpoint line here
PublicKey  = <Astradial NUC public key>
AllowedIPs = 10.30.0.2/32
chmod 600 astradial-trunk.conf
wg-quick up astradial-trunk
systemctl enable wg-quick@astradial-trunk
  1. Open the WireGuard port in the host firewall.
iptables -I INPUT -p udp --dport 51821 -j ACCEPT
  1. Verify once Astradial has added the peer:
wg show astradial-trunk        # expect a recent handshake
ping -c3 10.30.0.2             # the Astradial gateway over the tunnel

Checkpoint. ping 10.30.0.2 must succeed before continuing. If it does not, confirm inbound UDP 51821 is open and that the public key sent to Astradial matches the private key in the conf.


4. Step 2 — SIP profile bound to the tunnel IP

FusionPBX's default external profile binds the host's public IP. SIP sourced from that IP is dropped by the tunnel. Create a dedicated profile bound to the tunnel IP 10.30.0.3.

GUI: Advanced → SIP Profiles → copy external → rename to astradial-trunk. Set the following, then Start the profile.

Setting Value
sip-ip 10.30.0.3
rtp-ip 10.30.0.3
ext-sip-ip 10.30.0.3
ext-rtp-ip 10.30.0.3
sip-port 5060
context public
auth-calls false
apply-inbound-acl remove / leave empty

Verify:

fs_cli -x "sofia status" | grep astradial-trunk
# expect: astradial-trunk  profile  sip:mod_sofia@10.30.0.3:5060  RUNNING

Note. ext-sip-ip and ext-rtp-ip are 10.30.0.3 (not the public IP) because the tunnel is a direct, un-NATed path.


5. Step 3 — Gateway

GUI: Accounts → Gateways → Add.

Field Value
Gateway astradial
Proxy 10.30.0.2:5070
Register False
Username / From User 918065080710 (an allocated DID)
Profile astradial-trunk
Context public
Enabled True

Important. The From User must be an allocated DID. Left blank, FreeSWITCH puts FreeSWITCH in the From header and the Astradial gateway rejects the call with 403 (anti-spoofing).

Verify:

fs_cli -x "sofia status gateway <gateway-uuid>"
# expect: Proxy sip:10.30.0.2:5070, Status UP, From <sip:918065080710@...>

6. Step 4 — Inbound (Destinations)

Route each DID to an extension. Use plain digits — no +, no regex.

GUI: switch to the production domain, then Dialplan → Destinations → Add.

Field Value
Type Inbound
Country Code (blank)
Destination 918065080710
Context public
Action Transfer → extension (e.g. 6000)
Enabled True

Repeat for each DID.

Critical. FusionPBX in single dialplan mode matches the incoming number against the destination number by exact equality. If the Destination field contains a regex (for example \+?918065080710) or a +, it will never equal the plain digits the trunk delivers, and the call returns 404 silently. Enter the number exactly as the trunk sends it — plain digits.

Verify (from Astradial, no PSTN call needed):

# On the NUC — simulate an inbound INVITE to the customer:
asterisk -rx "channel originate PJSIP/918065080710@<customer-endpoint> application Echo"
# Expect the FusionPBX response: 100 Trying -> 183 Session Progress -> 200 OK
# A 404 means the Destination number is not plain digits (see Critical note).

7. Step 5 — Outbound (Route)

Let extensions dial PSTN through the astradial gateway.

GUI: production domain → Dialplan → Outbound Routes → Add.

Field Value
Gateway astradial
Dialplan Expression match your dialling (e.g. Indian mobiles)
Caller ID an allocated DID (918065080710)

Equivalent dialplan (10-digit sent to the trunk; Astradial formats it for Tata):

<condition field="destination_number" expression="^(?:\+?91|0091|0)?([6-9]\d{9})$">
  <action application="set" data="effective_caller_id_number=918065080710"/>
  <action application="bridge" data="sofia/gateway/<gateway-uuid>/$1"/>
</condition>

Note. Send the plain 10-digit number to the gateway. The Astradial NUC normalises it to the 0 + 10-digit format the Tata NNI requires. Caller ID is forced to an allocated DID by the gateway's From User, so the trunk accepts it.


8. Step 6 — Extension and softphone

The test extension lives on the production domain, so its SIP realm is the domain name (for example skylink.local), not the server hostname.

For a remote softphone (Zoiper or Linphone recommended):

Field Value
Username 6000
Password the extension password
Domain / SIP realm the production domain (e.g. skylink.local)
Server / Registrar the FusionPBX host (public IP or hostname), port 5080
Transport UDP

Two host-side requirements for remote registration:

  1. Resolve a private .local realm — add it to the client's hosts file, or use an outbound proxy pointing at the server:
echo "<fusionpbx-public-ip> <domain>" | sudo tee -a /etc/hosts
  1. Allow the client's public IP through the FusionPBX firewall (it uses a per-IP SIP allow-list):
iptables -I INPUT -s <client-ip>/32 -p udp --dport 5060:5091 -j ACCEPT

Note. The internal (registration) profile port on this build is 5080, not 5060. Confirm with fs_cli -x "sofia status".


9. Verification

Inbound. Call a DID from a mobile. The mapped extension should ring with two-way audio.

Outbound. From the extension, dial a PSTN number. The call should connect and the callee should see the allocated DID as caller ID.

Signalling check (from Astradial).

# Watch the customer leg on the NUC while placing a test call:
tcpdump -i wg-reseller host 10.30.0.3 and port 5060
# Inbound success:  INVITE -> 100 -> 183 -> 200
# Outbound success: INVITE -> 100 -> 183 -> 200 (From user = allocated DID)

10. Critical points (do not skip)

# Rule
1 Inbound Destination number is plain digits — no +, no regex. A regex there gives a silent 404.
2 The SIP profile must be bound to the tunnel IP (10.30.0.3), not the public IP, or the trunk drops the packets.
3 The gateway From User must be an allocated DID, or outbound gets 403.
4 Configure everything on the production domain, not a secondary domain.
5 The remote softphone realm is the domain name; the registrar port is the internal profile port.
6 The client IP must be in the FusionPBX SIP allow-list, or REGISTER is dropped before FreeSWITCH.

Item Value
Tunnel IP (customer) 10.30.0.3
Astradial gateway (over tunnel) 10.30.0.2:5070
SIP profile astradial-trunk (bound 10.30.0.3:5060)
Gateway astradial, From User 918065080710
DIDs 918065080710, 918065080711
Inbound target extension 6000
Outbound CID 918065080710

See also: the SIP Trunk Reseller design (NUC side) and the FusionPBX Integration reference (full troubleshooting) in the internal documentation.