1# This module defines global configuration for Haka.
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let
8
9 cfg = config.services.haka;
10
11 haka = cfg.package;
12
13 hakaConf = pkgs.writeText "haka.conf"
14 ''
15 [general]
16 configuration = ${if lib.strings.hasPrefix "/" cfg.configFile
17 then "${cfg.configFile}"
18 else "${haka}/share/haka/sample/${cfg.configFile}"}
19 ${optionalString (builtins.lessThan 0 cfg.threads) "thread = ${cfg.threads}"}
20
21 [packet]
22 ${optionalString cfg.pcap ''module = "packet/pcap"''}
23 ${optionalString cfg.nfqueue ''module = "packet/nqueue"''}
24 ${optionalString cfg.dump.enable ''dump = "yes"''}
25 ${optionalString cfg.dump.enable ''dump_input = "${cfg.dump.input}"''}
26 ${optionalString cfg.dump.enable ''dump_output = "${cfg.dump.output}"''}
27
28 interfaces = "${lib.strings.concatStringsSep "," cfg.interfaces}"
29
30 [log]
31 # Select the log module
32 module = "log/syslog"
33
34 # Set the default logging level
35 #level = "info,packet=debug"
36
37 [alert]
38 # Select the alert module
39 module = "alert/syslog"
40
41 # Disable alert on standard output
42 #alert_on_stdout = no
43
44 # alert/file module option
45 #file = "/dev/null"
46 '';
47
48in
49
50{
51
52 ###### interface
53
54 options = {
55
56 services.haka = {
57
58 enable = mkEnableOption "Haka";
59
60 package = mkOption {
61 default = pkgs.haka;
62 defaultText = "pkgs.haka";
63 type = types.package;
64 description = "
65 Which Haka derivation to use.
66 ";
67 };
68
69 configFile = mkOption {
70 default = "empty.lua";
71 example = "/srv/haka/myfilter.lua";
72 type = types.string;
73 description = ''
74 Specify which configuration file Haka uses.
75 It can be absolute path or a path relative to the sample directory of
76 the haka git repo.
77 '';
78 };
79
80 interfaces = mkOption {
81 default = [ "eth0" ];
82 example = [ "any" ];
83 type = with types; listOf string;
84 description = ''
85 Specify which interface(s) Haka listens to.
86 Use 'any' to listen to all interfaces.
87 '';
88 };
89
90 threads = mkOption {
91 default = 0;
92 example = 4;
93 type = types.int;
94 description = ''
95 The number of threads that will be used.
96 All system threads are used by default.
97 '';
98 };
99
100 pcap = mkOption {
101 default = true;
102 example = false;
103 type = types.bool;
104 description = "Whether to enable pcap";
105 };
106
107 nfqueue = mkEnableOption "nfqueue";
108
109 dump.enable = mkEnableOption "dump";
110 dump.input = mkOption {
111 default = "/tmp/input.pcap";
112 example = "/path/to/file.pcap";
113 type = types.path;
114 description = "Path to file where incoming packets are dumped";
115 };
116
117 dump.output = mkOption {
118 default = "/tmp/output.pcap";
119 example = "/path/to/file.pcap";
120 type = types.path;
121 description = "Path to file where outgoing packets are dumped";
122 };
123 };
124 };
125
126
127 ###### implementation
128
129 config = mkIf cfg.enable {
130
131 assertions = [
132 { assertion = cfg.pcap != cfg.nfqueue;
133 message = "either pcap or nfqueue can be enabled, not both.";
134 }
135 { assertion = cfg.nfqueue -> !dump.enable;
136 message = "dump can only be used with nfqueue.";
137 }
138 { assertion = cfg.interfaces != [];
139 message = "at least one interface must be specified.";
140 }];
141
142
143 environment.systemPackages = [ haka ];
144
145 systemd.services.haka = {
146 description = "Haka";
147 wantedBy = [ "multi-user.target" ];
148 after = [ "network.target" ];
149 serviceConfig = {
150 ExecStart = "${haka}/bin/haka -c ${hakaConf}";
151 ExecStop = "${haka}/bin/hakactl stop";
152 User = "root";
153 Type = "forking";
154 };
155 };
156 };
157}