diff options
author | Sandro <sandro.jaeckel@gmail.com> | 2022-11-01 23:44:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-01 23:44:25 +0100 |
commit | a01b2b807e7396987d5de08c41c15323c9957e3c (patch) | |
tree | ee5e4f1983c4d8aff193a9526ede0289df3c428a | |
parent | 796cc1ad514ec46ab0631ec56e6cb4e397f36e26 (diff) | |
parent | 76ccbea1525199e169c3f59fc8dfc559a2c2a324 (diff) |
Merge pull request #197221 from azahi/endlessh-module
-rw-r--r-- | nixos/doc/manual/from_md/release-notes/rl-2211.section.xml | 7 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2211.section.md | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/security/endlessh.nix | 99 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/endlessh.nix | 43 | ||||
-rw-r--r-- | pkgs/servers/endlessh/default.nix | 20 |
7 files changed, 170 insertions, 3 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 5de7e79bb080e..e9f4f707f52fd 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -316,6 +316,13 @@ </listitem> <listitem> <para> + <link xlink:href="https://github.com/skeeto/endlessh">endlessh</link>, + an SSH tarpit. Available as + <link linkend="opt-services.endlessh.enable">services.endlessh</link>. + </para> + </listitem> + <listitem> + <para> <link xlink:href="https://github.com/shizunge/endlessh-go">endlessh-go</link>, an SSH tarpit that exposes Prometheus metrics. Available as <link linkend="opt-services.endlessh-go.enable">services.endlessh-go</link>. diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 541deabc2057d..9b5257ca8e1e5 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -109,6 +109,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [alps](https://git.sr.ht/~migadu/alps), a simple and extensible webmail. Available as [services.alps](#opt-services.alps.enable). +- [endlessh](https://github.com/skeeto/endlessh), an SSH tarpit. Available as [services.endlessh](#opt-services.endlessh.enable). + - [endlessh-go](https://github.com/shizunge/endlessh-go), an SSH tarpit that exposes Prometheus metrics. Available as [services.endlessh-go](#opt-services.endlessh-go.enable). - [Garage](https://garagehq.deuxfleurs.fr/), a simple object storage server for geodistributed deployments, alternative to MinIO. Available as [services.garage](#opt-services.garage.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ba9f67f87fd62..1e9298a6571d8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1012,6 +1012,7 @@ ./services/security/certmgr.nix ./services/security/cfssl.nix ./services/security/clamav.nix + ./services/security/endlessh.nix ./services/security/endlessh-go.nix ./services/security/fail2ban.nix ./services/security/fprintd.nix diff --git a/nixos/modules/services/security/endlessh.nix b/nixos/modules/services/security/endlessh.nix new file mode 100644 index 0000000000000..e99b4dadcd581 --- /dev/null +++ b/nixos/modules/services/security/endlessh.nix @@ -0,0 +1,99 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.endlessh; +in +{ + options.services.endlessh = { + enable = mkEnableOption (mdDoc "endlessh service"); + + port = mkOption { + type = types.port; + default = 2222; + example = 22; + description = mdDoc '' + Specifies on which port the endlessh daemon listens for SSH + connections. + + Setting this to `22` may conflict with {option}`services.openssh`. + ''; + }; + + extraOptions = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "-6" "-d 9000" "-v" ]; + description = mdDoc '' + Additional command line options to pass to the endlessh daemon. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Whether to open a firewall port for the SSH listener. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.endlessh = { + description = "SSH tarpit"; + requires = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + let + needsPrivileges = cfg.port < 1024; + capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ]; + rootDirectory = "/run/endlessh"; + in + { + Restart = "always"; + ExecStart = with cfg; concatStringsSep " " ([ + "${pkgs.endlessh}/bin/endlessh" + "-p ${toString port}" + ] ++ extraOptions); + DynamicUser = true; + RootDirectory = rootDirectory; + BindReadOnlyPaths = [ builtins.storeDir ]; + InaccessiblePaths = [ "-+${rootDirectory}" ]; + RuntimeDirectory = baseNameOf rootDirectory; + RuntimeDirectoryMode = "700"; + AmbientCapabilities = capabilities; + CapabilityBoundingSet = capabilities; + UMask = "0077"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = !needsPrivileges; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + ProtectProc = "noaccess"; + ProcSubset = "pid"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ]; + }; + }; + + networking.firewall.allowedTCPPorts = with cfg; + optionals openFirewall [ port ]; + }; + + meta.maintainers = with maintainers; [ azahi ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 06ee955668f29..a3253339c035e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -183,6 +183,7 @@ in { ejabberd = handleTest ./xmpp/ejabberd.nix {}; elk = handleTestOn ["x86_64-linux"] ./elk.nix {}; emacs-daemon = handleTest ./emacs-daemon.nix {}; + endlessh = handleTest ./endlessh.nix {}; endlessh-go = handleTest ./endlessh-go.nix {}; engelsystem = handleTest ./engelsystem.nix {}; enlightenment = handleTest ./enlightenment.nix {}; diff --git a/nixos/tests/endlessh.nix b/nixos/tests/endlessh.nix new file mode 100644 index 0000000000000..be742a749fdd8 --- /dev/null +++ b/nixos/tests/endlessh.nix @@ -0,0 +1,43 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: +{ + name = "endlessh"; + meta.maintainers = with lib.maintainers; [ azahi ]; + + nodes = { + server = { ... }: { + services.endlessh = { + enable = true; + openFirewall = true; + }; + + specialisation = { + unprivileged.configuration.services.endlessh.port = 2222; + + privileged.configuration.services.endlessh.port = 22; + }; + }; + + client = { pkgs, ... }: { + environment.systemPackages = with pkgs; [ curl netcat ]; + }; + }; + + testScript = '' + def activate_specialisation(name: str): + server.succeed(f"/run/booted-system/specialisation/{name}/bin/switch-to-configuration test >&2") + + start_all() + + with subtest("Unprivileged"): + activate_specialisation("unprivileged") + server.wait_for_unit("endlessh.service") + server.wait_for_open_port(2222) + client.succeed("nc -dvW5 server 2222") + + with subtest("Privileged"): + activate_specialisation("privileged") + server.wait_for_unit("endlessh.service") + server.wait_for_open_port(22) + client.succeed("nc -dvW5 server 22") + ''; +}) diff --git a/pkgs/servers/endlessh/default.nix b/pkgs/servers/endlessh/default.nix index fc05ec033d4b5..e408c764939f1 100644 --- a/pkgs/servers/endlessh/default.nix +++ b/pkgs/servers/endlessh/default.nix @@ -1,4 +1,10 @@ -{ lib, stdenv, fetchFromGitHub }: +{ lib +, stdenv +, fetchFromGitHub +, testers +, endlessh +, nixosTests +}: stdenv.mkDerivation rec { pname = "endlessh"; @@ -8,17 +14,25 @@ stdenv.mkDerivation rec { owner = "skeeto"; repo = pname; rev = version; - sha256 = "0ziwr8j1frsp3dajr8h5glkm1dn5cci404kazz5w1jfrp0736x68"; + hash = "sha256-yHQzDrjZycDL/2oSQCJjxbZQJ30FoixVG1dnFyTKPH4="; }; makeFlags = [ "PREFIX=$(out)" ]; + passthru.tests = { + inherit (nixosTests) endlessh; + version = testers.testVersion { + package = endlessh; + command = "endlessh -V"; + }; + }; + meta = with lib; { description = "SSH tarpit that slowly sends an endless banner"; homepage = "https://github.com/skeeto/endlessh"; changelog = "https://github.com/skeeto/endlessh/releases/tag/${version}"; license = licenses.unlicense; - maintainers = [ maintainers.marsam ]; + maintainers = with maintainers; [ azahi marsam ]; platforms = platforms.unix; }; } |