From 695b0bfbe3099009529a0fa3dc00dc0e285868cf Mon Sep 17 00:00:00 2001 From: David Wronek Date: Thu, 28 Aug 2025 11:05:23 +0200 Subject: [PATCH] nixos/sshwifty: init module Signed-off-by: David Wronek --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/sshwifty.nix | 128 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 nixos/modules/services/web-apps/sshwifty.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 42147814225b..30f542ac1cc9 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1694,6 +1694,7 @@ ./services/web-apps/snipe-it.nix ./services/web-apps/snips-sh.nix ./services/web-apps/sogo.nix + ./services/web-apps/sshwifty.nix ./services/web-apps/stash.nix ./services/web-apps/stirling-pdf.nix ./services/web-apps/strfry.nix diff --git a/nixos/modules/services/web-apps/sshwifty.nix b/nixos/modules/services/web-apps/sshwifty.nix new file mode 100644 index 000000000000..40dbd6ec725d --- /dev/null +++ b/nixos/modules/services/web-apps/sshwifty.nix @@ -0,0 +1,128 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.sshwifty; + format = pkgs.formats.json { }; + settings = format.generate "sshwifty.json" cfg.settings; +in +{ + options.services.sshwifty = { + enable = lib.mkEnableOption "Sshwifty"; + package = lib.mkPackageOption pkgs "sshwifty" { }; + settings = lib.mkOption { + type = format.type; + description = '' + Configuration for Sshwifty. See + [the Sshwifty documentation](https://github.com/nirui/sshwifty/tree/master?tab=readme-ov-file#configuration) + for possible options. + ''; + }; + sharedKeyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to a file containing the shared key."; + }; + socks5PasswordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to a file containing the SOCKS5 password."; + }; + }; + config = lib.mkIf cfg.enable { + systemd.services.sshwifty = { + description = "Sshwifty"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = '' + ${lib.optionalString (cfg.sharedKeyFile != null || cfg.socks5PasswordFile != null) ( + lib.concatStringsSep " " [ + (lib.getExe pkgs.jq) + "-s" + "'.[0] * .[1]" + (lib.optionalString (cfg.sharedKeyFile != null && cfg.socks5PasswordFile != null) "* .[2]") + "'" + settings + (lib.optionalString ( + cfg.sharedKeyFile != null + ) "<(echo \"{\\\"SharedKey\\\":\\\"$(cat $CREDENTIALS_DIRECTORY/sharedkey)\\\"}\")") + (lib.optionalString ( + cfg.socks5PasswordFile != null + ) "<(echo \"{\\\"Socks5Password\\\":\\\"$(cat $CREDENTIALS_DIRECTORY/socks5pass)\\\"}\")") + "> /run/sshwifty/sshwifty.json" + ] + )} + ${lib.optionalString ( + cfg.sharedKeyFile != null || cfg.socks5PasswordFile != null + ) "export SSHWIFTY_CONFIG=/run/sshwifty/sshwifty.json"} + ${lib.optionalString ( + cfg.sharedKeyFile == null && cfg.socks5PasswordFile == null + ) "export SSHWIFTY_CONFIG=${settings}"} + exec ${lib.getExe cfg.package} + ''; + serviceConfig = { + DynamicUser = true; + RuntimeDirectory = "sshwifty"; + RuntimeDirectoryMode = "0750"; + LoadCredential = + [ ] + ++ lib.optionals (cfg.sharedKeyFile != null) [ "sharedkey:${cfg.sharedKeyFile}" ] + ++ lib.optionals (cfg.socks5PasswordFile != null) [ "socks5pass:${cfg.socks5PasswordFile}" ]; + # Hardening + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RemoveIPC = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + PrivateTmp = "disconnected"; + ProcSubset = "pid"; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = [ + "~cgroup" + "~ipc" + "~mnt" + "~net" + "~pid" + "~user" + "~uts" + ]; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "~@clock" + "~@cpu-emulation" + "~@debug" + "~@module" + "~@mount" + "~@obsolete" + "~@privileged" + "~@raw-io" + "~@reboot" + "~@resources" + "~@swap" + ]; + UMask = "0077"; + }; + }; + }; + meta.maintainers = [ lib.maintainers.ungeskriptet ]; +}