at 23.11-pre 4.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.endlessh-go; 7in 8{ 9 options.services.endlessh-go = { 10 enable = mkEnableOption (mdDoc "endlessh-go service"); 11 12 listenAddress = mkOption { 13 type = types.str; 14 default = "0.0.0.0"; 15 example = "[::]"; 16 description = mdDoc '' 17 Interface address to bind the endlessh-go daemon to SSH connections. 18 ''; 19 }; 20 21 port = mkOption { 22 type = types.port; 23 default = 2222; 24 example = 22; 25 description = mdDoc '' 26 Specifies on which port the endlessh-go daemon listens for SSH 27 connections. 28 29 Setting this to `22` may conflict with {option}`services.openssh`. 30 ''; 31 }; 32 33 prometheus = { 34 enable = mkEnableOption (mdDoc "Prometheus integration"); 35 36 listenAddress = mkOption { 37 type = types.str; 38 default = "0.0.0.0"; 39 example = "[::]"; 40 description = mdDoc '' 41 Interface address to bind the endlessh-go daemon to answer Prometheus 42 queries. 43 ''; 44 }; 45 46 port = mkOption { 47 type = types.port; 48 default = 2112; 49 example = 9119; 50 description = mdDoc '' 51 Specifies on which port the endlessh-go daemon listens for Prometheus 52 queries. 53 ''; 54 }; 55 }; 56 57 extraOptions = mkOption { 58 type = with types; listOf str; 59 default = [ ]; 60 example = [ "-conn_type=tcp4" "-max_clients=8192" ]; 61 description = mdDoc '' 62 Additional command line options to pass to the endlessh-go daemon. 63 ''; 64 }; 65 66 openFirewall = mkOption { 67 type = types.bool; 68 default = false; 69 description = lib.mdDoc '' 70 Whether to open a firewall port for the SSH listener. 71 ''; 72 }; 73 }; 74 75 config = mkIf cfg.enable { 76 systemd.services.endlessh-go = { 77 description = "SSH tarpit"; 78 requires = [ "network.target" ]; 79 wantedBy = [ "multi-user.target" ]; 80 serviceConfig = 81 let 82 needsPrivileges = cfg.port < 1024 || cfg.prometheus.port < 1024; 83 capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ]; 84 rootDirectory = "/run/endlessh-go"; 85 in 86 { 87 Restart = "always"; 88 ExecStart = with cfg; concatStringsSep " " ([ 89 "${pkgs.endlessh-go}/bin/endlessh-go" 90 "-logtostderr" 91 "-host=${listenAddress}" 92 "-port=${toString port}" 93 ] ++ optionals prometheus.enable [ 94 "-enable_prometheus" 95 "-prometheus_host=${prometheus.listenAddress}" 96 "-prometheus_port=${toString prometheus.port}" 97 ] ++ extraOptions); 98 DynamicUser = true; 99 RootDirectory = rootDirectory; 100 BindReadOnlyPaths = [ builtins.storeDir ]; 101 InaccessiblePaths = [ "-+${rootDirectory}" ]; 102 RuntimeDirectory = baseNameOf rootDirectory; 103 RuntimeDirectoryMode = "700"; 104 AmbientCapabilities = capabilities; 105 CapabilityBoundingSet = capabilities; 106 UMask = "0077"; 107 LockPersonality = true; 108 MemoryDenyWriteExecute = true; 109 NoNewPrivileges = true; 110 PrivateDevices = true; 111 PrivateTmp = true; 112 PrivateUsers = !needsPrivileges; 113 ProtectClock = true; 114 ProtectControlGroups = true; 115 ProtectHome = true; 116 ProtectHostname = true; 117 ProtectKernelLogs = true; 118 ProtectKernelModules = true; 119 ProtectKernelTunables = true; 120 ProtectSystem = "strict"; 121 ProtectProc = "noaccess"; 122 ProcSubset = "pid"; 123 RemoveIPC = true; 124 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; 125 RestrictNamespaces = true; 126 RestrictRealtime = true; 127 RestrictSUIDSGID = true; 128 SystemCallArchitectures = "native"; 129 SystemCallFilter = [ "@system-service" "~@privileged" ]; 130 }; 131 }; 132 133 networking.firewall.allowedTCPPorts = with cfg; 134 optionals openFirewall [ port prometheus.port ]; 135 }; 136 137 meta.maintainers = with maintainers; [ azahi ]; 138}