vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / nats.nix
blob4851daae4dbabc42345143dd42687f23ead2cc5f
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.services.nats;
9   format = pkgs.formats.json { };
11   configFile = format.generate "nats.conf" cfg.settings;
13   validateConfig = file:
14   pkgs.runCommand "validate-nats-conf" {
15     nativeBuildInputs = [ pkgs.nats-server ];
16   } ''
17     nats-server --config "${configFile}" -t
18     ln -s "${configFile}" "$out"
19   '';
20 in {
22   ### Interface
24   options = {
25     services.nats = {
26       enable = mkEnableOption "NATS messaging system";
28       user = mkOption {
29         type = types.str;
30         default = "nats";
31         description = "User account under which NATS runs.";
32       };
34       group = mkOption {
35         type = types.str;
36         default = "nats";
37         description = "Group under which NATS runs.";
38       };
40       serverName = mkOption {
41         default = "nats";
42         example = "n1-c3";
43         type = types.str;
44         description = ''
45           Name of the NATS server, must be unique if clustered.
46         '';
47       };
49       jetstream = mkEnableOption "JetStream";
51       port = mkOption {
52         default = 4222;
53         type = types.port;
54         description = ''
55           Port on which to listen.
56         '';
57       };
59       dataDir = mkOption {
60         default = "/var/lib/nats";
61         type = types.path;
62         description = ''
63           The NATS data directory. Only used if JetStream is enabled, for
64           storing stream metadata and messages.
66           If left as the default value this directory will automatically be
67           created before the NATS server starts, otherwise the sysadmin is
68           responsible for ensuring the directory exists with appropriate
69           ownership and permissions.
70         '';
71       };
73       settings = mkOption {
74         default = { };
75         type = format.type;
76         example = literalExpression ''
77           {
78             jetstream = {
79               max_mem = "1G";
80               max_file = "10G";
81             };
82           };
83         '';
84         description = ''
85           Declarative NATS configuration. See the
86           [
87           NATS documentation](https://docs.nats.io/nats-server/configuration) for a list of options.
88         '';
89       };
90     };
91   };
93   ### Implementation
95   config = mkIf cfg.enable {
96     services.nats.settings = {
97       server_name = cfg.serverName;
98       port = cfg.port;
99       jetstream = optionalAttrs cfg.jetstream { store_dir = cfg.dataDir; };
100     };
102     systemd.services.nats = {
103       description = "NATS messaging system";
104       wantedBy = [ "multi-user.target" ];
105       after = [ "network.target" ];
107       serviceConfig = mkMerge [
108         (mkIf (cfg.dataDir == "/var/lib/nats") {
109           StateDirectory = "nats";
110           StateDirectoryMode = "0750";
111         })
112         {
113           Type = "simple";
114           ExecStart = "${pkgs.nats-server}/bin/nats-server -c ${validateConfig configFile}";
115           ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
116           ExecStop = "${pkgs.coreutils}/bin/kill -SIGINT $MAINPID";
117           Restart = "on-failure";
119           User = cfg.user;
120           Group = cfg.group;
122           # Hardening
123           CapabilityBoundingSet = "";
124           LimitNOFILE = 800000; # JetStream requires 2 FDs open per stream.
125           LockPersonality = true;
126           MemoryDenyWriteExecute = true;
127           NoNewPrivileges = true;
128           PrivateDevices = true;
129           PrivateTmp = true;
130           PrivateUsers = true;
131           ProcSubset = "pid";
132           ProtectClock = true;
133           ProtectControlGroups = true;
134           ProtectHome = true;
135           ProtectHostname = true;
136           ProtectKernelLogs = true;
137           ProtectKernelModules = true;
138           ProtectKernelTunables = true;
139           ProtectProc = "invisible";
140           ProtectSystem = "strict";
141           ReadOnlyPaths = [ ];
142           ReadWritePaths = [ cfg.dataDir ];
143           RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
144           RestrictNamespaces = true;
145           RestrictRealtime = true;
146           RestrictSUIDSGID = true;
147           SystemCallFilter = [ "@system-service" "~@privileged" ];
148           UMask = "0077";
149         }
150       ];
151     };
153     users.users = mkIf (cfg.user == "nats") {
154       nats = {
155         description = "NATS daemon user";
156         isSystemUser = true;
157         group = cfg.group;
158         home = cfg.dataDir;
159       };
160     };
162     users.groups = mkIf (cfg.group == "nats") { nats = { }; };
163   };