Files
server-config/containers/server-n0/sshpiper.nix
Floweynt 76fa38e34c
flake-check / flake-check (push) Canceled after 0s
lint / lint (push) Canceled after 0s
diff-tag / dix (push) Canceled after 0s
initial commit
2026-08-31 08:41:45 -05:00

123 lines
3.0 KiB
Nix

{
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;
};
}