at 24.11-pre 5.0 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 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); 8in with lib; { 9 options.services.lokinet = { 10 enable = mkEnableOption "Lokinet daemon"; 11 12 package = mkPackageOption pkgs "lokinet" { }; 13 14 useLocally = mkOption { 15 type = types.bool; 16 default = false; 17 example = true; 18 description = "Whether to use Lokinet locally."; 19 }; 20 21 settings = mkOption { 22 type = with types; 23 submodule { 24 freeformType = settingsFormat.type; 25 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 }; 33 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 }; 44 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 }; 55 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 }; 69 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 }; 89 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 }; 100 101 config = mkIf cfg.enable { 102 networking.resolvconf.extraConfig = mkIf cfg.useLocally '' 103 name_servers="${cfg.settings.dns.bind}" 104 ''; 105 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" ]; 111 112 preStart = '' 113 ln -sf ${cfg.package}/share/bootstrap.signed ${dataDir} 114 ${pkgs.coreutils}/bin/install -m 600 ${configFile} ${dataDir}/lokinet.ini 115 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 ''; 120 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"; 128 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 }; 149 150 environment.systemPackages = [ cfg.package ]; 151 }; 152}