vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / haproxy.nix
blob23c06f2949808d0a2aa15ed65882c440911d0b33
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.haproxy;
4   haproxyCfg = pkgs.writeText "haproxy.conf" ''
5     global
6       # needed for hot-reload to work without dropping packets in multi-worker mode
7       stats socket /run/haproxy/haproxy.sock mode 600 expose-fd listeners level user
8     ${cfg.config}
9   '';
12   options = {
13     services.haproxy = {
15       enable = lib.mkEnableOption "HAProxy, the reliable, high performance TCP/HTTP load balancer";
17       package = lib.mkPackageOption pkgs "haproxy" { };
19       user = lib.mkOption {
20         type = lib.types.str;
21         default = "haproxy";
22         description = "User account under which haproxy runs.";
23       };
25       group = lib.mkOption {
26         type = lib.types.str;
27         default = "haproxy";
28         description = "Group account under which haproxy runs.";
29       };
31       config = lib.mkOption {
32         type = lib.types.nullOr lib.types.lines;
33         default = null;
34         description = ''
35           Contents of the HAProxy configuration file,
36           {file}`haproxy.conf`.
37         '';
38       };
39     };
40   };
42   config = lib.mkIf cfg.enable {
44     assertions = [{
45       assertion = cfg.config != null;
46       message = "You must provide services.haproxy.config.";
47     }];
49     # configuration file indirection is needed to support reloading
50     environment.etc."haproxy.cfg".source = haproxyCfg;
52     systemd.services.haproxy = {
53       description = "HAProxy";
54       after = [ "network.target" ];
55       wantedBy = [ "multi-user.target" ];
56       serviceConfig = {
57         User = cfg.user;
58         Group = cfg.group;
59         Type = "notify";
60         ExecStartPre = [
61           # when the master process receives USR2, it reloads itself using exec(argv[0]),
62           # so we create a symlink there and update it before reloading
63           "${pkgs.coreutils}/bin/ln -sf ${lib.getExe cfg.package} /run/haproxy/haproxy"
64           # when running the config test, don't be quiet so we can see what goes wrong
65           "/run/haproxy/haproxy -c -f ${haproxyCfg}"
66         ];
67         ExecStart = "/run/haproxy/haproxy -Ws -f /etc/haproxy.cfg -p /run/haproxy/haproxy.pid";
68         # support reloading
69         ExecReload = [
70           "${lib.getExe cfg.package} -c -f ${haproxyCfg}"
71           "${pkgs.coreutils}/bin/ln -sf ${lib.getExe cfg.package} /run/haproxy/haproxy"
72           "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"
73         ];
74         KillMode = "mixed";
75         SuccessExitStatus = "143";
76         Restart = "always";
77         RuntimeDirectory = "haproxy";
78         # upstream hardening options
79         NoNewPrivileges = true;
80         ProtectHome = true;
81         ProtectSystem = "strict";
82         ProtectKernelTunables = true;
83         ProtectKernelModules = true;
84         ProtectControlGroups = true;
85         SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync";
86         # needed in case we bind to port < 1024
87         AmbientCapabilities = "CAP_NET_BIND_SERVICE";
88       };
89     };
91     users.users = lib.optionalAttrs (cfg.user == "haproxy") {
92       haproxy = {
93         group = cfg.group;
94         isSystemUser = true;
95       };
96     };
98     users.groups = lib.optionalAttrs (cfg.group == "haproxy") {
99       haproxy = {};
100     };
101   };