From 461bdf0a7abde1521d9a8ed5c19f57bd3d412126 Mon Sep 17 00:00:00 2001 From: wyndon Date: Tue, 31 May 2022 07:54:25 +0200 Subject: [PATCH 1/2] lokinet: init at 0.9.9 --- .../networking/p2p/lokinet/default.nix | 64 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 2 files changed, 66 insertions(+) create mode 100644 pkgs/applications/networking/p2p/lokinet/default.nix diff --git a/pkgs/applications/networking/p2p/lokinet/default.nix b/pkgs/applications/networking/p2p/lokinet/default.nix new file mode 100644 index 000000000000..e3e2c8e58831 --- /dev/null +++ b/pkgs/applications/networking/p2p/lokinet/default.nix @@ -0,0 +1,64 @@ +{ stdenv +, lib +, fetchFromGitHub +, cmake +, libevent +, libsodium +, libuv +, nlohmann_json +, pkg-config +, sqlite +, systemd +, unbound +, zeromq +}: + +stdenv.mkDerivation rec { + pname = "lokinet"; + version = "0.9.9"; + + src = fetchFromGitHub { + owner = "oxen-io"; + repo = "lokinet"; + rev = "v${version}"; + fetchSubmodules = true; + sha256 = "sha256-AaGsRg9S9Cng9emI/mN09QSOIRbE+x3916clWAwLnRs="; + }; + + nativeBuildInputs = [ + cmake + pkg-config + ]; + + buildInputs = [ + libevent + libuv + libsodium + nlohmann_json + sqlite + systemd + unbound + zeromq + ]; + + cmakeFlags = [ + "-DGIT_VERSION=v${version}" + "-DWITH_BOOTSTRAP=OFF" # we provide bootstrap files manually + "-DWITH_SETCAP=OFF" + ]; + + # copy bootstrap files + # see https://github.com/oxen-io/lokinet/issues/1765#issuecomment-938208774 + postInstall = '' + mkdir -p $out/share/testnet + cp $src/contrib/bootstrap/mainnet.signed $out/share/bootstrap.signed + cp $src/contrib/bootstrap/testnet.signed $out/share/testnet/bootstrap.signed + ''; + + meta = with lib; { + description = "Anonymous, decentralized and IP based overlay network for the internet"; + homepage = "https://lokinet.org/"; + license = licenses.gpl3Plus; + maintainers = with maintainers; [ wyndon ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 6b396cf56189..6ff981e99b1a 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -28105,6 +28105,8 @@ with pkgs; portaudio = null; }; + lokinet = callPackage ../applications/networking/p2p/lokinet { }; + losslesscut-bin = callPackage ../applications/video/losslesscut-bin { }; loxodo = callPackage ../applications/misc/loxodo { }; From 69e1e00ebbdf40c1a1b2cc622f7e58aa927b4044 Mon Sep 17 00:00:00 2001 From: wyndon Date: Tue, 31 May 2022 07:54:41 +0200 Subject: [PATCH 2/2] nixos/lokinet: init --- nixos/modules/module-list.nix | 1 + nixos/modules/services/networking/lokinet.nix | 157 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 nixos/modules/services/networking/lokinet.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b757e05edce3..c8e1216813e4 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -825,6 +825,7 @@ ./services/networking/libreswan.nix ./services/networking/lldpd.nix ./services/networking/logmein-hamachi.nix + ./services/networking/lokinet.nix ./services/networking/lxd-image-server.nix ./services/networking/magic-wormhole-mailbox-server.nix ./services/networking/matterbridge.nix diff --git a/nixos/modules/services/networking/lokinet.nix b/nixos/modules/services/networking/lokinet.nix new file mode 100644 index 000000000000..cf091341c839 --- /dev/null +++ b/nixos/modules/services/networking/lokinet.nix @@ -0,0 +1,157 @@ +{ 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 = mkOption { + type = types.package; + default = pkgs.lokinet; + defaultText = literalExpression "pkgs.lokinet"; + description = "Lokinet package to use."; + }; + + 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 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 ]; + }; +}