Reverse Proxy: Fundamentals of Service Consolidation

Reverse Proxy: Fundamentals of Service Consolidation

SSL termination, domain-based routing, and backend communication. Reverse proxy concepts for service consolidation and secure self-hosting architectures.

Software and versions used

This explanation applies to:

  • HTTP protocol: HTTP/1.1, HTTP/2, HTTP/3
  • SSL/TLS: Version 1.2+ for secure connections
  • Reverse proxy concepts: Platform-independent fundamentals
  • Context: Distribution-independent proxy fundamentals

Reverse Proxy mediates between clients and backend services

A reverse proxy receives client requests and forwards them to backend services—the opposite of a forward proxy, which relays client requests to external servers. This intermediary role enables service consolidation: ten different web applications share one public IP address over port 443 instead of requiring separate IP addresses or ports for each service.

Article 1 and Article 5 explain IP addresses, ports, and firewall concepts. A reverse proxy extends these concepts with service mediation: Plausible Analytics listens internally on port 8000, Matrix Synapse on port 8008, and Listmonk on port 9000. The reverse proxy receives all HTTPS requests on port 443 and decides which backend service processes the request based on the HTTP Host header.

Client requests contain domain information in the Host header: GET / HTTP/1.1 Host: analytics.example.com. The proxy reads this header and forwards the request to the corresponding backend—analytics.example.com to 127.0.0.1:8000, chat.example.com to 127.0.0.1:8008. Clients only see the standard HTTP ports 80 and 443, while backend services can use any internal ports.

This Host header mediation works transparently: browsers send ordinary HTTPS requests, and the proxy translates them into HTTP backend requests. Responses travel the reverse path—the backend response is forwarded as the client response. Clients cannot tell that the backend services are running on different ports or IP addresses.

SSL termination centralizes encryption and certificate management

HTTPS connections require a TLS handshake, certificate validation, and encryption/decryption for every request. SSL termination at the reverse proxy centralizes these cryptographic operations. Client connections are decrypted at the proxy, while backend communication takes place unencrypted over localhost or private networks.

The proxy centrally manages SSL certificates and private keys for all domains. A wildcard certificate for *.example.com covers analytics.example.com, chat.example.com, and newsletter.example.com. The backend services implement only HTTP—the SSL configuration exists only once on the proxy instead of separately in every service.

SSL termination enables modern TLS features without modifying backend services. HTTP/2 multiplexes multiple requests over a single TCP connection and reduces latency. Perfect Forward Secrecy generates temporary keys for each session, so compromised server keys cannot decrypt past connections. OCSP Stapling validates certificate status in advance and reduces client latency during the TLS handshake.

Client (HTTPS Port 443) → Reverse Proxy (SSL termination) → Backend (HTTP Port 8000)

Backend services receive client information through HTTP headers: X-Forwarded-For for the client IP, X-Forwarded-Proto: https for the original protocol, and X-Real-IP for the original source address. These headers enable correct backend logging and IP-based access control despite proxy mediation.

Domain-based routing uses the HTTP Host header for service selection

HTTP/1.1 introduced the Host header for virtual hosting—multiple websites sharing a single IP address. Reverse proxies use this mechanism for backend selection: identical URLs are forwarded to different services depending on the domain.

Wildcard domains scale automatically: one rule for *.api.example.com matches both v1.api.example.com and v2.api.example.com. Subdomain patterns route different API versions to their corresponding backend services. New subdomains automatically inherit the appropriate routing rules without manual configuration.

Path-based routing combines the domain and the URL path for granular service separation: example.com/api/* to the API server on port 3000, example.com/admin/* to the administration interface on port 4000, and example.com/* to the frontend website on port 5000. A single domain serves multiple specialized backend services based on the URL structure.

This routing flexibility enables service architectures with clear separation. The API backend, administration interface, and public website run as separate processes with their own scaling characteristics while remaining accessible through consistent domain names.

Backend communication transfers client context through HTTP headers

Backend services behind reverse proxies lose direct contact with the client—all requests appear to originate from the proxy. HTTP headers transfer the original client information: X-Forwarded-For for the client IP, X-Forwarded-Proto for the original protocol, and X-Forwarded-Host for the requested domain.

Proxy-to-backend requests extend the standard HTTP headers with client context:

Original client request:
GET /dashboard HTTP/1.1
Host: analytics.example.com

Proxy-to-backend request:
GET /dashboard HTTP/1.1
Host: analytics.example.com
X-Forwarded-For: 203.0.113.25
X-Forwarded-Proto: https
X-Real-IP: 203.0.113.25

Backend services must evaluate these headers to behave correctly. Logging systems use X-Forwarded-For to record the real client IPs instead of the proxy address. Rate limiting is based on the original client IPs. Redirect URLs use X-Forwarded-Proto to generate correct HTTPS URLs.

Trusted proxy configuration prevents header spoofing. Backend services accept forwarded headers only from configured proxy IPs (127.0.0.1, private networks). Unknown clients cannot forge X-Forwarded-For—security is established through IP-based trust.

Load balancing and connection pooling optimize backend communication

Load balancing distributes incoming requests across multiple backend instances to increase fault tolerance and improve performance. Round Robin cycles through the available backends. Least Connections forwards requests to the backend with the fewest active connections. IP Hash ensures session persistence by assigning backends based on the client IP.

Health checks monitor backend availability through regular test requests. Backends that stop responding are automatically removed from the load-balancing pool until they become reachable again. Automated failure handling enables uninterrupted service updates and backend maintenance.

Establishing TCP connections between the proxy and backend introduces handshake overhead for every request. Connection pooling keeps TCP connections to backend services open and reuses them for multiple HTTP requests. Persistent connections reduce latency and CPU utilization by eliminating repeated connection establishment.

Keep-Alive parameters define connection reuse: the maximum number of requests per connection, the idle timeout for unused connections, and the pool size per backend. These parameters balance resource utilization against performance improvements based on traffic patterns.

Caching and security features extend proxy functionality

Reverse proxy caching temporarily stores backend responses and serves repeated requests directly from the cache. Static assets (CSS, JavaScript, images) are cached after the first request and delivered directly by the proxy without placing additional load on the backend.

Cache-Control headers define caching behavior: Cache-Control: max-age=3600 allows caching for one hour, while Cache-Control: no-cache forces backend validation for every request. ETag headers enable conditional requests—the proxy checks whether content has changed without transferring the entire response.

Security features implement defense-in-depth strategies at the application layer. Security headers such as Strict-Transport-Security enforce HTTPS, X-Content-Type-Options prevent MIME type sniffing, and X-Frame-Options block clickjacking. Injecting these headers protects backend services without requiring individual implementations.

Rate limiting restricts the request frequency per client IP or session and protects against brute-force attacks. IP-based access control filters requests based on source addresses before forwarding them to the backend. Web Application Firewall features analyze HTTP requests for suspicious patterns such as SQL injection or cross-site scripting.

Monitoring and troubleshooting for service monitoring

Ten backend services generate ten separate log files in different directories. This makes troubleshooting more difficult: was the slow request caused by Plausible on port 8000 or Matrix on port 8008? Reverse proxy logs centralize this information—all requests pass through a single point with consistent logging.

Request-response time measurements distinguish between client-to-proxy latency and proxy-to-backend latency. A request to analytics.example.com suddenly takes 5 seconds instead of 200 ms. The proxy logs immediately reveal whether the problem lies in the SSL handshake (high client-to-proxy latency) or in the backend service (high proxy-to-backend latency).

Access logs use structured formats for automated analysis: Combined Log Format, JSON logs, or custom formats with request IDs for trace correlation. These logs contain complete request information: client IP, request URL, response codes, response times, and backend server.

Health check monitoring continuously tracks backend availability and records outages with timestamps. Backend pool status shows active and inactive services for capacity planning. Failover events are logged for post-incident analysis and service-level agreement reporting.


Next steps:

Michael of the Dragons

develops books, software, and open frameworks around technical systems, digital independence, and durable software architectures.
More about Michael →
Reverse Proxy: Fundamentals of Service Consolidation
Previous Article → Firewall Principles: Understanding Packet Filtering and Connection Tracking