Skip to content

Reverse Proxy Configuration

This guide covers configuring reverse proxies to front License Monitor and License Server Detail, providing SSL termination, load balancing, and security features.

A reverse proxy provides:

  • SSL/TLS Termination - Offload encryption to the proxy
  • Load Balancing - Distribute traffic across multiple instances
  • Security - Hide internal services, add headers
  • Caching - Cache static assets
  • Compression - Reduce bandwidth usage
/etc/nginx/sites-available/license-monitor
upstream license_monitor {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL Configuration
ssl_certificate /etc/ssl/certs/api.example.com.crt;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# API endpoints
location /api/ {
proxy_pass http://license_monitor;
proxy_http_version 1.1;
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# WebSocket endpoints
location /ws/ {
proxy_pass http://license_monitor;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header 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;
# WebSocket timeouts
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
# SSE endpoints
location /stream/ {
proxy_pass http://license_monitor;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# SSE specific settings
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400;
chunked_transfer_encoding off;
}
# Health check (no auth required)
location /api/health {
proxy_pass http://license_monitor;
proxy_http_version 1.1;
access_log off;
}
}
# Multiple License Monitor instances
upstream license_monitor {
least_conn; # Load balancing method
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 backup;
keepalive 32;
}
# Health checks (nginx plus) or use nginx_upstream_check_module
# upstream license_monitor {
# server 192.168.1.10:8080;
# check interval=3000 rise=2 fall=5 timeout=1000 type=http;
# check_http_send "GET /api/health HTTP/1.0\r\n\r\n";
# check_http_expect_alive http_2xx http_3xx;
# }
# Define rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=ws_limit:10m rate=5r/s;
server {
# Apply rate limiting to API
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://license_monitor;
# ... other settings
}
# Stricter rate limiting for expensive operations
location /api/execute {
limit_req zone=api_limit burst=5 nodelay;
proxy_pass http://license_monitor;
}
}
/etc/apache2/sites-available/license-monitor.conf
<VirtualHost *:80>
ServerName api.example.com
Redirect permanent / https://api.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName api.example.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/ssl/certs/api.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/api.example.com.key
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
# Security headers
Header always set Strict-Transport-Security "max-age=63072000"
# Enable required modules
# a2enmod proxy proxy_http proxy_wstunnel headers ssl
# Proxy settings
ProxyPreserveHost On
ProxyPass /api/ http://127.0.0.1:8080/api/
ProxyPassReverse /api/ http://127.0.0.1:8080/api/
# WebSocket proxy
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/ws/(.*) ws://127.0.0.1:8080/ws/$1 [P,L]
ProxyPass /ws/ ws://127.0.0.1:8080/ws/
ProxyPassReverse /ws/ ws://127.0.0.1:8080/ws/
# SSE proxy
<Location /stream/>
ProxyPass http://127.0.0.1:8080/stream/
ProxyPassReverse http://127.0.0.1:8080/stream/
# Disable buffering for SSE
SetEnv proxy-sendcl 1
SetEnv proxy-sendchunked 1
</Location>
# Logging
ErrorLog ${APACHE_LOG_DIR}/license-monitor-error.log
CustomLog ${APACHE_LOG_DIR}/license-monitor-access.log combined
</VirtualHost>
Terminal window
# Enable Apache modules
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod rewrite
sudo a2enmod deflate
# Enable sites
sudo a2ensite license-monitor
sudo a2ensite license-dashboard
# Test configuration
sudo apachectl configtest
# Restart Apache
sudo systemctl restart apache2

Serve both applications under a single domain:

/etc/nginx/sites-available/license-management
upstream license_monitor {
server 127.0.0.1:8080;
keepalive 32;
}
upstream license_dashboard {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name licenses.example.com;
# SSL configuration...
# Dashboard (default)
location / {
proxy_pass http://license_dashboard;
proxy_http_version 1.1;
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;
}
# License Monitor API under /monitor/
location /monitor/api/ {
rewrite ^/monitor/api/(.*)$ /api/$1 break;
proxy_pass http://license_monitor;
proxy_http_version 1.1;
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;
}
# License Monitor WebSocket
location /monitor/ws/ {
rewrite ^/monitor/ws/(.*)$ /ws/$1 break;
proxy_pass http://license_monitor;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}
# Allow only specific IPs
location /api/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://license_monitor;
}
# Protect API with basic auth
location /api/ {
auth_basic "License Monitor API";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://license_monitor;
}
# Forward API key header
location /api/ {
proxy_set_header X-API-Key $http_x_api_key;
proxy_pass http://license_monitor;
}
Terminal window
# Test configuration
sudo nginx -t
# Reload configuration
sudo nginx -s reload
# View error logs
sudo tail -f /var/log/nginx/error.log
Terminal window
# Test configuration
sudo apachectl configtest
# Reload configuration
sudo systemctl reload apache2
# View error logs
sudo tail -f /var/log/apache2/error.log