summaryrefslogtreecommitdiffstats
path: root/nixos
diff options
context:
space:
mode:
authorSandro <sandro.jaeckel@gmail.com>2022-10-09 16:50:02 +0200
committerGitHub <noreply@github.com>2022-10-09 16:50:02 +0200
commitf5802f496da7fb8bc2a2bb61f6506d3217151257 (patch)
tree3ab9e29820e70478fa28033ab0c05bd25e5c7b50 /nixos
parentead59cfc9de5df38e034159c8be99232e9e6feb5 (diff)
parent99dc9b9c164af3bc6c08ff4a4db4c2b58e368160 (diff)
Merge pull request #187026 from azahi/endlessh-go
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2211.section.xml7
-rw-r--r--nixos/doc/manual/release-notes/rl-2211.section.md2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/security/endlessh-go.nix138
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/endlessh-go.nix58
6 files changed, 207 insertions, 0 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 177af1d2afa3..9e5d4bfd20d9 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
@@ -270,6 +270,13 @@
</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>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<link xlink:href="https://netbird.io">netbird</link>, a zero
configuration VPN. Available as
<link xlink:href="options.html#opt-services.netbird.enable">services.netbird</link>.
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md
index d0376b67c982..47f3da3a435a 100644
--- a/nixos/doc/manual/release-notes/rl-2211.section.md
+++ b/nixos/doc/manual/release-notes/rl-2211.section.md
@@ -95,6 +95,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-go](https://github.com/shizunge/endlessh-go), an SSH tarpit that exposes Prometheus metrics. Available as [services.endlessh-go](#opt-services.endlessh-go.enable).
+
- [netbird](https://netbird.io), a zero configuration VPN.
Available as [services.netbird](options.html#opt-services.netbird.enable).
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index db07d6312c42..494df03e3a36 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1004,6 +1004,7 @@
./services/security/certmgr.nix
./services/security/cfssl.nix
./services/security/clamav.nix
+ ./services/security/endlessh-go.nix
./services/security/fail2ban.nix
./services/security/fprintd.nix
./services/security/haka.nix
diff --git a/nixos/modules/services/security/endlessh-go.nix b/nixos/modules/services/security/endlessh-go.nix
new file mode 100644
index 000000000000..61cca5531739
--- /dev/null
+++ b/nixos/modules/services/security/endlessh-go.nix
@@ -0,0 +1,138 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.endlessh-go;
+in
+{
+ options.services.endlessh-go = {
+ enable = mkEnableOption (mdDoc "endlessh-go service");
+
+ listenAddress = mkOption {
+ type = types.str;
+ default = "0.0.0.0";
+ example = "[::]";
+ description = mdDoc ''
+ Interface address to bind the endlessh-go daemon to SSH connections.
+ '';
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 2222;
+ example = 22;
+ description = mdDoc ''
+ Specifies on which port the endlessh-go daemon listens for SSH
+ connections.
+
+ Setting this to `22` may conflict with {option}`services.openssh`.
+ '';
+ };
+
+ prometheus = {
+ enable = mkEnableOption (mdDoc "Prometheus integration");
+
+ listenAddress = mkOption {
+ type = types.str;
+ default = "0.0.0.0";
+ example = "[::]";
+ description = mdDoc ''
+ Interface address to bind the endlessh-go daemon to answer Prometheus
+ queries.
+ '';
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 2112;
+ example = 9119;
+ description = mdDoc ''
+ Specifies on which port the endlessh-go daemon listens for Prometheus
+ queries.
+ '';
+ };
+ };
+
+ extraOptions = mkOption {
+ type = with types; listOf str;
+ default = [ ];
+ example = [ "-conn_type=tcp4" "-max_clients=8192" ];
+ description = mdDoc ''
+ Additional command line options to pass to the endlessh-go 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-go = {
+ description = "SSH tarpit";
+ requires = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig =
+ let
+ needsPrivileges = cfg.port < 1024 || cfg.prometheus.port < 1024;
+ capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
+ rootDirectory = "/run/endlessh-go";
+ in
+ {
+ Restart = "always";
+ ExecStart = with cfg; concatStringsSep " " ([
+ "${pkgs.endlessh-go}/bin/endlessh-go"
+ "-logtostderr"
+ "-host=${listenAddress}"
+ "-port=${toString port}"
+ ] ++ optionals prometheus.enable [
+ "-enable_prometheus"
+ "-prometheus_host=${prometheus.listenAddress}"
+ "-prometheus_port=${toString prometheus.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 prometheus.port ];
+ };
+
+ meta.maintainers = with maintainers; [ azahi ];
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 131936a87c37..e699b3b46261 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -180,6 +180,7 @@ in {
ejabberd = handleTest ./xmpp/ejabberd.nix {};
elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
emacs-daemon = handleTest ./emacs-daemon.nix {};
+ endlessh-go = handleTest ./endlessh-go.nix {};
engelsystem = handleTest ./engelsystem.nix {};
enlightenment = handleTest ./enlightenment.nix {};
env = handleTest ./env.nix {};
diff --git a/nixos/tests/endlessh-go.nix b/nixos/tests/endlessh-go.nix
new file mode 100644
index 000000000000..b261dbf1c560
--- /dev/null
+++ b/nixos/tests/endlessh-go.nix
@@ -0,0 +1,58 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }:
+{
+ name = "endlessh-go";
+ meta.maintainers = with lib.maintainers; [ azahi ];
+
+ nodes = {
+ server = { ... }: {
+ services.endlessh-go = {
+ enable = true;
+ prometheus.enable = true;
+ openFirewall = true;
+ };
+
+ specialisation = {
+ unprivileged.configuration = {
+ services.endlessh-go = {
+ port = 2222;
+ prometheus.port = 9229;
+ };
+ };
+
+ privileged.configuration = {
+ services.endlessh-go = {
+ port = 22;
+ prometheus.port = 92;
+ };
+ };
+ };
+ };
+
+ 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-go.service")
+ server.wait_for_open_port(2222)
+ server.wait_for_open_port(9229)
+ client.succeed("nc -dvW5 server 2222")
+ client.succeed("curl -kv server:9229/metrics")
+
+ with subtest("Privileged"):
+ activate_specialisation("privileged")
+ server.wait_for_unit("endlessh-go.service")
+ server.wait_for_open_port(22)
+ server.wait_for_open_port(92)
+ client.succeed("nc -dvW5 server 22")
+ client.succeed("curl -kv server:92/metrics")
+ '';
+})