{ lib, sysConfig, config, pkgs, ... }: let cfg = config.programs.ssh.autosshProxies; in { options = { programs.ssh.autosshProxies = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: { options = { port = lib.mkOption { type = lib.types.port; }; socksPort = lib.mkOption { type = lib.types.port; default = config.port - 1; }; host = lib.mkOption { type = lib.types.str; default = name; }; sshpassSecret = lib.mkOption { type = lib.types.nullOr lib.types.str; }; ProxyCommand = lib.mkOption { type = lib.types.str; readOnly = true; default = "${lib.getExe pkgs.socat} - SOCKS4A:127.0.0.1:%h:%p,socksport=${toString config.port}"; }; }; })); }; }; config = { assertions = [ { assertion = builtins.length (lib.unique (lib.concatMap (cfg: [cfg.port cfg.socksPort]) (builtins.attrValues cfg))) == builtins.length (builtins.attrValues cfg) * 2; message = "autosshProxy ports are not unique"; } ]; systemd.user.services = lib.mkMerge (map (cfg: { "autossh-socks@${cfg.host}:${toString cfg.socksPort}" = { Service = { Type = "notify"; NotifyAccess = "all"; WorkingDirectory = "~"; Restart = "always"; RestartSec = "23s"; ExecStart = "${pkgs.writeScript "autossh" '' #!${lib.getExe config.programs.zsh.package} -xe host="''${1%:*}" port="''${1#*:}" typeset -a cmd cmd=() if [[ -n "''${SSHPASS_SECRET}" ]]; then cmd+=(${lib.getExe' pkgs.sshpassSecret "sshpass-secret"}) cmd+=("''${(@s/:/)SSHPASS_SECRET}") cmd+=(--) fi cmd+=(${lib.getExe' pkgs.openssh "ssh"} -vN -D 127.0.0.1:''${port} -o ControlPath=none -o ExitOnForwardFailure=yes -o ServerAliveCountMax=15 -o ServerAliveInterval=2 "''${host}") ( exec -a "''${cmd[1]}" -- ''${cmd} ) & pid=$! newpid="" i=200 while ! { newpid=$(${lib.getExe' pkgs.iproute2 "ss"} -HO -pln "src localhost sport ''${port}" | ${lib.getExe pkgs.gnused} -r 's/^.*pid=([0-9]+).*$/\1/'); [[ -n $newpid ]] }; do if ! kill -0 "''${pid}"; then wait "''${pid}" exit $? fi [[ "''${i}" -gt 0 ]] || exit 1 i=$((''${i} - 1)) ${lib.getExe' pkgs.coreutils "sleep"} 0.1 done ${lib.getExe' sysConfig.systemd.package "systemd-notify"} --pid=''${newpid} --ready ''} \"%I\""; Environment = lib.optional (cfg.sshpassSecret != null) "SSHPASS_SECRET=${cfg.sshpassSecret}"; }; Unit = { StopWhenUnneeded = true; StartLimitInterval = "180s"; StartLimitBurst = 7; }; }; "proxy-to-autossh-socks@${toString cfg.port}" = { Unit = { BindsTo = ["autossh-socks@${cfg.host}:${toString cfg.socksPort}.service" "proxy-to-autossh-socks@${toString cfg.port}.socket"]; After = ["autossh-socks@${cfg.host}:${toString cfg.socksPort}.service" "proxy-to-autossh-socks@${toString cfg.port}.socket"]; }; Service = { ExecStart = "${sysConfig.systemd.package}/lib/systemd/systemd-socket-proxyd --exit-idle-time=60s 127.0.0.1:${toString cfg.socksPort}"; Restart = "always"; RestartSec = "23s"; }; }; }) (builtins.attrValues cfg)); systemd.user.sockets = builtins.listToAttrs (map (cfg: lib.nameValuePair "proxy-to-autossh-socks@${toString cfg.port}" { Socket = { ListenStream = "%I"; TriggerLimitIntervalSec = 0; PollLimitIntervalSec = "180s"; PollLimitBurst = 6; }; Install = { WantedBy = ["sockets.target"]; }; }) (builtins.attrValues cfg)); }; }