global
        pidfile                 /var/run/haproxy.pid
        #chroot                 /var/lib/haproxy
        user                    haproxy
        group                   haproxy

        # Makes the process fork into background
        daemon

        ## Logging stdout/stderr because we are in docker
        log                     stdout format raw local0 debug

        ## Tuning
        tune.bufsize            64768
        maxconn                 500000

        ## Enable Authelia Redirects
        ##lua-prepend-path        /etc/haproxy/?/http.lua
        ##lua-load                /etc/haproxy/haproxy-lua-http/auth-request.lua

        ## Stats
        stats socket /var/lib/haproxy/stats level admin mode 660 group haproxy expose-fd listeners
        stats timeout 30s

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


        tune.ssl.default-dh-param 4096
        #ssl-dh-param-file /path/to/dhparam

        ## SSL/TLS Cipher Suites
        ## See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
        #ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

        ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

#### DEFAULTS ####
defaults
        default-server              init-addr none
        log                         global
        mode                        http
        balance                     leastconn
        retries                     3
        timeout http-request        60s
        timeout queue               1m
        timeout connect             30s
        timeout client              1m
        timeout server              1m
        timeout http-keep-alive     30s
        timeout check               10s
        timeout client-fin          30s
        maxconn                     500000
        option                      http-keep-alive
        option                      forwardfor
        option                      http-server-close
        option                      dontlognull
        option                      httplog
        option                      redispatch
        option                      tcpka
        http-error status 503 content-type "text/html; charset=utf-8"    lf-file /etc/haproxy/errors/html/503.html

http-errors allerrors
        errorfile 404 /etc/haproxy/errors/tpl/404.http
        errorfile 400 /etc/haproxy/errors/tpl/400.http
        errorfile 403 /etc/haproxy/errors/tpl/403.http
        errorfile 408 /etc/haproxy/errors/tpl/408.http
        errorfile 502 /etc/haproxy/errors/tpl/502.http
        errorfile 504 /etc/haproxy/errors/tpl/504.http
#        errorfile 500 /etc/haproxy/errors/tpl/500.http
#        errorfile 503 /etc/haproxy/errors/tpl/503.http

#---------------------------------------------------------------------
##### FRONTENDs: WEB/HTTP/HTTPS
#---------------------------------------------------------------------
{# HAProxy frontends are configurations that define the IP addresses and ports clients can connect to #}
{# specifying how incoming requests should be forwarded to backends, and can include rules for routing traffic based on conditions or default actions #}

{# This frontend section listens on Port 444 (This can be overriden by modifying the Ansible Variables, refernce the default/main.yml) #}
{# This exposes a statistics page, with some controls to manage load balancing  #}
frontend  STATS
        mode http
{% if selfsigned_enabled %}
        bind :::{{ startcloud_haproxy_port_forwards[2].guest }} ssl crt {{ cert_dir }}/combined/{{ settings.hostname }}.{{ settings.domain }}.pem
{% else %}
        bind :::{{ startcloud_haproxy_port_forwards[2].guest }} ssl crt {{ cert_dir }}/combined/default-signed.pem
{% endif %}
        stats enable
        stats uri /
        stats admin if TRUE
        http-request use-service prometheus-exporter if { path /metrics }


{# This frontend section listens on Port 80 (This can be overriden by modifying the Ansible Variables, refernce the default/main.yml) #}
{# All This section does, is IF any URL hits the server, and if it contains the URI /.well-known/acme-challenge/,  #}
{# then send it to the Let's Encrypt Backend Defined in the backend section at the bottom. #}
{# If haproxy_ssl_redirect is set to false, which normally it is not and should not be, then It will not send a 301 request to the user to use HTTPS #}
{# Since there are no other Directives such as ACLs, use_backend, or nothing else is done with the request #}
{# If you want HAProxy to proxy the backends like it does port 443, then you can, but its not recommended, copy the configurations from the 443 backend, #}
{# And place them here with some slight modifications. Again this is not recommended, you should use SSL everywhere. #}
frontend EXT-WEB:{{ startcloud_haproxy_port_forwards[0].guest}}
        bind :::{{ startcloud_haproxy_port_forwards[0].guest}}
        mode http
        log global

        # Redirections to Let's Encrypt local agent
        acl ispath_letsencrypt                  path_beg /.well-known/acme-challenge/
{% if haproxy_ssl_redirect %}
        # Redirect HTTP -> HTTPS (except let's encrypt)
        redirect  code 301 scheme https if !{ ssl_fc }   !ispath_letsencrypt
{% endif %}
        use_backend     letsencrypt_80          if      ispath_letsencrypt


{# This frontend section listens on Port 443 (This can be overriden by modifying the Ansible Variables, refernce the default/main.yml) #}
{# This section, unlike the Port 80 section above, defines most of the advanced rules and configurations for how URLs are handled for the services, #}
{# running on this server.  #}
frontend  HTTPS-IN
{% if selfsigned_enabled %}
        bind :::{{ startcloud_haproxy_port_forwards[1].guest}} v4v6 ssl crt  {{ cert_dir }}/combined/{{ settings.hostname }}.{{ settings.domain }}.pem
{% else %}
        bind :::{{ startcloud_haproxy_port_forwards[1].guest}} v4v6 ssl crt  {{ cert_dir }}/combined/default-signed.pem
{% endif %}
        mode http
{% if haproxy_ssl_redirect %}
        http-request redirect scheme https unless { ssl_fc }
{% endif %}

        ## Dynamic Logging to Error Page
        errorfiles allerrors
        unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
        unique-id-header X-Unique-ID
        capture request header Host len 64

        log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %[unique-id]"

{# Due to Cors Preflight Requests, this needs to be disabled  #}
        #BEGIN CORS
        #http-response set-header Access-Control-Allow-Origin "*"
        #http-response set-header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, JSNLog-RequestId, activityId, applicationId, applicationUserId, channelId, senderId, sessionId"
        #http-response set-header Access-Control-Max-Age 3628800
        #http-response set-header Access-Control-Allow-Methods "*"
        # END CORS

        #### ACL's  ####
        ## Source ACL Definitions
        {#acl network_allowed           src                  10.0.2.0/16 192.168.0.0/16 172.16.0.0/16 #}
        ## Host ACL Definitions
        acl host_direct_ip            path_reg             -i ^.*\b(\d{1,3}\.){3}\d{1,3}\b.*$
{% if domino_nomadweb_use_proxy_url is defined %}
{% if domino_nomadweb_use_proxy_url and domino_nomadweb_proxy_url is defined %}
        acl host_main                 hdr(host)            -i {{ settings.hostname }}.{{ settings.domain }}
        acl host_agents_api           hdr(host)            -i api.{{ settings.hostname }}.{{ settings.domain }}
{% endif %}
{% endif %}
        acl host_console              hdr(host)            -i console.{{ settings.hostname }}.{{ settings.domain }}
        acl is_options                method               OPTIONS

{% if startcloud_web_terminal_proxy_url is defined %}
        acl host_web_terminal         hdr(host)            -i {{ startcloud_web_terminal_proxy_url }}
{% endif %}

{% if domino_vagrant_rest_api_proxy_url is defined %}
        acl host_restapi              hdr(host)            -i {{ domino_vagrant_rest_api_proxy_url }}
{% endif %}
{% if domino_nomadweb_use_proxy_url is defined %}
{% if domino_nomadweb_use_proxy_url and domino_nomadweb_proxy_url is defined %}
        acl host_nomadweb             hdr(host)            -i {{ domino_nomadweb_proxy_url }}
{% endif %}
{% if not domino_nomadweb_use_proxy_url %}
        acl host_nomadweb             hdr(host)            -i {{ settings.hostname }}.{{ settings.domain }}
{% endif %}
{% endif %}
{% if domino_install_proxy_url is defined %}
        acl host_domino               hdr(host)            -i {{ domino_install_proxy_url }}
{% endif %}
{% if domino_oidc_provider_enabled is defined and domino_oidc_provider_enabled and domino_oidc_install_proxy_url is defined %}
        acl host_domino_oidc          hdr(host)            -i {{ domino_oidc_install_proxy_url }}
{% endif %}
{% if startcloud_quick_start_proxy_url is defined %}
        acl host_downloads            hdr(host)            -i {{ startcloud_quick_start_proxy_url }}
{% endif %}
{% if domino_leap_proxy_url is defined %}
        acl host_leap                 hdr(host)            -i {{ domino_leap_proxy_url }}
{% endif %}
{% if domino_traveler_proxy_url is defined %}
        acl host_traveler             hdr(host)            -i {{ domino_traveler_proxy_url }}
{% endif %}
{% if domino_sametime_proxy_url is defined %}
        acl host_sametime             hdr(host)            -i {{ domino_sametime_proxy_url }}
{% endif %}
{% if startcloud_guacamole_proxy_url is defined %}
        acl host_guacamole            hdr(host)            -i {{ startcloud_guacamole_proxy_url }}
{% endif %}
{% if domino_verse_proxy_url is defined %}
        acl host_verse                hdr(host)            -i {{ domino_verse_proxy_url }}
{% endif %}
{% if voltmx_port_forwards[0].url is defined %}
        acl host_voltmx               hdr(host)            -i {{ settings.hostname }}.{{ settings.domain }}
{% endif %}

        ## Application backends
        use_backend                   console              if host_console
{% if domino_vagrant_rest_api_proxy_url is defined %}
        use_backend                   cors_backend         if host_restapi is_options
        use_backend                   restapi              if host_restapi
{% endif %}
{% if domino_nomadweb_proxy_url is defined %}
        use_backend                   cors_backend         if host_nomadweb is_options
        use_backend                   nomadweb             if host_nomadweb
{% endif %}
{% if domino_install_proxy_url is defined %}
{% if domino_nomadweb_use_proxy_url is defined %}
{% if domino_nomadweb_use_proxy_url and domino_nomadweb_proxy_url is defined %}
        use_backend                   domino               if host_domino || host_main || host_agents_api
{% elif not domino_nomadweb_use_proxy_url %}
        use_backend                   domino               if host_domino || host_agents_api
{% else %}
        use_backend                   domino               if host_domino || host_agents_api
{% endif %}
{% endif %}
{% endif %}
{% if domino_oidc_provider_enabled is defined and domino_oidc_provider_enabled %}
        use_backend                   domino_oidc          if host_domino_oidc
{% endif %}
{% if domino_leap_proxy_url is defined %}
        use_backend                   leap                 if host_leap
{% endif %}
{% if domino_traveler_proxy_url is defined %}
        use_backend                   traveler             if host_traveler
{% endif %}
{% if domino_sametime_proxy_url is defined %}
        use_backend                   sametime             if host_sametime
{% endif %}
{% if startcloud_guacamole_proxy_url is defined %}
        use_backend                   guacamole            if host_guacamole
{% endif %}
{% if domino_verse_proxy_url is defined %}
        use_backend                   verse                if host_verse
{% endif %}
{% if voltmx_port_forwards[0].url is defined %}
        use_backend                   voltmx               if host_voltmx
{% endif %}
{% if startcloud_web_terminal_proxy_url is defined %}
        use_backend                   web_terminal            if host_web_terminal
{% endif %}
{% if startcloud_quick_start_proxy_url is defined %}
        use_backend                   downloads            if host_downloads || host_direct_ip
{% endif %}
{% if haproxy_default_backend is defined and haproxy_default_backend | length > 0 %}
        default_backend               {{ haproxy_default_backend }}
{% endif %}

#---------------------------------------------------------------------
##### BACKENDS ####
#---------------------------------------------------------------------
{# Haproxy backends are sets of servers defined in the HAProxy configuration that receive forwarded requests,  #}
{# allowing for load balancing and increased reliability by distributing the load across multiple servers #}

## Let's Encrypt Cert-bot Tool
backend letsencrypt_80
        mode http
        log global
        http-response set-header Server haproxy
        server  letsencrypt             127.0.0.1:{{ haproxy_cert_bot_port }}

# CORS preflight requests
backend cors_backend
        http-after-response set-header Access-Control-Allow-Origin "*"
        http-after-response set-header Access-Control-Allow-Headers "*"
        http-after-response set-header Access-Control-Allow-Credentials "true"
        http-after-response set-header Access-Control-Allow-Methods "GET, DELETE, OPTIONS, POST, PUT, PATCH"
        http-after-response set-header Access-Control-Max-Age "31536000"
        http-request return status 200

# Console
backend console
        server  cockpit               127.0.0.1:9090    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none

{% if startcloud_web_terminal_port_forwards[0].guest is defined %}
backend web_terminal
        server  web_terminal          127.0.0.1:{{ startcloud_web_terminal_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}

{% if domino_vagrant_rest_api_port_forwards[0].guest is defined %}
# Rest API
backend restapi
        http-response set-header Access-Control-Allow-Origin "*"
        http-response set-header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
        http-response set-header Access-Control-Allow-Credentials "true"
        http-response set-header Access-Control-Allow-Methods "GET, DELETE, OPTIONS, POST, PUT, PATCH"
        server  restapi               127.0.0.1:{{ domino_vagrant_rest_api_port_forwards[0].guest }}    check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% if startcloud_quick_start_port_forwards[0].guest is defined %}
# Downloads
backend downloads
        server  downloads             127.0.0.1:{{ startcloud_quick_start_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% if domino_install_port_forwards[0].guest is defined and domino_install_proxy_url is defined %}
# Domino
backend domino
        server  domino-https          {{ domino_install_proxy_url }}:{{ domino_install_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_install_port_forwards[1].guest is defined %}
        server  domino-http           {{ domino_install_proxy_url }}:{{ domino_install_port_forwards[1].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}

{% if domino_install_port_forwards[0].guest is defined and domino_oidc_install_proxy_url is defined and domino_oidc_provider_enabled %}
# Domino OIDC
backend domino_oidc
        server  domino-oidc-https          {{ domino_oidc_install_proxy_url }}:{{ domino_install_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_install_port_forwards[1].guest is defined %}
        server  domino-oidc-http           {{ domino_oidc_install_proxy_url }}:{{ domino_install_port_forwards[1].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}

{% if domino_nomadweb_port_forwards[0].guest is defined %}
# Nomad Web
backend nomadweb
        server  nomadweb              {{ domino_nomadweb_proxy_url }}:{{ domino_nomadweb_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% if domino_traveler_port_forwards[0].guest is defined %}
# Traveler
backend traveler
        server  domino-https          {{ domino_traveler_proxy_url }}:{{ domino_traveler_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_traveler_port_forwards[1].guest is defined %}
        server  domino-http           {{ domino_traveler_proxy_url }}:{{ domino_traveler_port_forwards[1].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}
{% if domino_leap_port_forwards[0].guest is defined %}
# Leap
backend leap
        server  domino-https          {{ domino_leap_proxy_url }}:{{ domino_leap_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_leap_port_forwards[1].guest is defined %}
        server  domino-http           {{ domino_leap_proxy_url }}:{{ domino_leap_port_forwards[1].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}
{% if startcloud_guacamole_port_forwards[0].guest is defined %}
# Guacamole
backend guacamole
        server  guacamole             127.0.0.1:{{ startcloud_guacamole_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% if domino_verse_port_forwards[0].guest is defined %}
# Verse
backend verse
        server  domino-https          {{ domino_verse_proxy_url }}:{{ domino_verse_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_verse_port_forwards[1].guest is defined %}
        server  domino-http           {{ domino_verse_proxy_url }}:{{ domino_verse_port_forwards[1].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}
{% if domino_sametime_port_forwards[0].guest is defined %}
# Sametime
backend sametime
        server  domino-https          127.0.0.1:{{ domino_sametime_port_forwards[0].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
{% if domino_sametime_port_forwards[1].guest is defined %}
        server  domino-http           127.0.0.1:{{ domino_sametime_port_forwards[0].guest }}    backup check cookie {{ settings.hostname }} init-addr last,libc,none
{% endif %}
{% endif %}
{% if voltmx_port_forwards[0].guest is defined %}
# Voltmx
backend voltmx
        balance roundrobin
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request add-header X-Forwarded-Proto https
{% if voltmx_port_forwards[1].guest is defined %}
        server  voltmx-https          127.0.0.1:{{ voltmx_port_forwards[1].guest }}    ssl verify none sni ssl_fc_sni check cookie {{ settings.hostname }} init-addr last,libc,none
        server  voltmx-http           127.0.0.1:{{ voltmx_port_forwards[0].guest }}    backup check cookie voltmx init-addr last,libc,none
{% else %}
        server  voltmx-http           127.0.0.1:{{ voltmx_port_forwards[0].guest }}    check cookie voltmx init-addr last,libc,none
{% endif %}
{% endif %}