From 66c20993a978f2c7b7fc990dd2bc8bf2ca1a8051 Mon Sep 17 00:00:00 2001 From: ibizaman Date: Tue, 13 Sep 2022 23:47:49 -0700 Subject: [PATCH] add haproxy with ssl termination --- all-packages.nix | 4 ++ caddy/mksiteconfig.nix | 5 ++- haproxy/config.nix | 93 ++++++++++++++++++++++++++++++++++++++++++ haproxy/siteconfig.nix | 20 +++++++++ haproxy/unit.nix | 75 ++++++++++++++++++++++++++++++++++ 5 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 haproxy/config.nix create mode 100644 haproxy/siteconfig.nix create mode 100644 haproxy/unit.nix diff --git a/all-packages.nix b/all-packages.nix index 4a87f88..790270e 100644 --- a/all-packages.nix +++ b/all-packages.nix @@ -11,6 +11,10 @@ let self = rec { PostgresDB = callPackage ./postgresdb {}; + HaproxyConfig = callPackage ./haproxy/config.nix {inherit utils;}; + HaproxyService = callPackage ./haproxy/unit.nix {inherit utils;}; + mkHaproxySiteConfig = callPackage ./haproxy/siteconfig.nix {}; + CaddyConfig = callPackage ./caddy/config.nix {inherit utils;}; CaddyService = callPackage ./caddy/unit.nix {inherit utils;}; CaddySiteConfig = callPackage ./caddy/siteconfig.nix {inherit utils;}; diff --git a/caddy/mksiteconfig.nix b/caddy/mksiteconfig.nix index 00cf146..fa37cf5 100644 --- a/caddy/mksiteconfig.nix +++ b/caddy/mksiteconfig.nix @@ -8,14 +8,15 @@ , siteRoot , siteSocket ? "" }: -{ +rec { inherit name; + caddySocket = "${CaddyService.runtimeDirectory}/${siteName}.sock"; pkg = CaddySiteConfig rec { inherit (CaddyConfig) siteConfigDir; portBinding = port; bindService = siteName; - siteSocket = "${CaddyService.runtimeDirectory}/${siteName}.sock"; + siteSocket = caddySocket; serviceRoot = siteRoot; phpFpmSiteSocket = siteSocket; }; diff --git a/haproxy/config.nix b/haproxy/config.nix new file mode 100644 index 0000000..878b079 --- /dev/null +++ b/haproxy/config.nix @@ -0,0 +1,93 @@ +{ 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} + ''; +} diff --git a/haproxy/siteconfig.nix b/haproxy/siteconfig.nix new file mode 100644 index 0000000..3d82c05 --- /dev/null +++ b/haproxy/siteconfig.nix @@ -0,0 +1,20 @@ +{ stdenv +, pkgs +}: +{ serviceName +, serviceSocket +}: + +{ + acl = '' + acl acl_${serviceName} hdr_beg(host) ${serviceName}. + use_backend ${serviceName} if acl_${serviceName} + ''; + + backend = '' + backend ${serviceName} + mode http + option forwardfor + server ${serviceName}1 ${serviceSocket} + ''; +} diff --git a/haproxy/unit.nix b/haproxy/unit.nix new file mode 100644 index 0000000..577d7e6 --- /dev/null +++ b/haproxy/unit.nix @@ -0,0 +1,75 @@ +{ stdenv +, pkgs +, utils +}: +{ configDir ? "/etc/haproxy" +, configFile ? "haproxy.cfg" +, pidfile ? "/run/haproxy/haproxy.pid" +, socket ? "/run/haproxy/haproxy.sock" +}: +{...}: + +# User and group are set in config.nix + +utils.systemd.mkService rec { + name = "haproxy"; + + content = '' + [Unit] + Description=HAProxy Load Balancer + Documentation=https://www.haproxy.com/documentation/hapee/latest/onepage/ + After=network.target network-online.target + Wants=network-online.target systemd-networkd-wait-online.target + + StartLimitInterval=14400 + StartLimitBurst=10 + + [Service] + Environment="CONFIG=${configDir}/${configFile}" "PIDFILE=${pidfile}" "EXTRAOPTS=-S ${socket}" + ExecStart=${pkgs.haproxy}/bin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS + ExecReload=${pkgs.haproxy}/bin/haproxy -Ws -f $CONFIG -c -q $EXTRAOPTS + ExecReload=${pkgs.coreutils}/bin/kill -USR2 $MAINPID + KillMode=mixed + Restart=always + SuccessExitStatus=143 + Type=notify + + + # Restart=on-abnormal + RuntimeDirectory=haproxy + + # KillMode=mixed + # KillSignal=SIGQUIT + TimeoutStopSec=5s + + LimitNOFILE=1048576 + LimitNPROC=512 + + PrivateDevices=true + LockPersonality=true + NoNewPrivileges=true + PrivateDevices=true + PrivateTmp=true + ProtectClock=true + ProtectControlGroups=true + ProtectHome=true + ProtectHostname=true + ProtectKernelLogs=true + ProtectKernelModules=true + ProtectKernelTunables=true + ProtectSystem=full + RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX + RestrictNamespaces=true + RestrictRealtime=true + RestrictSUIDSGID=true + + # CapabilityBoundingSet=CAP_NET_BIND_SERVICE + # AmbientCapabilities=CAP_NET_BIND_SERVICE + + # ProtectSystem=strict + # ReadWritePaths=/var/lib/haproxy /var/log/haproxy + + [Install] + WantedBy=multi-user.target + ''; +}