{ stdenv , pkgs , lib , utils }: { configDir ? "/etc/haproxy" , configFile ? "haproxy.cfg" , acls ? [] , backends ? [] , certPath , user ? "haproxy" , group ? "haproxy" , statsEnable ? false , statsPort ? 8404 , statsUri ? "/stats" , statsRefresh ? "10s" , prometheusStatsUri ? null }: let stats = if statsEnable then "" else '' frontend stats bind localhost:${builtins.toString statsPort} mode http stats enable # stats hide-version stats uri ${statsUri} stats refresh ${statsRefresh} '' + (if prometheusStatsUri == null then "" else '' http-request use-service prometheus-exporter if { path ${prometheusStatsUri} } ''); indent = spaces: content: lib.strings.concatMapStrings (x: spaces + x + "\n") (lib.strings.splitString "\n" content); acls_str = lib.strings.concatMapStrings (acl: indent " " acl) acls; backends_str = builtins.concatStringsSep "\n" backends; in utils.mkConfigFile { name = configFile; dir = configDir; content = '' global # Load the plugin handling Let's Encrypt request # lua-load /etc/haproxy/plugins/haproxy-acme-validation-plugin-0.1.1/acme-http01-webroot.lua # Silence a warning issued by haproxy. Using 2048 # instead of the default 1024 makes the connection stronger. tune.ssl.default-dh-param 2048 maxconn 20000 user ${user} group ${group} log /dev/log local0 info defaults log global option httplog timeout connect 10s timeout client 15s timeout server 30s timeout queue 100s frontend http-to-https mode http bind *:80 redirect scheme https code 301 if !{ ssl_fc } ${stats} frontend https mode http bind *:443 ssl crt ${certPath} http-request set-header X-Forwarded-Port %[dst_port] http-request set-header X-Forwarded-For %[src] http-request add-header X-Forwarded-Proto https http-response set-header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload;" ${acls_str} ${backends_str} ''; }