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