How to Setup NGINX Reverse Proxy for Telecom Applications (HTTPS, WebSockets, Security)
Production-safe NGINX reverse proxy configuration for telecom dashboards and FreePBX-style apps with HTTPS, headers, and WebSocket support.
Telecom deployments (FreePBX, Asterisk tools, Web dashboards, ARI/WebSockets, internal APIs) almost always need a reverse proxy in front of them. The reasons are practical:
- Single public HTTPS entry for multiple services (UI, API, PBX admin, ARI)
- WebSocket support for ARI and real-time dashboards
- Security controls (TLS, headers, rate limits, IP allowlists)
- Clean routing without exposing internal ports to the internet
This guide is written for Ubuntu + Debian servers and focuses on real problems people face in telecom setups (502/504 errors, WebSocket failures, mixed-content HTTPS issues, wrong client IP in logs, and timeouts during long calls/recording uploads).
Architecture: What NGINX Is Doing in a Telecom Setup
Think of NGINX as the single secure “front door” that routes requests to internal services. You keep your PBX and telecom components private, while users access one HTTPS domain.
Key point: Only ports 80/443 should be public. Everything else stays internal. For SIP/RTP ports, follow your firewall reference: Ports Required for FreePBX + Asterisk.
Install NGINX on Ubuntu/Debian (Production-Friendly)
On both Ubuntu and Debian, the package name is nginx.
For stable production, install from official repos unless you specifically need the newest mainline.
# Ubuntu / Debian
sudo apt update
sudo apt install -y nginx
# Enable and start
sudo systemctl enable nginx
sudo systemctl start nginx
# Confirm running
systemctl status nginx --no-pager
If you are using UFW:
sudo ufw allow 'Nginx Full'
sudo ufw status
Before You Proxy Anything: Avoid the #1 Telecom Mistake
Problem: “I exposed FreePBX / ARI ports directly to the internet”
Exposing PBX admin and ARI endpoints publicly is a high-risk pattern. For telecom apps, do this instead:
- Keep FreePBX web UI bound to LAN/private IP (or behind VPN)
- Keep ARI/AMI bound to internal IPs only
- Expose only NGINX 443 publicly
- Add allowlists + auth on admin paths
If you need a clean SSL setup, use: Generate Free SSL with Let’s Encrypt and Configure SSL Using Let’s Encrypt.
Base HTTPS Reverse Proxy Template (Works for Most Telecom Apps)
This is the foundation: HTTPS with strong defaults, and routing to internal services. You can reuse it for telecom dashboards, admin portals, and backend APIs.
# File (Ubuntu/Debian):
# /etc/nginx/sites-available/telecom-app.conf
server {
listen 80;
server_name telecom.example.com;
# Redirect everything to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name telecom.example.com;
# SSL paths (Let's Encrypt example)
ssl_certificate /etc/letsencrypt/live/telecom.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/telecom.example.com/privkey.pem;
# Basic TLS hardening (safe defaults)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Upload limits (useful for recordings, reports, exports)
client_max_body_size 50m;
# Timeouts (useful for long API calls, exports)
proxy_connect_timeout 10s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
send_timeout 120s;
# Standard proxy headers (preserve real client info)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Example: Backend API at /api/
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
# Example: Frontend UI (static build or separate server)
# Option A: Serve a built UI from disk
root /var/www/telecom-ui;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Enable the site and test config:
sudo ln -s /etc/nginx/sites-available/telecom-app.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Problem: “WebSocket fails behind NGINX” (ARI / Real-Time Dashboards)
ARI and many real-time telecom dashboards use WebSockets. If you proxy WebSockets without upgrade headers, you’ll see:
- 400 / 426 errors
- Connection opens then closes instantly
- “WebSocket handshake failed” in browser console
Fix: add WebSocket upgrade handling. This config supports both ARI REST and ARI WebSocket.
# Put this map in http {} block (usually in /etc/nginx/nginx.conf)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Inside your server { ... } block:
location /ari/ {
proxy_pass http://127.0.0.1:8088/ari/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# ARI can be long-lived (keepalive)
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
Notes for telecom deployments:
- ARI often runs on Asterisk HTTP server (commonly 8088). Keep it internal.
- Protect ARI with allowlists or VPN unless you have strong auth + strict ACL.
- If your ARI is on a different server, proxy_pass to its private IP instead of localhost.
Problem: “502 Bad Gateway” when proxying FreePBX or PBX Admin
Root causes you’ll actually see in telecom stacks
- Wrong upstream IP/port (FreePBX Apache not on that port)
- Firewall blocks local access (rare, but happens with hardening)
- SELinux/AppArmor constraints (more common on hardened images)
- Upstream returns huge headers → NGINX buffer issues (some admin apps do)
Safe pattern: keep FreePBX private, proxy only for VPN/admin
If you must publish a FreePBX UI (not recommended), at least restrict it. Example: only allow office IP or VPN subnet.
# Example: FreePBX behind NGINX at /pbx/
location /pbx/ {
# Restrict access (replace with your office/VPN IP range)
allow 203.0.113.10;
allow 10.0.0.0/8;
deny all;
proxy_pass http://127.0.0.1:80/; # FreePBX usually on Apache:80 internally
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# If you see header/buffer errors:
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
If you’re setting up ports/firewall the right way, cross-check: FreePBX + Asterisk Firewall Guide.
Problem: “Mixed content / WebRTC not working after enabling HTTPS”
In telecom apps, WebRTC and browser permissions are strict. Common breakages after enabling HTTPS:
- Frontend loads over HTTPS but calls API over HTTP → blocked by browser
- WebSocket uses
ws://instead ofwss:// - Wrong CORS headers from backend (especially in multi-subdomain setups)
Fix checklist
- Frontend API base URL should be https:// (not http)
- WebSocket URL should be wss:// (not ws)
- Set
X-Forwarded-Protoso backend knows original scheme
# Ensure this exists globally in your server block (already recommended)
proxy_set_header X-Forwarded-Proto $scheme;
For SSL generation and renewal automation, use: Let’s Encrypt on Ubuntu (Auto-Renew Script).
Security Hardening for Telecom Reverse Proxies (Practical Defaults)
Telecom stacks attract scanning, brute force, and credential stuffing. The goal: make the proxy safe without breaking legitimate traffic.
Recommended security headers
# Add inside server { ... }
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# HSTS (enable only after you confirm HTTPS works everywhere)
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Rate limiting for login endpoints (prevents brute force)
# Put these in http { } block:
limit_req_zone $binary_remote_addr zone=login_zone:10m rate=5r/m;
# Then in server { } block, example:
location = /api/auth/login {
limit_req zone=login_zone burst=10 nodelay;
proxy_pass http://127.0.0.1:8080/api/auth/login;
}
Allowlist admin paths (best protection for PBX UIs)
location /admin/ {
allow 203.0.113.10;
allow 10.0.0.0/8;
deny all;
proxy_pass http://127.0.0.1:8080/;
}
Problem: “Backend sees 127.0.0.1 as client IP” (Wrong Audit Logs)
Telecom systems often rely on correct IPs for audit, fraud detection, and compliance logs.
If your backend logs show 127.0.0.1, you are not passing real IP headers
or your app isn’t configured to trust them.
NGINX side (required)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Application side (common requirement)
- Spring Boot: enable forwarded headers strategy (varies by version)
- Node/Express:
app.set('trust proxy', true)
If your app is behind multiple proxies (cloud LB + NGINX), you must define trusted proxy hops.
Problem: “504 Gateway Timeout” during exports, recordings, or long tasks
Telecom dashboards often trigger heavy operations: exporting reports, searching call recordings, generating analytics, or large file downloads. Default timeouts can be too short.
Increase timeouts for specific heavy endpoints (not globally)
location /api/reports/export {
proxy_pass http://127.0.0.1:8080/api/reports/export;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
Also consider backend limits
- JVM/Node timeouts
- Database query timeouts
- Worker queue (async exports) for really large reports
Split Services by Subdomain (Cleanest for Telecom Platforms)
For larger telecom platforms, subdomains are cleaner than path routing. Example:
app.example.com→ frontend UIapi.example.com→ backend APIpbx.example.com→ PBX admin (restricted)
This reduces CORS complexity and makes security rules more precise.
# Example for api.example.com
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://127.0.0.1:8080/;
}
}
Validation: How to Confirm Your Proxy Is Correct (No Guessing)
1) NGINX config test
sudo nginx -t
2) Confirm ports open (public side)
sudo ss -lntp | grep -E ':80|:443'
3) Test HTTPS response
curl -I https://telecom.example.com/
4) Test WebSocket upgrade (basic check)
# This won’t complete a full ARI auth flow, but you can still confirm Upgrade is not blocked.
curl -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
https://telecom.example.com/ari/
5) Look at NGINX logs while testing
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
Troubleshooting Cheatsheet (Fast Root Cause Mapping)
502 Bad Gateway
- Upstream service not running
- Wrong upstream port
- Firewall blocks local port
- Look at
/var/log/nginx/error.logfirst
504 Gateway Timeout
- Backend is slow / blocked by DB
- Increase
proxy_read_timeouton the specific location - Fix backend workload (async exports)
WebSocket fails (ARI / realtime)
- Missing Upgrade headers
- Proxying to wrong ARI path/port
- Increase timeouts to 3600s for long-lived sockets
Mixed content / insecure WS
- Switch from
ws://towss:// - Ensure API uses
https:// - Pass
X-Forwarded-Proto
Wrong client IP in app logs
- Ensure
X-Forwarded-Foris set - Configure app to trust proxy headers
Production Checklist for Telecom Reverse Proxies
- Only ports 80/443 public (everything else internal)
- HTTPS working + renewal configured
- WebSocket upgrade configured where needed
- Admin routes are IP-restricted or behind VPN
- Timeouts tuned for long-lived telecom workflows
- Logs checked during real traffic
- Firewall rules match telecom requirements: FreePBX + Asterisk Ports Guide
If you want a simpler “single file” production NGINX layout that routes multiple MYLINEHUB services, also see: Nginx Reverse Proxy Configuration for MYLINEHUB Services.
Key Takeaway
A telecom reverse proxy is not “just routing”. It’s your security perimeter, your WebSocket gateway, and the difference between a stable production system and a fragile deployment.
Start with HTTPS, keep PBX internals private, add WebSocket support for ARI, and lock down admin routes. That one pattern prevents most telecom deployment disasters.
Want to see API-driven CRM + Telecom workflows in action? Try the WhatsApp bot or explore the demos.
Comments (0)
Be the first to comment.