Commit e6a71e75b4e7

Vincent Demeester <vincent@sbr.pm>
2016-12-14 15:00:45
Trying ssh-tunnel service on kobe
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 67f8545
Changed files (2)
machine/kobe.nix
@@ -9,8 +9,22 @@
 			../configuration/network.nix
 			# ../configuration/docker.nix
 			../configuration/custom-packages.nix
+			../service/ssh-tunnel.nix
 		];
 
+	# Enable the OpenSSH daemon.
+	services.openssh.enable = true;
+
+	# Enable the "SSH phone home" service for SSH reverse tunneling
+	services.ssh-phone-home = {
+		enable = true;
+		localUser = "vincent";
+		remoteHostname = "95.85.58.158";
+		remotePort = 22;
+		remoteUser = "vincent";
+		bindPort = 2222;
+	};
+	
 	networking.hostName = "kobe";
 
 }
service/ssh-tunnel.nix
@@ -0,0 +1,102 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  inherit (pkgs) openssh;
+  cfg = config.services.ssh-tunnel;
+in
+
+{
+
+  ###### interface
+
+  options = {
+    services.ssh-tunnel = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable a reverse SSH proxy.
+        '';
+      };
+
+      persist = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          When this is set to true, the service will persistently attempt to
+          reconnect at intervals whenever the port forwarding operation fails.
+          This is the recommended behavior for reliable operation. If one finds
+          oneself in an environment where this kind of behavior might draw the
+          suspicion of a network administrator, it might be a good idea to
+          set this option to false (or not use <literal>ssh-tunnel</literal>
+          at all).
+        '';
+      };
+
+      localUser = mkOption {
+        description = ''
+          Local user to connect as (i.e. the user with password-less SSH keys).
+        '';
+      };
+
+      remoteHostname = mkOption {
+        description = ''
+          The remote host to connect to. This should be the host outside of the
+          firewall or NAT.
+        '';
+      };
+
+      remotePort = mkOption {
+        default = 22;
+        description = ''
+          The port on which to connect to the remote host via SSH protocol.
+        '';
+      };
+
+      remoteUser = mkOption {
+        description = ''
+          The username to connect to the remote host as.
+        '';
+      };
+
+      bindPort = mkOption {
+        default = 2222;
+        description = ''
+          The port to bind and listen to on the remote host.
+        '';
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    systemd.services.ssh-tunnel =
+    {
+      description = ''
+        Reverse SSH tunnel as a service
+      '';
+
+      # FIXME: This isn't triggered until a reboot, and probably won't work between suspends.
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = with cfg; {
+        User = cfg.localUser;
+      } // (if cfg.persist then
+        {
+          # Restart every 10 seconds on failure
+          RestartSec = 10;
+          Restart = "on-failure";
+        }
+        else {}
+      );
+
+      script = with cfg;  ''
+        ${openssh}/bin/ssh -NTC -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R ${toString bindPort}:localhost:22 -l ${remoteUser} -p ${toString remotePort} ${remoteHostname}
+      '';
+    };
+  };
+}