at 25.11-pre 3.2 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.uptermd; 12in 13{ 14 options = { 15 services.uptermd = { 16 enable = mkEnableOption "uptermd"; 17 18 openFirewall = mkOption { 19 type = types.bool; 20 default = false; 21 description = '' 22 Whether to open the firewall for the port in {option}`services.uptermd.port`. 23 ''; 24 }; 25 26 port = mkOption { 27 type = types.port; 28 default = 2222; 29 description = '' 30 Port the server will listen on. 31 ''; 32 }; 33 34 listenAddress = mkOption { 35 type = types.str; 36 default = "[::]"; 37 example = "127.0.0.1"; 38 description = '' 39 Address the server will listen on. 40 ''; 41 }; 42 43 hostKey = mkOption { 44 type = types.nullOr types.path; 45 default = null; 46 example = "/run/keys/upterm_host_ed25519_key"; 47 description = '' 48 Path to SSH host key. If not defined, an ed25519 keypair is generated automatically. 49 ''; 50 }; 51 52 extraFlags = mkOption { 53 type = types.listOf types.str; 54 default = [ ]; 55 example = [ "--debug" ]; 56 description = '' 57 Extra flags passed to the uptermd command. 58 ''; 59 }; 60 }; 61 }; 62 63 config = mkIf cfg.enable { 64 networking.firewall = mkIf cfg.openFirewall { 65 allowedTCPPorts = [ cfg.port ]; 66 }; 67 68 systemd.services.uptermd = { 69 description = "Upterm Daemon"; 70 wantedBy = [ "multi-user.target" ]; 71 after = [ "network.target" ]; 72 73 path = [ pkgs.openssh ]; 74 75 preStart = mkIf (cfg.hostKey == null) '' 76 if ! [ -f ssh_host_ed25519_key ]; then 77 ssh-keygen \ 78 -t ed25519 \ 79 -f ssh_host_ed25519_key \ 80 -N "" 81 fi 82 ''; 83 84 serviceConfig = { 85 StateDirectory = "uptermd"; 86 WorkingDirectory = "/var/lib/uptermd"; 87 ExecStart = "${pkgs.upterm}/bin/uptermd --ssh-addr ${cfg.listenAddress}:${toString cfg.port} --private-key ${ 88 if cfg.hostKey == null then "ssh_host_ed25519_key" else cfg.hostKey 89 } ${concatStringsSep " " cfg.extraFlags}"; 90 91 # Hardening 92 AmbientCapabilities = mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; 93 CapabilityBoundingSet = mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; 94 PrivateUsers = cfg.port >= 1024; 95 DynamicUser = true; 96 LockPersonality = true; 97 MemoryDenyWriteExecute = true; 98 PrivateDevices = true; 99 ProtectClock = true; 100 ProtectControlGroups = true; 101 ProtectHome = true; 102 ProtectHostname = true; 103 ProtectKernelLogs = true; 104 ProtectKernelModules = true; 105 ProtectKernelTunables = true; 106 ProtectProc = "invisible"; 107 # AF_UNIX is for ssh-keygen, which relies on nscd to resolve the uid to a user 108 RestrictAddressFamilies = [ 109 "AF_INET" 110 "AF_INET6" 111 "AF_UNIX" 112 ]; 113 RestrictNamespaces = true; 114 RestrictRealtime = true; 115 SystemCallArchitectures = "native"; 116 SystemCallFilter = "@system-service"; 117 }; 118 }; 119 }; 120}