Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s
180 lines
5.1 KiB
Nix
180 lines
5.1 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.lokinet;
|
|
dataDir = "/var/lib/lokinet";
|
|
settingsFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; };
|
|
configFile = settingsFormat.generate "lokinet.ini" (
|
|
lib.filterAttrsRecursive (n: v: v != null) cfg.settings
|
|
);
|
|
in
|
|
with lib;
|
|
{
|
|
options.services.lokinet = {
|
|
enable = mkEnableOption "Lokinet daemon";
|
|
|
|
package = mkPackageOption pkgs "lokinet" { };
|
|
|
|
useLocally = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
example = true;
|
|
description = "Whether to use Lokinet locally.";
|
|
};
|
|
|
|
settings = mkOption {
|
|
type =
|
|
with types;
|
|
submodule {
|
|
freeformType = settingsFormat.type;
|
|
|
|
options = {
|
|
dns = {
|
|
bind = mkOption {
|
|
type = str;
|
|
default = "127.3.2.1";
|
|
description = "Address to bind to for handling DNS requests.";
|
|
};
|
|
|
|
upstream = mkOption {
|
|
type = listOf str;
|
|
default = [ "9.9.9.10" ];
|
|
example = [
|
|
"1.1.1.1"
|
|
"8.8.8.8"
|
|
];
|
|
description = ''
|
|
Upstream resolver(s) to use as fallback for non-loki addresses.
|
|
Multiple values accepted.
|
|
'';
|
|
};
|
|
};
|
|
|
|
network = {
|
|
exit = mkOption {
|
|
type = bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to act as an exit node. Beware that this
|
|
increases demand on the server and may pose liability concerns.
|
|
Enable at your own risk.
|
|
'';
|
|
};
|
|
|
|
exit-node = mkOption {
|
|
type = nullOr (listOf str);
|
|
default = null;
|
|
example = ''
|
|
exit-node = [ "example.loki" ]; # maps all exit traffic to example.loki
|
|
exit-node = [ "example.loki:100.0.0.0/24" ]; # maps 100.0.0.0/24 to example.loki
|
|
'';
|
|
description = ''
|
|
Specify a `.loki` address and an optional ip range to use as an exit broker.
|
|
See <http://probably.loki/wiki/index.php?title=Exit_Nodes> for
|
|
a list of exit nodes.
|
|
'';
|
|
};
|
|
|
|
keyfile = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
example = "snappkey.private";
|
|
description = ''
|
|
The private key to persist address with. If not specified the address will be ephemeral.
|
|
This keyfile is generated automatically if the specified file doesn't exist.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
};
|
|
default = { };
|
|
example = literalExpression ''
|
|
{
|
|
dns = {
|
|
bind = "127.3.2.1";
|
|
upstream = [ "1.1.1.1" "8.8.8.8" ];
|
|
};
|
|
|
|
network.exit-node = [ "example.loki" "example2.loki" ];
|
|
}
|
|
'';
|
|
description = ''
|
|
Configuration for Lokinet.
|
|
Currently, the best way to view the available settings is by
|
|
generating a config file using `lokinet -g`.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
networking.resolvconf.extraConfig = mkIf cfg.useLocally ''
|
|
name_servers="${cfg.settings.dns.bind}"
|
|
'';
|
|
|
|
systemd.services.lokinet = {
|
|
description = "Lokinet";
|
|
after = [
|
|
"network-online.target"
|
|
"network.target"
|
|
];
|
|
wants = [
|
|
"network-online.target"
|
|
"network.target"
|
|
];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
preStart = ''
|
|
ln -sf ${cfg.package}/share/bootstrap.signed ${dataDir}
|
|
${pkgs.coreutils}/bin/install -m 600 ${configFile} ${dataDir}/lokinet.ini
|
|
|
|
${optionalString (cfg.settings.network.keyfile != null) ''
|
|
${pkgs.crudini}/bin/crudini --set ${dataDir}/lokinet.ini network keyfile "${dataDir}/${cfg.settings.network.keyfile}"
|
|
''}
|
|
'';
|
|
|
|
serviceConfig = {
|
|
DynamicUser = true;
|
|
StateDirectory = "lokinet";
|
|
AmbientCapabilities = [
|
|
"CAP_NET_ADMIN"
|
|
"CAP_NET_BIND_SERVICE"
|
|
];
|
|
ExecStart = "${cfg.package}/bin/lokinet ${dataDir}/lokinet.ini";
|
|
Restart = "always";
|
|
RestartSec = "5s";
|
|
|
|
# hardening
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
NoNewPrivileges = true;
|
|
PrivateTmp = true;
|
|
PrivateMounts = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
ReadWritePaths = "/dev/net/tun";
|
|
RestrictAddressFamilies = [
|
|
"AF_UNIX"
|
|
"AF_INET"
|
|
"AF_INET6"
|
|
"AF_NETLINK"
|
|
];
|
|
RestrictNamespaces = true;
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = [ cfg.package ];
|
|
};
|
|
}
|