Setup HTTPs Forward Proxy with HAProxy

21,648

This is my Haproxy file configuration, it works well for HTTP and HTTPS protocol.

Here's the code :

#-----------------------------------------------------------------------------
# global
#-----------------------------------------------------------------------------

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

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    # An alternative list with additional directives can be obtained from
    #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

    # Tuning if required/needed
    # tune.ssl.default-dh-param 2048

#-----------------------------------------------------------------------------
# defaults
#-----------------------------------------------------------------------------

defaults
    log global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000
    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

#-----------------------------------------------------------------------------
# http frontend
#-----------------------------------------------------------------------------

frontend http-in
    bind *:80
    # Domain redirect, force the 'www' prefix
    redirect prefix https://www.domain1.net code 301 if { hdr_beg(host) -i domain1.net }
    redirect prefix https://www.domain2.net code 301 if { hdr_beg(host) -i domain2.net }
    # Define hosts
    acl is-domain1-site hdr(host) -i www.domain1.net
    acl is-domain1-blog hdr(host) -i blog.domain1.net
    acl is-domain1-wiki hdr(host) -i wiki.domain1.net
    acl is-domain2-site hdr(host) -i www.domain2.net
    acl is-domain2-blog hdr(host) -i blog.domain2.net
    acl is-domain2-wiki hdr(host) -i wiki.domain2.net
    # Force https for domain1
    redirect scheme https if is-domain1-site !{ ssl_fc }
    redirect scheme https if is-domain1-blog !{ ssl_fc }
    redirect scheme https if is-domain1-wiki !{ ssl_fc }
    # Force https for domain2
    redirect scheme https if is-domain2-site !{ ssl_fc }
    redirect scheme https if is-domain2-blog !{ ssl_fc }
    redirect scheme https if is-domain2-wiki !{ ssl_fc }
    # Default backend (parking)
    default_backend bk-ct100

#-----------------------------------------------------------------------------
# https frontend
#-----------------------------------------------------------------------------

frontend https-in
    bind *:443 ssl crt /etc/ssl/private/
    # Domain redirect force www
    redirect prefix https://www.domain1.net code 301 if { hdr_beg(host) -i domain1.net }
    redirect prefix https://www.domain2.net code 301 if { hdr_beg(host) -i domain2.net }
    # Define hosts for domain1
    acl is-domain1-site hdr(host) -i www.domain1.net
    acl is-domain1-blog hdr(host) -i blog.domain1.net
    acl is-domain1-wiki hdr(host) -i wiki.domain1.net
    # Define hosts for domain2
    acl is-domain2-site hdr(host) -i www.domain2.net
    acl is-domain2-blog hdr(host) -i blog.domain2.net
    acl is-domain2-wiki hdr(host) -i wiki.domain2.net
    # Figure out which backend to use for domain1
    use_backend bk-ct101 if is-domain1-site
    use_backend bk-ct101 if is-domain1-blog
    use_backend bk-ct101 if is-domain1-wiki
    # Figure out which backend to use for domain2
    use_backend bk-ct102 if is-domain2-site
    use_backend bk-ct102 if is-domain2-blog
    use_backend bk-ct102 if is-domain2-wiki
    # Default backend (parking)
    default_backend bk-ct100

#-----------------------------------------------------------------------------
# ct100 backend - parking
#-----------------------------------------------------------------------------

backend bk-ct100
    mode   http
    option forwardfor
    server ct100 192.168.100.100:80 check

#-----------------------------------------------------------------------------
# ct101 backend - domain1
#-----------------------------------------------------------------------------

backend bk-ct101
    mode   http
    option forwardfor
    server ct101 192.168.100.101:80 check

#-----------------------------------------------------------------------------
# ct102 backend - domain2
#-----------------------------------------------------------------------------

backend bk-ct102
    mode   http
    option forwardfor
    server ct102 192.168.100.102:80 check

#-----------------------------------------------------------------------------
# End-Of-File
#-----------------------------------------------------------------------------

In this configuration, I chose to redirect all traffic from HTTP to HTTPS. All of my certificates are stored inside /etc/ssl/private directory. I generated them using CertBot.

You can adapt this file for your needs but it should work :)

Share:
21,648
binaryuser
Author by

binaryuser

Updated on October 27, 2021

Comments

  • binaryuser
    binaryuser over 2 years

    In HAProxy, I've used option http-proxy to make it work like forward proxy. This seems to be working fine, but for HTTPS traffic that's not possible.

    So, is there any option in the HAProxy configuration that allows to proxy the HTTPS traffic just like Squid does ?

    I think the problem is that the option https_proxy isn't available.

    This configuration works perfectly for HTTP protocol:

    frontend http_proxy
       bind :3128
       option http_proxy
       default_backend proxy_server
    
    backend proxy_server
       option http_proxy
    

    Note - I've used the certificate with "ssl crt" along with the bind option but that didn't seem to proxy over HTTPS protocol