Skip to main content

How to Configure HA Proxy in DMZ

This how-to guides IT Admins and Implementation Consultants to securely deploy ServiceOps using HAProxy in a DMZ, protecting core application and database servers while supporting DR.

In this pattern, an HAProxy in the DMZ accepts public HTTPS traffic and forwards it to the internal Application server, which communicates with the Database server. This minimizes the attack surface and centralizes TLS and access controls at the edge.

Prerequisites

Before starting, review and satisfy the following:

Hardware Requirements

  • Application & Database: Split current memory provision equally between App and DB servers.
  • HA Proxy: 4 Core CPU, 4 GB RAM, 100 GB Disk.

Port Requirements

PortComponent(s)DirectionPurpose
443HA ProxyInboundHTTPS for ServiceOps UI (public)
80ApplicationFrom HA ProxyHTTP to Application (if SSL terminates at HAProxy)
443Application (optional)From HA ProxyHTTPS to Application (if re-encrypting to backend)
5432Application ↔ DatabaseInternal onlyDatabase connectivity
note

Choose either HTTP 80 or HTTPS 443 for the backend based on your security policy.

Firewall Configuration Snippets

For Ubuntu (UFW):

sudo ufw allow 443/tcp
sudo ufw allow 5432/tcp

For RHEL/CentOS (firewalld):

sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=5432/tcp --permanent
sudo firewall-cmd --reload

Deployment Scenarios for ServiceOps with HAProxy in DMZ

This guide details three common architectural patterns for deploying ServiceOps using HAProxy in a DMZ. Each scenario offers different trade-offs regarding security, performance, and complexity, allowing you to choose the best fit for your organizational needs and compliance requirements.

Before proceeding, review the quick selection guide to identify the most suitable scenario for your deployment.

Quick Selection Guide

  • Need fastest proxy→app path, OK hosting app in DMZ? → Scenario 1
  • Max security, simplest DMZ footprint (proxy only), App+DB together? → Scenario 2
  • Enterprise scale, independent App/DB scaling, strict least-privilege? → Scenario 3

Scenario 1 — HAProxy and ServiceOps App in DMZ; DB in Secured Network

Figure 1: Scenario 1 - HAProxy and ServiceOps App in DMZ; DB in Secured Network

Architecture

  • DMZ:
    • HAProxy (TLS termination, WAF-like rules, rate limiting)
    • ServiceOps App (one or more nodes)
  • Secured Network:
    • Database Server (ServiceOps DB)

Components & Roles

  • HAProxy (DMZ)
    • Public entry point on 443, terminates TLS, forwards to ServiceOps App.
    • Optional: mTLS for agents/integrations, WAF rules, IP allow/deny lists.
  • ServiceOps App (DMZ)
    • Hosts the web UI + APIs.
    • Initiates outbound DB connections to the secured network.
  • Database (Secured)
    • Stores all data; not internet-reachable.
    • Only the App can reach DB.

Use Cases

  • Internet-facing access is required, and you want lower latency between proxy and app.
  • Small/medium deployments where hardening the app host in DMZ is acceptable.

Benefits

  • Fast path (proxy→app) stays in DMZ.
  • DB remains protected inside the secure network.
  • Simple to scale app nodes horizontally in DMZ.

Configuration

  • Firewall / Ports

    • Internet → HAProxy (DMZ): 443 (TCP)
    • HAProxy (DMZ) → App (DMZ): 80/443 (TCP) (prefer 443)
    • App (DMZ) → DB (Secured): DB port (e.g., 5432 for PostgreSQL / 1433 for MS SQL)
    • Secured → DMZ (optional): Monitoring/SSH/Ansible as per ops policy
  • HAProxy (example)

    • Place this configuration snippet in /etc/haproxy/haproxy.cfg to define the frontend and backend for Scenario 1. Adjust IP addresses and certificate paths as per your environment.
    # /etc/haproxy/haproxy.cfg
    global
    log /dev/log local0
    maxconn 5000

    defaults
    log global
    mode http
    timeout connect 5s
    timeout client 60s
    timeout server 60s
    option httplog

    frontend fe_serviceops_https
    bind :443 ssl crt /etc/haproxy/certs/serviceops.pem alpn h2,http/1.1
    http-response set-header Strict-Transport-Security "max-age=31536000"
    acl healthcheck path -i /healthz
    use_backend be_health if healthcheck
    default_backend be_serviceops_app

    backend be_serviceops_app
    option httpchk GET /healthz
    http-check expect status 200
    balance leastconn
    # DMZ app nodes
    server app1 10.10.10.21:443 ssl verify none check
    server app2 10.10.10.22:443 ssl verify none check
    # If the app uses in-memory sessions, enable stickiness:
    # cookie SRV insert indirect nocache
    # server app1 10.10.10.21:443 ssl verify none check cookie A
    # server app2 10.10.10.22:443 ssl verify none check cookie B

    backend be_health
    mode http
  • ServiceOps App

    • Configure the ServiceOps Application to connect to the secured network Database host using its hostname/IP, port, and credentials.
    • Enforce TLS for the database connection if supported by your database (e.g., sslmode=require for PostgreSQL).

Notes

  • Harden the App hosts in DMZ (OS CIS hardening, minimal packages, auto-patching).
  • No direct DMZ → DB exposure from public; traffic goes App→DB only.
  • Consider IDS/IPS between DMZ and Secure LAN.

Common Notes (All Scenarios)

This section provides general notes and considerations applicable across all HAProxy deployment scenarios for ServiceOps.

  • Certificates & TLS
    • Use strong ciphers, TLS 1.2+; keep certificates on HAProxy if you terminate TLS there.
    • HSTS should be enabled on the public entry point.
    • Consider mTLS for agents/integrations that post data to ServiceOps for enhanced security.
  • Observability
    • Export HAProxy logs to a SIEM (Security Information and Event Management) system for centralized monitoring and analysis.
    • Enable a dedicated Application health endpoint (e.g., /healthz or /status) for load balancer checks.
    • Implement synthetic checks (external) to validate end-to-end application availability and performance.
  • Hardening
    • Lock down management ports (SSH, RDP) to bastion/jump hosts only.
    • Apply OS and package hardening guidelines (e.g., CIS benchmarks), and ensure auto-patching is configured where safe and appropriate.
    • Implement rate limiting for login APIs and enable bot/DoS mitigation at the HAProxy layer.
  • DNS
    • The Public FQDN (Fully Qualified Domain Name) should resolve to the HAProxy in the DMZ.
    • Consider split-horizon DNS if internal FQDNs for Application and Database servers differ from their public counterparts.

Example Minimal "Getting Started" Steps (any scenario)

This section provides a minimal set of steps to get started with any of the HAProxy deployment scenarios.

  1. Install HAProxy on the DMZ host and place your certificate (e.g., combined .pem file) at /etc/haproxy/certs/serviceops.pem.
  2. Create a health endpoint on the ServiceOps Application (e.g., /healthz returning a 200 HTTP status code) for HAProxy health checks.
  3. Configure haproxy.cfg using the matching backend example above for your chosen scenario, then reload or restart HAProxy (systemctl restart haproxy).
  4. Open firewalls exactly as listed in the chosen scenario's "Firewall / Ports" section; deny all other inbound traffic by default.
  5. Set the ServiceOps base URL to the public FQDN (the domain behind HAProxy).
  6. Test critical paths: external browser access via FQDN, internal Application to Database connectivity, and failover between application nodes (if clustered).
  7. Enable logging/metrics for HAProxy and ServiceOps, and set up alerts on health status, 5xx error rates, and latency thresholds.

Verification Checklist

To ensure successful deployment and operation, verify the following:

  • HAProxy Configuration: Validate the syntax of /etc/haproxy/haproxy.cfg to ensure no errors.

    haproxy -c -f /etc/haproxy/haproxy.cfg
  • HAProxy Service Status: Confirm the HAProxy service is running and check its logs for any issues.

    systemctl status haproxy | cat
    journalctl -u haproxy -e | tail -n 100
  • Public Connectivity: Test access to your application through the public DNS/VIP to ensure it's reachable.

    curl -kI https://your-domain.example.com/
  • SSL Certificate Inspection (Optional): Verify the presented SSL certificate details for correctness and validity.

    openssl s_client -connect your-domain.example.com:443 -servername your-domain.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
  • Application to Database Connectivity: Ensure the Application server can reach the Database on port 5432 and that firewall rules permit this internal communication.

    ss -lntp | grep -E '(\:443|\:5432)'

Operational Notes & Best Practices

This section provides important operational considerations and best practices for maintaining your HAProxy and ServiceOps deployment.

  • Use a full certificate chain on HAProxy and ensure timely renewal to prevent service interruptions.
  • Restrict access to HAProxy statistics (/haproxy?stats) or other management endpoints via ACLs or basic authentication.
  • Ensure log rotation is configured for HAProxy to prevent excessive disk growth due to log accumulation.
  • Document all critical IPs, DNS entries, and certificate locations for effective disaster recovery and reproducibility.

Troubleshooting

This section provides common troubleshooting steps for issues that may arise during or after deployment.

  • Page does not load through VIP/DNS: validate HAProxy bind IPs and certificate paths; run haproxy -c -f ... to check configuration syntax.
  • Backend health checks failing: confirm the Application server is reachable on the configured port from HAProxy; review firewall rules between DMZ and internal network.
  • TLS errors: ensure the PEM file includes the full certificate chain and that file permissions are 600 with root:root ownership for sensitive certificate files.

Rollback Procedure

In case of issues or undesirable behavior after changes, follow this procedure to revert to a previous working configuration.

# Create timestamped backup of current HAProxy configuration
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak.$(date +%F)

# After changes, to revert to a specific backup (replace YYYY-MM-DD with the backup date)
mv /etc/haproxy/haproxy.cfg.bak.YYYY-MM-DD /etc/haproxy/haproxy.cfg
systemctl restart haproxy

This section addresses frequently asked questions related to HAProxy deployment in a DMZ.

Q: Why can't we host the Application server directly in the DMZ?
A: Hosting the Application server directly in the DMZ exposes it to public traffic, significantly increasing the attack surface. Using HA Proxy ensures that only the proxy is exposed, while the Application and Database servers remain protected in the internal network, reducing potential security risks.

Next Steps

After successfully deploying HAProxy and ServiceOps, consider these next steps for advanced configuration and maintenance:

  • Review the HA deployment guide’s verification and operational best practices for advanced scenarios.
  • If re-encrypting to the backend, align certificate management between HAProxy and Application nodes to ensure seamless and secure communication.
  • Consider adding HAProxy stats authentication and robust network ACLs (Access Control Lists) before going live with your production environment.