vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / lokinet.nix
blob76203c61b504e4d7b7a95b92b7238dbb82624069
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.lokinet;
5   dataDir = "/var/lib/lokinet";
6   settingsFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; };
7   configFile = settingsFormat.generate "lokinet.ini" (lib.filterAttrsRecursive (n: v: v != null) cfg.settings);
8 in with lib; {
9   options.services.lokinet = {
10     enable = mkEnableOption "Lokinet daemon";
12     package = mkPackageOption pkgs "lokinet" { };
14     useLocally = mkOption {
15       type = types.bool;
16       default = false;
17       example = true;
18       description = "Whether to use Lokinet locally.";
19     };
21     settings = mkOption {
22       type = with types;
23         submodule {
24           freeformType = settingsFormat.type;
26           options = {
27             dns = {
28               bind = mkOption {
29                 type = str;
30                 default = "127.3.2.1";
31                 description = "Address to bind to for handling DNS requests.";
32               };
34               upstream = mkOption {
35                 type = listOf str;
36                 default = [ "9.9.9.10" ];
37                 example = [ "1.1.1.1" "8.8.8.8" ];
38                 description = ''
39                   Upstream resolver(s) to use as fallback for non-loki addresses.
40                   Multiple values accepted.
41                 '';
42               };
43             };
45             network = {
46               exit = mkOption {
47                 type = bool;
48                 default = false;
49                 description = ''
50                   Whether to act as an exit node. Beware that this
51                   increases demand on the server and may pose liability concerns.
52                   Enable at your own risk.
53                 '';
54               };
56               exit-node = mkOption {
57                 type = nullOr (listOf str);
58                 default = null;
59                 example = ''
60                   exit-node = [ "example.loki" ];              # maps all exit traffic to example.loki
61                   exit-node = [ "example.loki:100.0.0.0/24" ]; # maps 100.0.0.0/24 to example.loki
62                 '';
63                 description = ''
64                   Specify a `.loki` address and an optional ip range to use as an exit broker.
65                   See <http://probably.loki/wiki/index.php?title=Exit_Nodes> for
66                   a list of exit nodes.
67                 '';
68               };
70               keyfile = mkOption {
71                 type = nullOr str;
72                 default = null;
73                 example = "snappkey.private";
74                 description = ''
75                   The private key to persist address with. If not specified the address will be ephemeral.
76                   This keyfile is generated automatically if the specified file doesn't exist.
77                 '';
78               };
79             };
80           };
81         };
82       default = { };
83       example = literalExpression ''
84         {
85           dns = {
86             bind = "127.3.2.1";
87             upstream = [ "1.1.1.1" "8.8.8.8" ];
88           };
90           network.exit-node = [ "example.loki" "example2.loki" ];
91         }
92       '';
93       description = ''
94         Configuration for Lokinet.
95         Currently, the best way to view the available settings is by
96         generating a config file using `lokinet -g`.
97       '';
98     };
99   };
101   config = mkIf cfg.enable {
102     networking.resolvconf.extraConfig = mkIf cfg.useLocally ''
103       name_servers="${cfg.settings.dns.bind}"
104     '';
106     systemd.services.lokinet = {
107       description = "Lokinet";
108       after = [ "network-online.target" "network.target" ];
109       wants = [ "network-online.target" "network.target" ];
110       wantedBy = [ "multi-user.target" ];
112       preStart = ''
113         ln -sf ${cfg.package}/share/bootstrap.signed ${dataDir}
114         ${pkgs.coreutils}/bin/install -m 600 ${configFile} ${dataDir}/lokinet.ini
116         ${optionalString (cfg.settings.network.keyfile != null) ''
117           ${pkgs.crudini}/bin/crudini --set ${dataDir}/lokinet.ini network keyfile "${dataDir}/${cfg.settings.network.keyfile}"
118         ''}
119       '';
121       serviceConfig = {
122         DynamicUser = true;
123         StateDirectory = "lokinet";
124         AmbientCapabilities = [ "CAP_NET_ADMIN" "CAP_NET_BIND_SERVICE" ];
125         ExecStart = "${cfg.package}/bin/lokinet ${dataDir}/lokinet.ini";
126         Restart = "always";
127         RestartSec = "5s";
129         # hardening
130         LockPersonality = true;
131         MemoryDenyWriteExecute = true;
132         NoNewPrivileges = true;
133         PrivateTmp = true;
134         PrivateMounts = true;
135         ProtectControlGroups = true;
136         ProtectHome = true;
137         ProtectHostname = true;
138         ProtectKernelLogs = true;
139         ProtectKernelModules = true;
140         ProtectKernelTunables = true;
141         ProtectSystem = "strict";
142         ReadWritePaths = "/dev/net/tun";
143         RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
144         RestrictNamespaces = true;
145         RestrictRealtime = true;
146         RestrictSUIDSGID = true;
147       };
148     };
150     environment.systemPackages = [ cfg.package ];
151   };