API Hardening Guide
This guide covers securing the OpenGSLB API for production deployments.
Threat Model
The API exposes:
Server IP addresses and ports (infrastructure topology)
Region names (organizational structure)
Health states and failure messages (operational status)
Timing information (maintenance windows, patterns)
Potential threats:
Reconnaissance by external attackers
Lateral movement after initial compromise
Insider threats mapping infrastructure
Defense Layers
Layer 1: Network Binding (Default)
By default, OpenGSLB binds to 127.0.0.1:8080. This is the strongest default—the API is only accessible from the local machine.
api:
enabled: true
address: "127.0.0.1:8080"
Access via SSH tunnel:
ssh -L 8080:localhost:8080 user@opengslb-server
curl http://localhost:8080/api/v1/health/servers
Layer 2: IP-Based ACL
For network access without a reverse proxy, use the built-in ACL:
api:
enabled: true
address: "0.0.0.0:8080"
allowed_networks:
- "10.0.0.0/8" # Internal network
- "192.168.100.50/32" # Monitoring server
The ACL is enforced before any request processing. Denied requests receive a 403 Forbidden with no additional information.
Layer 3: Reverse Proxy (Recommended for Production)
For production deployments requiring authentication, use a reverse proxy.
NGINX with Basic Auth
upstream opengslb_api {
server 127.0.0.1:8080;
}
server {
listen 443 ssl;
server_name gslb-api.example.com;
ssl_certificate /etc/nginx/ssl/api.crt;
ssl_certificate_key /etc/nginx/ssl/api.key;
# Basic authentication
auth_basic "OpenGSLB API";
auth_basic_user_file /etc/nginx/htpasswd;
location /api/ {
proxy_pass http://opengslb_api;
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;
}
# Deny access to other paths
location / {
return 404;
}
}
Create htpasswd file:
htpasswd -c /etc/nginx/htpasswd admin
OpenGSLB configuration:
api:
enabled: true
address: "127.0.0.1:8080"
allowed_networks:
- "127.0.0.1/32"
trust_proxy_headers: true # Trust NGINX headers
NGINX with Client Certificates (mTLS)
server {
listen 443 ssl;
server_name gslb-api.example.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Client certificate verification
ssl_client_certificate /etc/nginx/ssl/client-ca.crt;
ssl_verify_client on;
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-Real-IP $remote_addr;
}
}
HAProxy with Basic Auth
frontend api_frontend
bind *:443 ssl crt /etc/haproxy/certs/api.pem
# Basic auth
acl auth_ok http_auth(api_users)
http-request auth realm "OpenGSLB API" unless auth_ok
use_backend opengslb_api
backend opengslb_api
server local 127.0.0.1:8080
userlist api_users
user admin password $6$rounds=5000$... # mkpasswd -m sha-512
OAuth2 Proxy
For SSO integration:
# oauth2-proxy config
provider = "google" # or oidc, azure, etc.
email_domain = "example.com"
upstream = "http://127.0.0.1:8080"
Configuration Recommendations
Minimal Production Config
api:
enabled: true
address: "127.0.0.1:8080"
allowed_networks:
- "127.0.0.1/32"
trust_proxy_headers: true
With NGINX/HAProxy handling:
TLS termination
Authentication (basic, mTLS, or OAuth2)
Rate limiting
Access logging
Air-Gapped / High Security
api:
enabled: true
address: "127.0.0.1:8080"
allowed_networks:
- "127.0.0.1/32"
trust_proxy_headers: false
Access only via SSH with key-based authentication.
Internal Monitoring Network
api:
enabled: true
address: "10.100.0.5:8080"
allowed_networks:
- "10.100.0.0/24" # Monitoring VLAN only
trust_proxy_headers: false
Combined with network-level controls (firewall, VLANs).
Firewall Rules
iptables
# Allow only monitoring network
iptables -A INPUT -p tcp --dport 8080 -s 10.100.0.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
firewalld
firewall-cmd --permanent --new-zone=gslb-api
firewall-cmd --permanent --zone=gslb-api --add-source=10.100.0.0/24
firewall-cmd --permanent --zone=gslb-api --add-port=8080/tcp
firewall-cmd --reload
Logging and Auditing
API requests are logged at DEBUG level:
logging:
level: debug # Enables API request logging
format: json # Structured logs for SIEM
Log format:
{
"time": "2025-01-15T10:30:00Z",
"level": "DEBUG",
"msg": "api request",
"method": "GET",
"path": "/api/v1/health/servers",
"status": 200,
"duration_ms": 5,
"remote_addr": "192.168.1.100:45678"
}
ACL denials are logged at WARN level:
{
"time": "2025-01-15T10:30:00Z",
"level": "WARN",
"msg": "access denied by ACL",
"client_ip": "10.0.0.1",
"path": "/api/v1/health/servers"
}
Checklist
API bound to localhost or specific interface
allowed_networksrestricted to necessary IPstrust_proxy_headersonly enabled behind trusted proxyReverse proxy handles authentication
TLS encryption for any network access
Firewall rules as defense-in-depth
API access logged and monitored
Regular review of allowed_networks