🏗️ System Architecture & Engineering Rationale
AiPBX is purposefully engineered to eliminate corporate firewall blockades, solve WebRTC NAT traversal challenges, streamline multi-device identity, and handle high-concurrency instant messaging.
1. Unified Layered Architecture
AiPBX is built on a modular, loosely coupled multi-tier architecture. All ingress traffic is multiplexed through a single entry point and routed cleanly at the protocol level:
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ ┌───────────────────────────────┐ ┌─────────────────────────────────┐ │
│ │ Android Mobile App │ │ Web Browser Client │ │
│ │ (Kotlin + WebRTC/SIP) │ │ (WebRTC Softphone + Portal) │ │
│ └───────────────┬───────────────┘ └────────────────┬────────────────┘ │
└───────────────────┼────────────────────────────────────────────────┼────────────────────┘
│ HTTPS / WSS / TURNS (Single Port: 443) │ HTTPS / WSS / TURNS
▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ EDGE INGRESS: NGINX PORT 443 ALPN MULTIPLEXER (L4) │
│ Nginx TCP Stream module (ssl_preread on) — Transparent proxy evaluating ALPN bytes: │
│ │
│ ├── [ ALPN Present ] (http/1.1, h2: Web Browsers, Mobile REST API, Management) │
│ │ └──► Streamed to Apache 2.4 TLS Termination (127.0.0.1:8443) │
│ │ │
│ └── [ ALPN Empty / None ] (WebRTC TURNS media relay behind restrictive firewalls) │
│ └──► Streamed to Coturn TURNS Service (127.0.0.1:5349) │
└───────────────────────────────────┬────────────────────────────────┬────────────────────┘
│ │
[ ALPN Present ] [ No ALPN ]
▼ │
┌───────────────────────────────────────────────────────┐ │
│ APPLICATION & WEBSOCKET PROXY TIER │ ▼
│ Apache 2.4 (127.0.0.1:8443 with TLS Termination) │ ┌─────────────────────────────┐
│ ├── / ──► PHP 8 MVC Web Portal │ │ COTURN RELAY │
│ ├── /ws ──► Asterisk WebRTC (8088/ws) │ │ TURNS Server (Port 5349) │
│ └── /chat/ws ──► Go Chat Engine (8086/ws) │ │ Zero Media Loss for │
│ │ │ Symmetric NAT Traversal │
│ Port 80: HTTP Redirect & Let's Encrypt ACME HTTP-01 │ └─────────────────────────────┘
└──────────┬────────────────────────┬───────────────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ PHP 8 MVC │ │ Asterisk 22 │
│ Web Portal │ │ VoIP Engine │
│ (Hardened Runtime) │ │ (PJSIP/WebRTC) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
│ AMI (Port 5038) │
├────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ MariaDB 11 (utf8mb4_unicode_ci) — Two-Tier Privilege Security Model: │
│ ├── aipbx_portal (Runtime DML: SELECT, INSERT, UPDATE, DELETE only) │
│ └── aipbx_migrator (Schema DDL: Phinx Migrations only) │
└─────────────────────────────────────────────────────────────────────────────────────────┘
2. Why Port 443 ALPN Stream Multiplexing?
Traditional PBX setups require opening numerous external ports: UDP 5060 for SIP, 8089 for WebRTC WSS, and 3478/5349 for STUN/TURN. However, modern corporate networks (banks, hospitals, universities, government offices) enforce strict firewalls that block all outbound traffic except ports 80 and 443.
ssl_preread on inspects the unencrypted Application-Layer Protocol Negotiation (ALPN) extension in the initial TLS ClientHello packet. It transparently multiplexes traffic without needing to decrypt the TLS session at the edge.
Nginx L4 Stream Configuration:
stream {
map $ssl_preread_alpn_protocols $upstream_backend {
# Standard web browsers and mobile REST API clients
"~*http" apache_https;
"~*h2" apache_https;
# WebRTC TURNS media relay packets (send empty ALPN)
default coturn_turns;
}
upstream apache_https {
server 127.0.0.1:8443;
}
upstream coturn_turns {
server 127.0.0.1:5349;
}
server {
listen 443;
proxy_pass $upstream_backend;
ssl_preread on;
proxy_connect_timeout 5s;
proxy_timeout 3600s;
}
}
3. Dual-Endpoint PJSIP & WebRTC Architecture
Many legacy PBX solutions struggle to connect both a physical hardware phone and a WebRTC browser/mobile client to the same extension. Their transport and encryption profiles are mutually exclusive:
- WebRTC (Browser & Mobile): Mandatory WSS transport, DTLS-SRTP encryption, ICE candidate negotiation, AVPF profile, and Opus audio codec.
- Hardware Phone (Desktop IP Phone / ATA): Standard UDP/TLS transport, SDES-SRTP or plain RTP, SAVP profile, and G.711u/a or G.722 codecs.
| Endpoint ID | Target Client | Transport & Port | Encryption & Codec |
|---|---|---|---|
| 1000 | Hardware IP Phone / Desktop SIP | UDP / TLS (Port 5060/5061) | SDES-SRTP / G.711a, G.722, G.729 |
| 1000-webrtc | Web Browser & Native Mobile App | WSS (Port 443 ALPN / 8089) | DTLS-SRTP + ICE / Opus (HD Audio) |
Dial(PJSIP/1000&PJSIP/1000-webrtc,30), ringing both the desk phone and the mobile smartphone simultaneously. Whichever picks up first takes the call; the other cancels silently.
4. Standalone Go Real-Time WebSocket Service
PHP is fantastic for short-lived HTTP request-response lifecycles, but inefficient for sustaining tens of thousands of idle WebSocket connections. AiPBX offloads instant messaging and group channels to a compiled Go service (/opt/aipbx/bin/aipbx-chat):
- Micro Memory Footprint: 10,000 active concurrent WebSocket clients consume only ~28 MB of RAM.
- Goroutine Concurrency: Channels handle message fanout asynchronously without OS thread overhead.
- Zero External Dependencies: Single self-contained binary running as an isolated systemd daemon.
- Presence & Typing Signals: Real-time typing indicators, read receipts, and online status distributed in milliseconds.
5. Asterisk Configuration Sync Pipeline
Asterisk configuration files in AiPBX are never edited by hand. The MariaDB database is the single source of truth. Whenever changes occur, an atomic generation and rollback pipeline executes:
Web UI / REST API Request
│
▼
Controller Validation & Auth Check
│
▼
Service writes to MariaDB (DML)
│
▼
Sync Generator (src/sync/*.php)
├── 1. Backs up existing file to .bak
├── 2. Queries DB and generates modular files under /etc/asterisk/pbx/*.conf
└── 3. Issues Asterisk reload command (dialplan reload, queue reload...)
│
├── [ SUCCESS ] ──► Updates audit log, removes .bak cleanly.
└── [ FAILURE ] ──► AUTOMATIC ROLLBACK: Restores .bak immediately,
prevents downtime, and logs error report.
6. Two-Tier MariaDB Privilege Security Model
| User Account | Runtime Scope | Granted SQL Privileges | Restricted Privileges |
|---|---|---|---|
| aipbx_portal | PHP Web Portal & REST API | SELECT, INSERT, UPDATE, DELETE | DROP, ALTER, CREATE, GRANT (Forbidden) |
| aipbx_migrator | Phinx Database Migrations (CLI) | CREATE, ALTER, INDEX, DROP | Local CLI only during schema migrations |