In enterprise environments managing multiple internal applications and microservices, the standard practice is often deploying complex stacks such as NGINX, Traefik, or container-based balancers. However, where stability, minimalism, and kernel-level security are paramount, OpenBSD’s native relayd(8) daemon delivers a clean, lightweight, and auditable solution.
This case study demonstrates how XYZ Corp centralizes public HTTPS traffic across three distinct internal workloads using domain-based L7 routing, strict TLS termination, and active backend health monitoring.
1. Scenario and Requirements for XYZ Corp
XYZ Corp operates 3 separate services hosted in isolated subnets:
app.xyz.corp: Core customer portal (Go backend running on10.0.1.10:3000).api.xyz.corp: High-availability REST API (Load balanced between10.0.1.20:8000and10.0.1.21:8000).portal.xyz.corp: Corporate static portal and documentation (Served by OpenBSDhttpd(8)on127.0.0.1:8080).
2. Topology and Flow Diagram
[ INTERNET / Public HTTPS:443 Traffic ]
|
v
+-------------------+
| OpenBSD Edge |
| - PF Firewall |
| - relayd(8) TLS | (Public IP: 198.51.100.1)
+-------------------+
|
+-----------------------+-----------------------+
| Host: app.xyz.corp | Host: api.xyz.corp | Host: portal.xyz.corp
v v v
+---------------+ +------------------+ +------------------+
| Backend APP | | REST API Cluster | | Static Portal |
| 10.0.1.10:3000| | .20:8000 .21:8000| | 127.0.0.1:8080 |
+---------------+ +------------------+ +------------------+
3. Full /etc/relayd.conf Implementation
# /etc/relayd.conf - Multi-Tenant Setup for XYZ Corp
# 1. Backend Pools with Active Health Checks
table <backend_app> {
10.0.1.10
}
table <cluster_api> {
10.0.1.20
10.0.1.21
}
table <backend_portal> {
127.0.0.1
}
# 2. HTTP Protocol & Security Policies
http protocol "https_corporate_filter" {
tcp { nodelay, sack, socket buffer 65536 }
# Proxy Headers
match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
match request header append "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
match request header set "X-Forwarded-Proto" value "https"
# Global Security Headers
match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubDomains; preload"
match response header set "X-Content-Type-Options" value "nosniff"
match response header set "X-Frame-Options" value "DENY"
match response header set "Referrer-Policy" value "strict-origin-when-cross-origin"
# L7 Routing based on Host Header
match request header "Host" value "app.xyz.corp" forward to <backend_app>
match request header "Host" value "api.xyz.corp" forward to <cluster_api>
match request header "Host" value "portal.xyz.corp" forward to <backend_portal>
}
# 3. Public TLS Relay Definition
relay "tls_gateway" {
listen on 198.51.100.1 port 443 tls
protocol "https_corporate_filter"
# Default fallback
forward to <backend_portal> port 8080 check http "/healthz" code 200
# Specific forwards with dedicated backend ports and health probes
forward to <backend_app> port 3000 check http "/status" code 200
forward to <cluster_api> port 8000 check http "/v1/health" code 200
}
4. Live Inspection with relayctl(8)
Verify runtime health status across all backend tables:
doas relayctl show summary
Output:
Id Type Name Avlblty Status
1 relay tls_gateway active
1 table backend_app:3000 active
1 host 10.0.1.10 100.00% up
2 table cluster_api:8000 active
2 host 10.0.1.20 100.00% up
3 host 10.0.1.21 100.00% up
3 table backend_portal:8080 active
4 host 127.0.0.1 100.00% up