Sysadmin
May 27

Установка прокси-сервера и балансировщика HAProxy

Предположим, что у нас есть один белый IP-адрес, на который нужно навесить различные сервисы.
Идеальный вариант для этого - использование обратного прокси-сервера, например чуть ранее был описан способ virtual host на Nginx

Установка HAProxy

Чаще всего HAProxy уже находится в стандартном репозитории:

apt install -y haproxy
mv /etc/haproxy/haproxy.conf{,.orig}

Например настроим haproxy для перенаправления всего трафика http (80) и https (443) на виртуальную машину router, предварительно настроенную для маршрутизации, например в гипервизоре Proxmox VE, с выдачей IP адреса по DHCP и регистрацией в DNS, с настроенным Nginx и виртуальными хостами.

haproxy.conf - simple

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option forwardfor
        #option http-server-close
        timeout connect 10s
        timeout client  60s
        timeout server  60s

        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

listen stats
        stats enable
        mode http
        bind :7000
        stats realm      Haproxy\ Statistics
        stats auth someuser:somepassword
        stats uri /haproxystats
        stats refresh    30s

frontend http_bind
        bind *:80
        mode tcp
        option tcplog
        default_backend router_http

frontend https_bind
        bind *:443
        mode tcp
        option tcplog
        default_backend router_https

backend router_http
        mode tcp
        balance leastconn
        option httpclose
        option forwardfor
        server router_server router.antroot.lan:80
        server router_server router2.antroot.lan:80

backend router_https
        mode tcp
        server router_server router.antroot.lan:443

Добавим немного логики в haproxy, чтобы убрать из цепочки nginx.
Включим виртуальные хосты, перенаправим http-трафик на порт 80 соответствующих виртуальных машин, а https-трафик перенаправим на четвертом уровне сетевой модели по TCP, чтобы не пришлось устанавливать SSL-сертификаты на haproxy. Также это полезно, если в качестве конечного пункта выступает ingress кластера Kubernetes:

haproxy.conf - ssl passthrough

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 10s
        timeout client  60s
        timeout server  60s
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend http_in
        mode http
        option httplog
        bind *:80
        option forwardfor
        acl host_pve hdr(host) -i pve.antroot.ru
        acl host_git hdr(host) -i gitlab.antroot.ru
        acl host_wik hdr(host) -i wiki.antroot.ru
        acl host_k8s hdr(host) -i k8s.antroot.ru
        use_backend http_pve if host_pve
        use_backend http_git if host_git
        use_backend http_wik if host_wik
        use_backend http_k8s if host_k8s

backend http_pve
        mode http
        option httplog
        option forwardfor
        server pve pve.antroot.lan:80
backend http_git
        server git gitlab.antroot.lan:80
backend http_wik
        server wiki wiki.antroot.lan:80
backend http_k8s
        server k8s k8s.antroot.lan:80

frontend https_in
        mode tcp
        option tcplog
        option ssl-hello-chk # !
        bind *:443
        acl tls req.ssl_hello_type 1
        tcp-request inspect-delay 5s
        tcp-request content accept if tls
        #tcp-request content accept if { req.ssl_hello_type 1 }

        acl host_pve hdr(host) req.ssl_sni -i pve.antroot.ru
        acl host_git hdr(host) req.ssl_sni -i gitlab.antroot.ru
        acl host_wik hdr(host) req.ssl_sni -i wiki.antroot.ru
        acl host_k8s hdr(host) req.ssl_sni -i k8s.antroot.ru
        use_backend https_pve if host_pve
        use_backend https_git if host_git
        use_backend https_wik if host_wik
        use_backend https_k8s if host_k8s

backend https_pve
        mode tcp
        option tcplog
        option ssl-hello-chk
        server pve pve.antroot.lan:443
backend https_git
        server git gitlab.antroot.lan:443
backend https_wik
        server wiki wiki.antroot.lan:443
backend https_k8s
        mode tcp
        balance source # source leastconn roundrobin
        server k8s1 k8s1.antroot.lan:443 check ssl verify none fall 3 rise 2
        server k8s2 k8s2.antroot.lan:443 check ssl verify none fall 3 rise 2