{ name, pkgs, hostInfo, dsl, lib, containers, customPkgs, ... }: let inherit (dsl) mkContainer mkService collectContainers; inherit (hostInfo.paths) server secrets; dataDir = hostInfo.paths.data; mkSshpiperConfig = { pipes, privateKey ? "/common_id", }: let header = '' version: "1.0" pipes: ''; mkPipe = { username, host, keysName ? username, }: '' - from: - username: "${username}" authorized_keys: /etc/sshpiperd/keys/user_${keysName}/authorized_keys to: host: ${host}:22 username: "runner" private_key: "${privateKey}" ignore_hostkey: true ''; in header + lib.concatMapStrings mkPipe pipes; sshPipes = lib.concatMap ( { container, data }: map (lib.mergeAttrs { host = container.name; }) data ) (collectContainers "sshpiperRoutes" containers); sshpiperYaml = pkgs.writeText "sshpiper.yaml" (mkSshpiperConfig { pipes = sshPipes; }); in { ${name} = mkContainer { inherit name; net.access = map (p: { to = p.host; tcp = [ 22 ]; }) sshPipes; svc.autoStart = true; net.forward.tcp = [ { host = 22; container = 2222; } ]; resources.fs = { "/etc/sshpiperd/keys" = { hostPath = "${dataDir}/core/sshpiper"; isReadOnly = true; }; "/common_id" = { hostPath = "${server}/keypair/id_ed25519"; isReadOnly = true; }; "/etc/ssh/ssh_host_ed25519_key" = { hostPath = "${secrets}/ssh_host_ed25519_key"; isReadOnly = true; }; "/etc/ssh/ssh_host_rsa_key" = { hostPath = "${secrets}/ssh_host_rsa_key"; isReadOnly = true; }; "/etc/ssh/ssh_host_ecdsa_key" = { hostPath = "${secrets}/ssh_host_ecdsa_key"; isReadOnly = true; }; }; service = { pkgs, ... }: mkService { description = "sshpiper SSH multiplexer"; execStart = "${lib.getExe' customPkgs.sshpiper "sshpiperd"} --log-level trace --server-key '/etc/ssh/ssh_host_*_key' ${lib.getExe' customPkgs.sshpiper "yaml"} --config /run/sshpiperd/config.yaml"; networkOnline = true; serviceConfig = { # sshpiperd rejects world-readable configs; copy store (444) -> runtime (600) ExecStartPre = "${lib.getExe' pkgs.coreutils "install"} -m 600 ${sshpiperYaml} /run/sshpiperd/config.yaml"; RuntimeDirectory = "sshpiperd"; PrivateTmp = true; RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; }; }; }; _sshpiperRegister = let doTranslate = self: { username, keysName ? username, }: { inherit username keysName; host = self.name; }; in args: self: { sshpiperRoutes = if lib.isAttrs args then [ (doTranslate self args) ] else lib.map (doTranslate self) args; }; }