Skip to main content

HAProxy EC2 Instance Setup Documentation

Overview

This document describes the setup of our production HAProxy instance (prod.haproxy) which handles SSL termination for our domains. The setup uses HAProxy 3.0 and acme.sh for automated SSL certificate management.

Core Components

1. HAProxy Installation

# Install HAProxy 3.0
sudo apt-get install --no-install-recommends software-properties-common
sudo add-apt-repository ppa:vbernat/haproxy-3.0
sudo apt-get install haproxy=3.0.*

Command Explanation:

  • --no-install-recommends: Only installs the essential packages, skipping recommended packages
  • ppa:vbernat/haproxy-3.0: Personal Package Archive for HAProxy 3.0
  • haproxy=3.0.*: Specifies the version to install, where * matches any minor version

2. SSL Certificate Management (acme.sh)

Installation

# Clone and install acme.sh
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh/
./acme.sh --install -m my@email.com
sudo ln -s ~/.acme.sh/acme.sh /usr/local/bin/
sudo chmod 755 ~/.acme.sh

Command Explanation:

  • --install: Installs acme.sh to ~/.acme.sh/
  • -m email@example.com: Registers the email for Let's Encrypt notifications
  • ln -s: Creates a symbolic link for system-wide access
  • chmod 755: Sets read and execute permissions for all users, write for owner only

Configuration

Environment variables in ~/.acme.sh/account.conf:

# Certificate deployment path
DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs

# Command to reload HAProxy after certificate updates
DEPLOY_HAPROXY_RELOAD="sudo service haproxy restart"

# Cloudflare API credentials
CF_Token="your-token"
CF_Zone_ID="your-zone-id"

# Slack notifications
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."

3. Certificate Directory Setup

sudo mkdir /etc/haproxy/certs
sudo chown haproxy:haproxy /etc/haproxy/certs
sudo chmod 770 /etc/haproxy/certs

Command Explanation:

  • chmod 770: Gives read/write/execute to owner and group, nothing to others
  • chown haproxy:haproxy: Sets ownership to haproxy user and group

SSL Certificate Management

Issue New Certificates

acme.sh --issue --dns dns_cf --server letsencrypt \
-d mydomain.com \
-d *.mydomain.com

Command Options:

  • --issue: Issues a new certificate
  • --dns dns_cf: Uses Cloudflare DNS API for domain validation
  • --server letsencrypt: Specifies Let's Encrypt as the CA
  • -d domain.com: Specifies the domain(s) for the certificate
  • -d *.domain.com: Adds wildcard subdomain support

Deploy Certificates

acme.sh --deploy -d mydomain.com --deploy-hook haproxy

Command Options:

  • --deploy: Deploys the certificate
  • -d domain.com: Specifies which domain's certificate to deploy
  • --deploy-hook haproxy: Uses the HAProxy deployment method

User and Permission Management

Add User to HAProxy Group

sudo usermod -aG haproxy ubuntu
# or
sudo adduser ubuntu haproxy

Command Options:

  • usermod -aG: Adds user to a supplementary group
  • adduser user group: Adds user to group (alternative method)

Set Directory Permissions

sudo chown ubuntu:haproxy /etc/haproxy/certs
sudo chmod 750 /etc/haproxy/certs

Command Options:

  • chmod 750: Owner can read/write/execute, group can read/execute, others nothing
  • chown user:group: Changes ownership of directory

Monitoring Setup

Configure Slack Notifications

acme.sh --set-notify --notify-hook slack --notify-level 3

Command Options:

  • --set-notify: Enables notifications
  • --notify-hook slack: Uses Slack for notifications
  • --notify-level 3: Sets notification verbosity (1-3, where 3 is most verbose)

Adding a New Domain

Issue Certificate with Additional Domain

acme.sh --issue --dns dns_cf --server letsencrypt \
-d mydomain.com \
-d *.mydomain.com \
-d myapp.com \
-d *.myapp.com

Deploy Updated Certificate

acme.sh --deploy -d mydomain.com --deploy-hook haproxy

Verification Commands

Check Certificate Status

acme.sh --list

Command Options:

  • --list: Shows all managed certificates and their status

Check HAProxy Configuration

haproxy -c -f /etc/haproxy/haproxy.cfg

Command Options:

  • -c: Check configuration file syntax
  • -f file: Specify configuration file path

Automatic Renewal

acme.sh adds a cron job automatically during installation. View it with:

crontab -l

The default renewal period is 60 days before expiration. Renewals are automatic and will use the same configuration used during certificate issuance.