From 26c6e5f758b86f85dd9f9f46e484ed5fcab2147f Mon Sep 17 00:00:00 2001 From: Jason Felice Date: Mon, 24 Jun 2019 11:43:01 -0400 Subject: [PATCH] port autossh service from nixos --- modules/module-list.nix | 1 + modules/services/autossh.nix | 106 +++++++++++++++++++++++++++++++++++ release.nix | 1 + tests/autossh.nix | 17 ++++++ 4 files changed, 125 insertions(+) create mode 100644 modules/services/autossh.nix create mode 100644 tests/autossh.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 04ddd5b..0a07f11 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -30,6 +30,7 @@ ./fonts ./launchd ./services/activate-system + ./services/autossh.nix ./services/buildkite-agent.nix ./services/chunkwm.nix ./services/emacs.nix diff --git a/modules/services/autossh.nix b/modules/services/autossh.nix new file mode 100644 index 0000000..8c5cd5c --- /dev/null +++ b/modules/services/autossh.nix @@ -0,0 +1,106 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.autossh; + +in + +{ + + ###### interface + + options = { + + services.autossh = { + + sessions = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.string; + example = "socks-peer"; + description = "Name of the local AutoSSH session"; + }; + user = mkOption { + type = types.string; + example = "bill"; + description = "Name of the user the AutoSSH session should run as"; + }; + monitoringPort = mkOption { + type = types.int; + default = 0; + example = 20000; + description = '' + Port to be used by AutoSSH for peer monitoring. Note, that + AutoSSH also uses mport+1. Value of 0 disables the keep-alive + style monitoring + ''; + }; + extraArguments = mkOption { + type = types.string; + example = "-N -D4343 bill@socks.example.net"; + description = '' + Arguments to be passed to AutoSSH and retransmitted to SSH + process. Some meaningful options include -N (don't run remote + command), -D (open SOCKS proxy on local port), -R (forward + remote port), -L (forward local port), -v (Enable debug). Check + ssh manual for the complete list. + ''; + }; + }; + }); + + default = []; + description = '' + List of AutoSSH sessions to start as systemd services. Each service is + named 'autossh-{session.name}'. + ''; + + example = [ + { + name="socks-peer"; + user="bill"; + monitoringPort = 20000; + extraArguments="-N -D4343 billremote@socks.host.net"; + } + ]; + + }; + }; + + }; + + ###### implementation + + config = mkIf (cfg.sessions != []) { + + launchd.daemons = + lib.fold ( s : acc : acc // + { + "autossh-${s.name}" = + let + mport = if s ? monitoringPort then s.monitoringPort else 0; + in + { + # To be able to start the service with no network connection + environment.AUTOSSH_GATETIME="0"; + + # How often AutoSSH checks the network, in seconds + environment.AUTOSSH_POLL="30"; + + command = "${pkgs.autossh}/bin/autossh -M ${toString mport} ${s.extraArguments}"; + + serviceConfig = { + KeepAlive = true; + UserName = "${s.user}"; + }; + }; + }) {} cfg.sessions; + + environment.systemPackages = [ pkgs.autossh ]; + + }; +} diff --git a/release.nix b/release.nix index 4bccefa..5071d6a 100644 --- a/release.nix +++ b/release.nix @@ -98,6 +98,7 @@ let examples.simple = makeSystem ./modules/examples/simple.nix; tests.activation-scripts = makeTest ./tests/activation-scripts.nix; + tests.autossh = makeTest ./tests/autossh.nix; tests.checks-nix-gc = makeTest ./tests/checks-nix-gc.nix; tests.environment-path = makeTest ./tests/environment-path.nix; tests.launchd-daemons = makeTest ./tests/launchd-daemons.nix; diff --git a/tests/autossh.nix b/tests/autossh.nix new file mode 100644 index 0000000..d1aacd0 --- /dev/null +++ b/tests/autossh.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + services.autossh.sessions = [ { + name = "foo"; + user = "jfelice"; + extraArguments = "-i /some/key -T -N bar.eraserhead.net"; + } ]; + + test = '' + plist=${config.out}/Library/LaunchDaemons/org.nixos.autossh-foo.plist + test -f $plist + grep 'exec /nix/store/.*/bin/autossh ' $plist + grep 'exec.*-i /some/key ' $plist + tr -d '\n\t ' <$plist |grep 'KeepAlive' + ''; +}