OpenVPN ATA Tunnels (Grandstream FXS gateways)¶
Per-device OpenVPN tunnels that give Grandstream GXW-series analog (FXS) gateways a stable, encrypted path into Astradial's cloud Asterisk — the OpenVPN counterpart of the WireGuard Customer Tunnels.
Same security model (per-customer isolation, SIP/RTP-only INPUT scope), different transport: the GXW gateways' firmware speaks OpenVPN, not WireGuard, so they cannot use
wg1.
Status: Live · Server: 147.93.168.216 (cloud Asterisk host) · First customer: Mithra Scan (2026-06-15)
Why this exists (and why not WireGuard)¶
Grandstream GXW4216V2 (and siblings) are analog telephone adapters: they take physical phone/fax lines on FXS ports and register them to a PBX as SIP endpoints. To reach our cloud Asterisk reliably from a customer site (CGNAT, dynamic IP, NAT pinhole churn — the same problems described in Customer Tunnels), the device needs a stable tunnel.
The GXW firmware (1.0.25.2) ships an OpenVPN client only — no WireGuard. So these devices get their own OpenVPN transport (tun0) that runs in parallel with the WireGuard customer transport (wg1), governed by the same isolation rules.
The device firmware also constrains the crypto (this is why the server config looks "legacy"):
| Constraint | Required server setting |
|---|---|
No tls-auth / tls-crypt (no ta.key field in UI) | Omit them entirely |
| CBC only (no GCM in the dropdown) | data-ciphers AES-256-CBC, data-ciphers-fallback AES-256-CBC |
| Plain digest | auth SHA256 |
| LZO toggle only | Compression disabled on both sides (ATA "Enable LZO Compression = No") — avoids comp-lzo framing incompatibility on OpenVPN 2.6 and the VORACLE risk |
| UDP / TUN / 1194 | proto udp, dev tun, port 1194 |
| Key password | Client key generated nopass → GXW "Client Key Password" left blank |
Security model (read this first)¶
ATA tunnels carry external customer traffic and are isolated exactly like the WireGuard customer tunnels.
What enforces isolation¶
| Layer | Mechanism | Effect |
|---|---|---|
| 1. Per-device certificate | One cert/key per physical device, never shared (duplicate-cn off) | A stolen/cloned device can't impersonate another; revoke one without touching others |
| 2. Separate interface + port | tun0 on udp/1194, distinct from wg0/wg1 | Per-interface firewall + audit |
3. No client-to-client | Directive deliberately absent | OpenVPN won't bridge peers internally — all peer↔peer packets must pass the kernel firewall, where they're dropped |
| 4. iptables FORWARD drops | tun0↔tun0, tun0↔wg0, tun0↔wg1 all explicit DROP (+ default FORWARD policy DROP) | A device cannot reach another ATA customer, a WireGuard customer, or internal infra (NUC/staging) |
| 5. iptables INPUT scope | tun0 traffic accepted only to SIP 5060/5080 + RTP 10000-20000; catch-all DROP for the rest | Device can't reach AstraPBX API (8000), editor (3001), MariaDB (3306), etc. |
| 6. Tunnel bypasses the public SIP geo-filter | The india_sip ipset DROP is scoped -i eth0 only | The device registers through the tunnel by certificate — it never has to be in the public geo-allowlist, and the public SIP attack surface doesn't grow |
| 7. Split tunnel | No redirect-gateway, no pushed routes | The device can reach only 10.21.0.1 (the PBX). Its internet traffic does NOT flow through us |
What a device CAN reach via its tunnel¶
What a device CANNOT reach¶
❌ Other ATA devices — tun0↔tun0 FORWARD DROP + no client-to-client
❌ WireGuard customers (wg1) — tun0↔wg1 FORWARD DROP
❌ Internal infra (wg0: NUC .2, staging .3) — tun0↔wg0 FORWARD DROP
❌ AstraPBX API (8000) / editor (3001) / DB — tun0 INPUT catch-all DROP
❌ The public internet via us — split tunnel (no redirect-gateway)
Known parity gap (same as
wg1): host ports that UFW allows globally — SSH (22), 80/443, WSS (8089) — are accepted before the per-interface catch-all DROP, so a compromised device could in principle reach them on10.21.0.1. This matches the existing WireGuard-tunnel posture. To close it for both transports, insert interface-scoped DROPs above the UFW jump (e.g.iptables -I INPUT <n> -i tun0 -p tcp --dport 22 -j DROP). Tracked as future hardening, not done by default to stay consistent with the wg1 model.
Architecture¶
Address allocation¶
| Range | Use | Notes |
|---|---|---|
10.10.10.0/24 | Internal infra (wg0) | EXISTING. Do not add customers here. |
10.20.0.0/16 | WireGuard customer tunnels (wg1) | EXISTING. |
10.21.0.0/24 | OpenVPN ATA tunnels (tun0) | NEW. .1 = cloud/PBX tunnel IP. .200–.250 = dynamic fallback pool. Statics .16–.199. |
10.21.0.N/28 | Per-customer block | Each customer gets a /28; devices are static IPs within it (assigned via ccd). |
When the first
/24fills (16 customers), add10.21.1.0/24as a second shard (newserver/tuninstance) or widen the existing subnet — see the runbook.
Device & customer registry¶
| Customer | Block | Device | Cert (CN) | Tunnel IP | Use | Status |
|---|---|---|---|---|---|---|
| Mithra Scan | 10.21.0.16/28 | GXW4216V2 | mithra-gxw01 | 10.21.0.17 | Remote mgmt access | ✅ Live 2026-06-15 (tunnel up, web UI reachable over tunnel) |
| Paavai Hospital | 10.21.0.32/28 | HT814 | paavai-ht814 | 10.21.0.33 | Remote mgmt access | ✅ Live 2026-06-17 (tunnel up, web UI reachable over tunnel; HT814 drops ICMP — verify via HTTP, not ping) |
| Gopi Hospital | 10.21.0.48/28 | HT814 | gopi-ht814 | 10.21.0.49 | Remote mgmt access | 🟡 Provisioned 2026-06-20 (cert + ccd + files staged; awaiting device-side upload/connect) |
| ACR Hospital | 10.21.0.64/28 | GXW4216V2 | acr-gxw01 | 10.21.0.65 | Remote mgmt access | 🟡 Provisioned 2026-06-24 (cert + ccd + files staged) |
| DCNet | 10.21.0.80/28 | Dinstar DAG (FXS) | dcnet-dag01 | 10.21.0.81 | Remote mgmt access | ✅ Live 2026-06-30 (tunnel up, device connected; web UI reachable over tunnel on HTTPS/443 — not HTTP/80) |
Keep this table current — it is the human-readable source of truth for IP/cert allocation. The machine truth is
/etc/openvpn/ccd/(IPs) and/etc/openvpn/easy-rsa/pki/index.txt(certs) on the server.
On-server layout (147.93.168.216)¶
| Path | What |
|---|---|
/etc/openvpn/server/astradial-ata.conf | Server config (service openvpn-server@astradial-ata) |
/etc/openvpn/easy-rsa/pki/ | PKI — ca.crt, issued/, private/, dh.pem (RSA-2048, SHA256; CA 10 yr, client certs ~825 d) |
/etc/openvpn/ccd/<device> | Per-device static tunnel IP (ifconfig-push) |
/etc/openvpn/clients/<customer>/ | Staged upload files per customer (root 0600) |
/usr/local/sbin/ovpn-add-client.sh | Provisioning helper (cert + ccd + staged files) |
/usr/local/sbin/openvpn-customer-iptables.sh | Isolation rules — sibling of customer-tunnels-iptables.sh; called by systemd ExecStartPost/ExecStopPost |
/var/log/openvpn/astradial-ata{.log,-status.log} | Server log + connected-client status |
Components vs the WireGuard tunnels¶
| WireGuard customer tunnels | OpenVPN ATA tunnels | |
|---|---|---|
| Interface / port | wg1 / udp 51821 | tun0 / udp 1194 |
| Subnet | 10.20.0.0/16 (/30 per customer) | 10.21.0.0/24 (/28 per customer) |
| Identity | WG keypair + PSK | X.509 cert per device |
| Isolation script | customer-tunnels-iptables.sh (wg-quick PostUp/Down) | openvpn-customer-iptables.sh (systemd ExecStartPost/StopPost) |
| Managed by | Editor / API (DB-backed) | CLI helper ovpn-add-client.sh + this registry |
| Use case | Site routers (GWN), full PBX/site | Single analog-gateway appliances (GXW FXS) |
Operational notes & safety¶
- Additive & call-safe. Standing this up touched nothing in the call path: no Asterisk restart/reload, no pjsip change, no
wgchange. Every firewall rule is scoped to-i tun0/udp 1194. - Never
ufw reloadcasually. Both isolation scripts add their rules with rawiptablesoutside UFW's managed chains (the wg1 rules likewise). Aufw reloadflushes and rebuilds the chains, transiently dropping the livewg1andtun0customer rules until each service/interface re-triggers its script. If you must reload UFW, re-run both isolation scripts (or bouncewg1andopenvpn-server@astradial-ata) immediately after. - The OpenVPN port is opened by the isolation script (inserted at the top of INPUT), not by
ufw allow— same reason as above. It self-heals on service start / reboot.
See also¶
- Provision a Grandstream ATA onto the VPN — step-by-step runbook + how to retrieve configs & credentials
- Customer Tunnels (WireGuard) — the sibling transport and shared security model