vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / suricata / settings.nix
blobf96d78ca66d53e648a4bf0b6d7d577ba9471b4b8
2   lib,
3   config,
4   yaml,
5   ...
6 }:
7 let
8   cfg = config.services.suricata;
9   inherit (lib)
10     mkEnableOption
11     mkOption
12     types
13     literalExpression
14     ;
15   mkDisableOption =
16     name:
17     mkEnableOption name
18     // {
19       default = true;
20       example = false;
21     };
24   freeformType = yaml.type;
25   options = {
26     vars = mkOption {
27       type = types.nullOr (
28         types.submodule {
29           options = {
30             address-groups = mkOption {
31               type = (
32                 types.submodule {
33                   options = {
34                     HOME_NET = mkOption { default = "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"; };
35                     EXTERNAL_NET = mkOption { default = "!$HOME_NET"; };
36                     HTTP_SERVERS = mkOption { default = "$HOME_NET"; };
37                     SMTP_SERVERS = mkOption { default = "$HOME_NET"; };
38                     SQL_SERVERS = mkOption { default = "$HOME_NET"; };
39                     DNS_SERVERS = mkOption { default = "$HOME_NET"; };
40                     TELNET_SERVERS = mkOption { default = "$HOME_NET"; };
41                     AIM_SERVERS = mkOption { default = "$EXTERNAL_NET"; };
42                     DC_SERVERS = mkOption { default = "$HOME_NET"; };
43                     DNP3_SERVER = mkOption { default = "$HOME_NET"; };
44                     DNP3_CLIENT = mkOption { default = "$HOME_NET"; };
45                     MODBUS_CLIENT = mkOption { default = "$HOME_NET"; };
46                     MODBUS_SERVER = mkOption { default = "$HOME_NET"; };
47                     ENIP_CLIENT = mkOption { default = "$HOME_NET"; };
48                     ENIP_SERVER = mkOption { default = "$HOME_NET"; };
49                   };
50                 }
51               );
52               default = { };
53               example = {
54                 HOME_NET = "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]";
55                 EXTERNAL_NET = "!$HOME_NET";
56                 HTTP_SERVERS = "$HOME_NET";
57                 SMTP_SERVERS = "$HOME_NET";
58                 SQL_SERVERS = "$HOME_NET";
59                 DNS_SERVERS = "$HOME_NET";
60                 TELNET_SERVERS = "$HOME_NET";
61                 AIM_SERVERS = "$EXTERNAL_NET";
62                 DC_SERVERS = "$HOME_NET";
63                 DNP3_SERVER = "$HOME_NET";
64                 DNP3_CLIENT = "$HOME_NET";
65                 MODBUS_CLIENT = "$HOME_NET";
66                 MODBUS_SERVER = "$HOME_NET";
67                 ENIP_CLIENT = "$HOME_NET";
68                 ENIP_SERVER = "$HOME_NET";
69               };
70               description = ''
71                 The address group variables for suricata, if not defined the
72                 default value of suricata (see example) will be used.
73                 Your settings will extend the predefined values in example.
74               '';
75             };
77             port-groups = mkOption {
78               type = with types; nullOr (attrsOf str);
79               default = {
80                 HTTP_PORTS = "80";
81                 SHELLCODE_PORTS = "!80";
82                 ORACLE_PORTS = "1521";
83                 SSH_PORTS = "22";
84                 DNP3_PORTS = "20000";
85                 MODBUS_PORTS = "502";
86                 FILE_DATA_PORTS = "[$HTTP_PORTS,110,143]";
87                 FTP_PORTS = "21";
88                 GENEVE_PORTS = "6081";
89                 VXLAN_PORTS = "4789";
90                 TEREDO_PORTS = "3544";
91               };
92               description = ''
93                 The port group variables for suricata.
94               '';
95             };
96           };
97         }
98       );
99       default = { }; # add default values to config
100     };
102     stats = mkOption {
103       type =
104         with types;
105         nullOr (submodule {
106           options = {
107             enable = mkEnableOption "suricata global stats";
109             interval = mkOption {
110               type = types.str;
111               default = "8";
112               description = ''
113                 The interval field (in seconds) controls the interval at
114                 which stats are updated in the log.
115               '';
116             };
118             decoder-events = mkOption {
119               type = types.bool;
120               default = true;
121               description = ''
122                 Add decode events to stats
123               '';
124             };
126             decoder-events-prefix = mkOption {
127               type = types.str;
128               default = "decoder.event";
129               description = ''
130                 Decoder event prefix in stats. Has been 'decoder' before, but that leads
131                 to missing events in the eve.stats records.
132               '';
133             };
135             stream-events = mkOption {
136               type = types.bool;
137               default = false;
138               description = ''
139                 Add stream events as stats.
140               '';
141             };
142           };
143         });
144       default = null; # do not add to config unless specified
145     };
147     plugins = mkOption {
148       type = with types; nullOr (listOf path);
149       default = null;
150       description = ''
151         Plugins -- Experimental -- specify the filename for each plugin shared object
152       '';
153     };
155     outputs = mkOption {
156       type =
157         with types;
158         nullOr (
159           listOf (
160             attrsOf (submodule {
161               freeformType = yaml.type;
162               options = {
163                 enabled = mkEnableOption "<NAME>";
164               };
165             })
166           )
167         );
168       default = null;
169       example = literalExpression ''
170         [
171           {
172             fast = {
173               enabled = "yes";
174               filename = "fast.log";
175               append = "yes";
176             };
177           }
178           {
179             eve-log = {
180               enabled = "yes";
181               filetype = "regular";
182               filename = "eve.json";
183               community-id = true;
184               types = [
185                 {
186                   alert.tagged-packets = "yes";
187                 }
188               ];
189             };
190           }
191         ];
192       '';
193       description = ''
194         Configure the type of alert (and other) logging you would like.
196         Valid values for <NAME> are e. g. `fast`, `eve-log`, `syslog`, `file-store`, ...
197         - `fast`: a line based alerts log similar to Snort's fast.log
198         - `eve-log`: Extensible Event Format (nicknamed EVE) event log in JSON format
200         For more details regarding the configuration, checkout the shipped suricata.yaml
201         ```shell
202         nix-shell -p suricata yq coreutils-full --command 'yq < $(dirname $(which suricata))/../etc/suricata/suricata.yaml'
203         ```
204         and the [suricata documentation](https://docs.suricata.io/en/latest/output/index.html).
205       '';
206     };
208     "default-log-dir" = mkOption {
209       type = types.str;
210       default = "/var/log/suricata";
211       description = ''
212         The default logging directory. Any log or output file will be placed here if it's
213         not specified with a full path name. This can be overridden with the -l command
214         line parameter.
215       '';
216     };
218     logging = {
219       "default-log-level" = mkOption {
220         type = types.enum [
221           "error"
222           "warning"
223           "notice"
224           "info"
225           "perf"
226           "config"
227           "debug"
228         ];
229         default = "notice";
230         description = ''
231           The default log level: can be overridden in an output section.
232           Note that debug level logging will only be emitted if Suricata was
233           compiled with the --enable-debug configure option.
234         '';
235       };
237       "default-log-format" = mkOption {
238         type = types.nullOr types.str;
239         default = null;
240         description = ''
241           The default output format. Optional parameter, should default to
242           something reasonable if not provided. Can be overridden in an
243           output section.  You can leave this out to get the default.
244         '';
245       };
247       "default-output-filter" = mkOption {
248         type = types.nullOr types.str;
249         default = null;
250         description = ''
251           A regex to filter output.  Can be overridden in an output section.
252           Defaults to empty (no filter).
253         '';
254       };
256       "stacktrace-on-signal" = mkOption {
257         type = types.nullOr types.str;
258         default = null;
259         description = ''
260           Requires libunwind to be available when Suricata is configured and built.
261           If a signal unexpectedly terminates Suricata, displays a brief diagnostic
262           message with the offending stacktrace if enabled.
263         '';
264       };
266       outputs = {
267         console = {
268           enable = mkDisableOption "logging to console";
269         };
270         file = {
271           enable = mkDisableOption "logging to file";
273           level = mkOption {
274             type = types.enum [
275               "error"
276               "warning"
277               "notice"
278               "info"
279               "perf"
280               "config"
281               "debug"
282             ];
283             default = "info";
284             description = ''
285               Loglevel for logs written to the logfile
286             '';
287           };
289           filename = mkOption {
290             type = types.str;
291             default = "suricata.log";
292             description = ''
293               Filename of the logfile
294             '';
295           };
297           format = mkOption {
298             type = types.nullOr types.str;
299             default = null;
300             description = ''
301               Logformat for logs written to the logfile
302             '';
303           };
305           type = mkOption {
306             type = types.nullOr types.str;
307             default = null;
308             description = ''
309               Type of logfile
310             '';
311           };
312         };
313         syslog = {
314           enable = mkEnableOption "logging to syslog";
316           facility = mkOption {
317             type = types.str;
318             default = "local5";
319             description = ''
320               Facility to log to
321             '';
322           };
324           format = mkOption {
325             type = types.nullOr types.str;
326             default = null;
327             description = ''
328               Logformat for logs send to syslog
329             '';
330           };
332           type = mkOption {
333             type = types.nullOr types.str;
334             default = null;
335             description = ''
336               Type of logs send to syslog
337             '';
338           };
339         };
340       };
341     };
343     "af-packet" = mkOption {
344       type =
345         with types;
346         nullOr (
347           listOf (submodule {
348             freeformType = yaml.type;
349             options = {
350               interface = mkOption {
351                 type = types.str;
352                 default = null;
353               };
354             };
355           })
356         );
357       default = null;
358       description = ''
359         Linux high speed capture support
360       '';
361     };
363     "af-xdp" = mkOption {
364       type =
365         with types;
366         nullOr (
367           listOf (submodule {
368             freeformType = yaml.type;
369             options = {
370               interface = mkOption {
371                 type = types.str;
372                 default = null;
373               };
374             };
375           })
376         );
377       default = null;
378       description = ''
379         Linux high speed af-xdp capture support, see
380         [docs/capture-hardware/af-xdp](https://docs.suricata.io/en/suricata-7.0.3/capture-hardware/af-xdp.html)
381       '';
382     };
384     "dpdk" = mkOption {
385       type =
386         with types;
387         nullOr (submodule {
388           options = {
389             eal-params.proc-type = mkOption {
390               type = with types; nullOr str;
391               default = null;
392             };
393             interfaces = mkOption {
394               type =
395                 with types;
396                 nullOr (
397                   listOf (submodule {
398                     freeformType = yaml.type;
399                     options = {
400                       interface = mkOption {
401                         type = types.str;
402                         default = null;
403                       };
404                     };
405                   })
406                 );
407               default = null;
408             };
409           };
410         });
411       default = null;
412       description = ''
413         DPDK capture support, see
414         [docs/capture-hardware/dpdk](https://docs.suricata.io/en/suricata-7.0.3/capture-hardware/dpdk.html)
415       '';
416     };
418     "pcap" = mkOption {
419       type =
420         with types;
421         nullOr (
422           listOf (submodule {
423             freeformType = yaml.type;
424             options = {
425               interface = mkOption {
426                 type = types.str;
427                 default = null;
428               };
429             };
430           })
431         );
432       default = null;
433       description = ''
434         Cross platform libpcap capture support
435       '';
436     };
438     "pcap-file".checksum-checks = mkOption {
439       type = types.enum [
440         "yes"
441         "no"
442         "auto"
443       ];
444       default = "auto";
445       description = ''
446         Possible values are:
447         - yes: checksum validation is forced
448         - no: checksum validation is disabled
449         - auto: Suricata uses a statistical approach to detect when
450         checksum off-loading is used. (default)
451         Warning: 'checksum-validation' must be set to yes to have checksum tested
452       '';
453     };
455     "app-layer" = mkOption {
456       type =
457         with types;
458         nullOr (submodule {
459           options = {
460             "error-policy" = mkOption {
461               type = types.enum [
462                 "drop-flow"
463                 "pass-flow"
464                 "bypass"
465                 "drop-packet"
466                 "pass-packet"
467                 "reject"
468                 "ignore"
469               ];
470               default = "ignore";
471               description = ''
472                 The error-policy setting applies to all app-layer parsers. Values can be
473                 "drop-flow", "pass-flow", "bypass", "drop-packet", "pass-packet", "reject" or
474                 "ignore" (the default).
475               '';
476             };
477             protocols = mkOption {
478               type =
479                 with types;
480                 nullOr (
481                   attrsOf (submodule {
482                     freeformType = yaml.type;
483                     options = {
484                       enabled = mkOption {
485                         type = types.enum [
486                           "yes"
487                           "no"
488                           "detection-only"
489                         ];
490                         default = "no";
491                         description = ''
492                           The option "enabled" takes 3 values - "yes", "no", "detection-only".
493                           "yes" enables both detection and the parser, "no" disables both, and
494                           "detection-only" enables protocol detection only (parser disabled).
495                         '';
496                       };
497                     };
498                   })
499                 );
500               default = null;
501             };
502           };
503         });
504       default = null; # do not add to config unless specified
505     };
507     "run-as" = {
508       user = mkOption {
509         type = types.str;
510         default = "suricata";
511         description = "Run Suricata with a specific user-id";
512       };
513       group = mkOption {
514         type = types.str;
515         default = "suricata";
516         description = "Run Suricata with a specific group-id";
517       };
518     };
520     "host-mode" = mkOption {
521       type = types.enum [
522         "router"
523         "sniffer-only"
524         "auto"
525       ];
526       default = "auto";
527       description = ''
528         If the Suricata box is a router for the sniffed networks, set it to 'router'. If
529         it is a pure sniffing setup, set it to 'sniffer-only'. If set to auto, the variable
530         is internally switched to 'router' in IPS mode and 'sniffer-only' in IDS mode.
531         This feature is currently only used by the reject* keywords.
532       '';
533     };
535     "unix-command" = mkOption {
536       type =
537         with types;
538         nullOr (submodule {
539           options = {
540             enabled = mkOption {
541               type = types.either types.bool (types.enum [ "auto" ]);
542               default = "auto";
543             };
544             filename = mkOption {
545               type = types.path;
546               default = "/run/suricata/suricata-command.socket";
547             };
548           };
549         });
550       default = { };
551       description = ''
552         Unix command socket that can be used to pass commands to Suricata.
553         An external tool can then connect to get information from Suricata
554         or trigger some modifications of the engine. Set enabled to yes
555         to activate the feature. In auto mode, the feature will only be
556         activated in live capture mode. You can use the filename variable to set
557         the file name of the socket.
558       '';
559     };
561     "exception-policy" = mkOption {
562       type = types.enum [
563         "auto"
564         "drop-packet"
565         "drop-flow"
566         "reject"
567         "bypass"
568         "pass-packet"
569         "pass-flow"
570         "ignore"
571       ];
572       default = "auto";
573       description = ''
574         Define a common behavior for all exception policies.
575         In IPS mode, the default is drop-flow. For cases when that's not possible, the
576         engine will fall to drop-packet. To fallback to old behavior (setting each of
577         them individually, or ignoring all), set this to ignore.
578         All values available for exception policies can be used, and there is one
579         extra option: auto - which means drop-flow or drop-packet (as explained above)
580         in IPS mode, and ignore in IDS mode. Exception policy values are: drop-packet,
581         drop-flow, reject, bypass, pass-packet, pass-flow, ignore (disable).
582       '';
583     };
585     "default-rule-path" = mkOption {
586       type = types.path;
587       default = "/var/lib/suricata/rules";
588       description = "Path in which suricata-update managed rules are stored by default";
589     };
591     "rule-files" = mkOption {
592       type = types.listOf types.str;
593       default = [ "suricata.rules" ];
594       description = "Files to load suricata-update managed rules, relative to 'default-rule-path'";
595     };
597     "classification-file" = mkOption {
598       type = types.str;
599       default = "/var/lib/suricata/rules/classification.config";
600       description = "Suricata classification configuration file";
601     };
603     "reference-config-file" = mkOption {
604       type = types.str;
605       default = "${cfg.package}/etc/suricata/reference.config";
606       description = "Suricata reference configuration file";
607     };
609     "threshold-file" = mkOption {
610       type = types.str;
611       default = "${cfg.package}/etc/suricata/threshold.config";
612       description = "Suricata threshold configuration file";
613     };
615     includes = mkOption {
616       type = with types; nullOr (listOf path);
617       default = null;
618       description = ''
619         Files to include in the suricata configuration. See
620         [docs/configuration/suricata-yaml](https://docs.suricata.io/en/suricata-7.0.3/configuration/suricata-yaml.html)
621         for available options.
622       '';
623     };
624   };