nixos/haproxy: add reloading support, use upstream service hardening
Refactor the systemd service definition for the haproxy reverse proxy, using the upstream systemd service definition. This allows the service to be reloaded on changes, preserving existing server state, and adds some hardening options.
This commit is contained in:
parent
fbdbe12f50
commit
c784d3ab76
|
@ -56,6 +56,9 @@ with lib;
|
|||
message = "You must provide services.haproxy.config.";
|
||||
}];
|
||||
|
||||
# configuration file indirection is needed to support reloading
|
||||
environment.etc."haproxy.cfg".source = haproxyCfg;
|
||||
|
||||
systemd.services.haproxy = {
|
||||
description = "HAProxy";
|
||||
after = [ "network.target" ];
|
||||
|
@ -64,11 +67,32 @@ with lib;
|
|||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Type = "notify";
|
||||
# when running the config test, don't be quiet so we can see what goes wrong
|
||||
ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}";
|
||||
ExecStart = "${pkgs.haproxy}/sbin/haproxy -Ws -f ${haproxyCfg}";
|
||||
Restart = "on-failure";
|
||||
ExecStartPre = [
|
||||
# when the master process receives USR2, it reloads itself using exec(argv[0]),
|
||||
# so we create a symlink there and update it before reloading
|
||||
"${pkgs.coreutils}/bin/ln -sf ${pkgs.haproxy}/sbin/haproxy /run/haproxy/haproxy"
|
||||
# when running the config test, don't be quiet so we can see what goes wrong
|
||||
"/run/haproxy/haproxy -c -f ${haproxyCfg}"
|
||||
];
|
||||
ExecStart = "/run/haproxy/haproxy -Ws -f /etc/haproxy.cfg -p /run/haproxy/haproxy.pid";
|
||||
# support reloading
|
||||
ExecReload = [
|
||||
"${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}"
|
||||
"${pkgs.coreutils}/bin/ln -sf ${pkgs.haproxy}/sbin/haproxy /run/haproxy/haproxy"
|
||||
"${pkgs.coreutils}/bin/kill -USR2 $MAINPID"
|
||||
];
|
||||
KillMode = "mixed";
|
||||
SuccessExitStatus = "143";
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "haproxy";
|
||||
# upstream hardening options
|
||||
NoNewPrivileges = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync";
|
||||
# needed in case we bind to port < 1024
|
||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
};
|
||||
|
|
|
@ -43,5 +43,13 @@ import ./make-test-python.nix ({ pkgs, ...}: {
|
|||
assert "haproxy_process_pool_allocated_bytes" in machine.succeed(
|
||||
"curl -k http://localhost:80/metrics"
|
||||
)
|
||||
|
||||
with subtest("reload"):
|
||||
machine.succeed("systemctl reload haproxy")
|
||||
# wait some time to ensure the following request hits the reloaded haproxy
|
||||
machine.sleep(5)
|
||||
assert "We are all good!" in machine.succeed(
|
||||
"curl -k http://localhost:80/index.txt"
|
||||
)
|
||||
'';
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue