📘 HAProxy Dynamic Provisioning (Maps + Certbot + Multi-backend)

Автор George, Май 21, 2026, 03:22

« назад - далее »

George

HAProxy Dynamic Provisioning System

Назначение:
Система автоматического управления HAProxy:
- создание backend'ов
- работа с maps (hosts / passth / acme)
- выпуск SSL сертификатов (Let's Encrypt)
- поддержка multi-node backend
- zero-downtime reload

---

📦 Архитектура

Код: bash
Client
  ↓
HAProxy (:80 / :443)
  ↓
Maps routing:
   ├── hosts.map (HTTP backend)
   ├── passth.map (TLS SNI backend)
   └── acme_backends.map (ACME HTTP backend)
  ↓
Backends (auto-generated)

---

⚙️ CLI инструмент

Основной скрипт:

Код: bash
/usr/local/bin/haproxy-map-update.sh

---

📌 Общий синтаксис

Код: bash
haproxy-map-update.sh set DOMAIN BACKEND MODE IP_LIST PORT [-y]
haproxy-map-update.sh del DOMAIN

---

🧪 Примеры использования

---

1. HTTP сайт (один сервер)

Код: bash
haproxy-map-update.sh set ftp.cloud-life.site ftp http 10.10.1.37 80 -y

Результат:
- backend ftp:80
- certbot через HAProxy (8888)
- hosts.map обновлён

---

2. HTTPS backend (multi-node passthrough)

Код: bash
haproxy-map-update.sh set games.cloud-life.site games passth "10.10.1.46,10.10.1.47,10.10.1.48" 443 -y

Результат:
- acme_games (HTTP/80)
- games backend (HTTPS/443)
- roundrobin между нодами
- SSL verify none

---

3. Удаление домена

Код: bash
haproxy-map-update.sh del games.cloud-life.site

---

🔐 SSL схема (Let's Encrypt)

HTTP challenge flow:

Код: bash
Internet → HAProxy :80
         → /.well-known/acme-challenge/
         → 127.0.0.1:8888 (certbot standalone)

---

⚙️ Backend types

HTTP backend:
- один сервер или несколько
- порт 80
- certbot active

PASSTH backend:
- TLS SNI routing
- порт 443
- multi-node support
- acme backend auto-created

---

📂 Maps

Код: bash
/etc/haproxy/maps/hosts.map
/etc/haproxy/maps/passth.map
/etc/haproxy/maps/acme_backends.map

---

🧠 Особенности системы

  • Backend создаётся автоматически при отсутствии
  • Поддержка multi-server (comma-separated IPs)
  • HTTPS backend автоматически получает ssl verify none
  • ACME backend создаётся отдельно для passth
  • Maps сортируются по длине ключа (важно для subdomains)
  • HAProxy reload только после всех операций

---

🚀 Multi-server пример

Код: bash
IP_LIST="10.10.1.46,10.10.1.47,10.10.1.48"
PORT=443

Результат:
Код: bash
server games1 10.10.1.46:443 ssl verify none check
server games2 10.10.1.47:443 ssl verify none check
server games3 10.10.1.48:443 ssl verify none check

---

💡 Режим -y

Автоматическое создание backend без вопросов:

Код: bash
-y

---

🏁 Итог

Система заменяет:
- ручное редактирование haproxy.cfg
- ручное управление backend'ами
- ручное создание SSL
- ручной reload

И превращает HAProxy в:
динамический ingress controller уровня mini-Kubernetes
  •  

George

📌 Core Scripts (HAProxy Dynamic System)

1. MAIN CLI:
Код: bash
/usr/local/bin/haproxy-map-update.sh

---

2. CERT ENGINE:
Код: bash
/usr/local/bin/haproxy-cert.sh

---

⚙️ 1. haproxy-cert.sh

Код: bash
#!/bin/bash
set -euo pipefail

DOMAIN=${1:-}

if [ -z "$DOMAIN" ]; then
    echo "[CERT] no domain!"
    exit 1
fi

echo "[CERT] Issuing certificate for $DOMAIN"

certbot certonly --standalone \
  --http-01-port=8888 \
  -d "$DOMAIN" \
  --non-interactive \
  --agree-tos \
  --email george@cloud-life.site \
  --expand

echo "[CERT] Building PEM"

cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem \
    /etc/letsencrypt/live/$DOMAIN/privkey.pem \
    > /etc/ssl/haproxy/$DOMAIN.pem

echo "[CERT] Done"

---

⚙️ 2. haproxy-map-update.sh

Код: bash
#!/bin/bash

GREEN="\033[0;32m"
NC="\033[0m"
RED="\033[0;31m"

CFG="/etc/haproxy/haproxy.cfg"

HOSTS_MAP="/etc/haproxy/maps/hosts.map"
PASSTH_MAP="/etc/haproxy/maps/passth.map"
ACME_MAP="/etc/haproxy/maps/acme_backends.map"

usage() {
    echo -e "${GREEN}"
    echo "Usage:"
    echo "  $0 set DOMAIN BACKEND MODE IP_LIST PORT [-y]"
    echo "  $0 del DOMAIN"
    echo -e "${NC}"
    exit 1
}

if [ $# -lt 2 ]; then
    usage
fi

ACTION=$1
DOMAIN=$2
BACKEND=${3:-}
MODE=${4:-}
IP_LIST=${5:-}
PORT=${6:-}
AUTO_YES=${7:-}

set -euo pipefail

backend_exists() {
    grep -q "^backend $BACKEND" "$CFG"
}

build_servers() {
    IFS=',' read -ra IPS <<< "$IP_LIST"
    i=1
    SERVERS=""

    for ip in "${IPS[@]}"; do
        name="${BACKEND}${i}"

        if [ "$PORT" == "443" ]; then
            SERVERS+="    server ${name} ${ip}:${PORT} ssl verify none check\n"
        else
            SERVERS+="    server ${name} ${ip}:${PORT} check\n"
        fi

        i=$((i+1))
    done
}

create_backend() {

    echo "[BACKEND] Creating: $BACKEND"

    if [ -z "${IP_LIST:-}" ]; then
        read -p "IP(s): " IP_LIST
    fi

    if [ -z "${PORT:-}" ]; then
        read -p "PORT: " PORT
    fi

    build_servers

    TMP=$(mktemp)

    awk -v block="$(cat <<EOF
backend $BACKEND
    mode http
    balance roundrobin
    option forwardfor header X-Real-IP
    http-request set-header X-Forwarded-For %[src]
    http-request set-header X-Forwarded-Port %[dst_port]

$SERVERS
EOF
)" '
    /# --- AUTO_BACKENDS_END ---/ {
        print block
    }
    { print }
    ' "$CFG" > "$TMP"

    mv "$TMP" "$CFG"
}

issue_cert() {
    /usr/local/bin/haproxy-cert.sh "$DOMAIN"
}

update_map() {
    local MAP=$1
    local KEY=$2
    local VALUE=$3

    TMP=$(mktemp)
    [ -f "$MAP" ] && cp "$MAP" "$TMP"

    grep -v "^$KEY " "$TMP" > "$TMP.new" || true
    echo "$KEY $VALUE" >> "$TMP.new"

    mv "$TMP.new" "$MAP"
    rm -f "$TMP"
}

delete_maps() {
    for m in "$HOSTS_MAP" "$PASSTH_MAP" "$ACME_MAP"; do
        [ -f "$m" ] && grep -v "^$DOMAIN " "$m" > "$m.tmp" && mv "$m.tmp" "$m"
    done
}

engine() {
    for MAP in "$HOSTS_MAP" "$PASSTH_MAP" "$ACME_MAP"; do
        [ -f "$MAP" ] || continue
        awk '{ print length($1), $0 }' "$MAP" | sort -nr | cut -d" " -f2- > "$MAP.tmp"
        mv "$MAP.tmp" "$MAP"
    done
}

echo "[MAP] $DOMAIN"

if [ "$ACTION" == "set" ]; then

    if ! backend_exists; then
        if [[ "$AUTO_YES" == "-y" ]]; then
            create_backend
        else
            read -p "Create backend $BACKEND? [Y/n]: " c
            [[ "$c" =~ ^[Nn]$ ]] && exit 1
            create_backend
        fi
    fi

    if [ "$MODE" == "http" ]; then
        issue_cert
        update_map "$HOSTS_MAP" "$DOMAIN" "$BACKEND"

    elif [ "$MODE" == "passth" ]; then
        update_map "$PASSTH_MAP" "$DOMAIN" "$BACKEND"
        update_map "$ACME_MAP" "$DOMAIN" "acme_${BACKEND}"
    fi

    delete_maps
    engine
    systemctl reload haproxy

elif [ "$ACTION" == "del" ]; then
    delete_maps
    engine
    systemctl reload haproxy
fi

echo -e "${GREEN}[DONE]${NC}"

---

📌 Требуемая структура HAProxy:

Код: bash
# --- AUTO_BACKENDS_END ---

---

🏁 Результат

  • Полностью автоматическое создание backend'ов
  • Multi-node поддержка
  • ACME + TLS split
  • Maps-driven routing
  • UI-ready CLI backend
  •  

ktaletmkec

zithromax joint pain  zithromax en espaГ±ol  buy zithromax z-pak zithromax renal dosing  when is the best time to take zithromax 
lyrica coming off  lyrica and dry mouth  buy lyrica for seizures how long does it take for lyrica to kick in  how long to take lyrica for shingles
  •  

🡱 🡳

Отметьте интересные вам фрагменты текста и они станут доступны по уникальной ссылке в адресной строке браузера.