1# NixOS module for hans, ip over icmp daemon
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let
8 cfg = config.services.hans;
9
10 hansUser = "hans";
11
12in
13{
14
15 ### configuration
16
17 options = {
18
19 services.hans = {
20 clients = mkOption {
21 default = {};
22 description = lib.mdDoc ''
23 Each attribute of this option defines a systemd service that
24 runs hans. Many or none may be defined.
25 The name of each service is
26 `hans-«name»`
27 where «name» is the name of the
28 corresponding attribute name.
29 '';
30 example = literalExpression ''
31 {
32 foo = {
33 server = "192.0.2.1";
34 extraConfig = "-v";
35 }
36 }
37 '';
38 type = types.attrsOf (types.submodule (
39 {
40 options = {
41 server = mkOption {
42 type = types.str;
43 default = "";
44 description = lib.mdDoc "IP address of server running hans";
45 example = "192.0.2.1";
46 };
47
48 extraConfig = mkOption {
49 type = types.str;
50 default = "";
51 description = lib.mdDoc "Additional command line parameters";
52 example = "-v";
53 };
54
55 passwordFile = mkOption {
56 type = types.str;
57 default = "";
58 description = lib.mdDoc "File that contains password";
59 };
60
61 };
62 }));
63 };
64
65 server = {
66 enable = mkOption {
67 type = types.bool;
68 default = false;
69 description = lib.mdDoc "enable hans server";
70 };
71
72 ip = mkOption {
73 type = types.str;
74 default = "";
75 description = lib.mdDoc "The assigned ip range";
76 example = "198.51.100.0";
77 };
78
79 respondToSystemPings = mkOption {
80 type = types.bool;
81 default = false;
82 description = lib.mdDoc "Force hans respond to ordinary pings";
83 };
84
85 extraConfig = mkOption {
86 type = types.str;
87 default = "";
88 description = lib.mdDoc "Additional command line parameters";
89 example = "-v";
90 };
91
92 passwordFile = mkOption {
93 type = types.str;
94 default = "";
95 description = lib.mdDoc "File that contains password";
96 };
97 };
98
99 };
100 };
101
102 ### implementation
103
104 config = mkIf (cfg.server.enable || cfg.clients != {}) {
105 boot.kernel.sysctl = optionalAttrs cfg.server.respondToSystemPings {
106 "net.ipv4.icmp_echo_ignore_all" = 1;
107 };
108
109 boot.kernelModules = [ "tun" ];
110
111 systemd.services =
112 let
113 createHansClientService = name: cfg:
114 {
115 description = "hans client - ${name}";
116 after = [ "network.target" ];
117 wantedBy = [ "multi-user.target" ];
118 script = "${pkgs.hans}/bin/hans -f -u ${hansUser} ${cfg.extraConfig} -c ${cfg.server} ${optionalString (cfg.passwordFile != "") "-p $(cat \"${cfg.passwordFile}\")"}";
119 serviceConfig = {
120 RestartSec = "30s";
121 Restart = "always";
122 };
123 };
124 in
125 listToAttrs (
126 mapAttrsToList
127 (name: value: nameValuePair "hans-${name}" (createHansClientService name value))
128 cfg.clients
129 ) // {
130 hans = mkIf (cfg.server.enable) {
131 description = "hans, ip over icmp server daemon";
132 after = [ "network.target" ];
133 wantedBy = [ "multi-user.target" ];
134 script = "${pkgs.hans}/bin/hans -f -u ${hansUser} ${cfg.server.extraConfig} -s ${cfg.server.ip} ${optionalString cfg.server.respondToSystemPings "-r"} ${optionalString (cfg.server.passwordFile != "") "-p $(cat \"${cfg.server.passwordFile}\")"}";
135 };
136 };
137
138 users.users.${hansUser} = {
139 description = "Hans daemon user";
140 isSystemUser = true;
141 };
142 };
143
144 meta.maintainers = with maintainers; [ ];
145}