diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index c6e09bda..fdf02a2c 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -10,6 +10,39 @@ let unwords = builtins.concatStringsSep " "; + localForwardModule = types.submodule ({ ... }: { + options = { + bind = { + address = mkOption { + type = types.str; + default = "localhost"; + example = "example.org"; + description = "The address where to bind the port."; + }; + + port = mkOption { + type = types.port; + example = 8080; + description = "Specifies port number to bind on bind address."; + }; + }; + + host = { + address = mkOption { + type = types.str; + example = "example.org"; + description = "The address where to forward the traffic to."; + }; + + port = mkOption { + type = types.port; + example = 80; + description = "Specifies port number to forward the traffic to."; + }; + }; + }; + }); + matchBlockModule = types.submodule ({ name, ... }: { options = { host = mkOption { @@ -152,6 +185,27 @@ let ''; }; + localForwards = mkOption { + type = types.listOf localForwardModule; + default = []; + example = literalExample '' + [ + { + bind.port = 8080; + host.address = "10.0.0.13"; + host.port = 80; + } + ]; + ''; + description = '' + Specify local port forwardings. See + + ssh_config + 5 + for LocalForward. + ''; + }; + extraOptions = mkOption { type = types.attrsOf types.str; default = {}; @@ -181,6 +235,14 @@ let ++ optional (cf.proxyCommand != null) " ProxyCommand ${cf.proxyCommand}" ++ optional (cf.proxyJump != null) " ProxyJump ${cf.proxyJump}" ++ map (file: " IdentityFile ${file}") cf.identityFile + ++ map (f: + let + addressPort = entry: " [${entry.address}]:${toString entry.port}"; + in + " LocalForward" + + addressPort f.bind + + addressPort f.host + ) cf.localForwards ++ mapAttrsToList (n: v: " ${n} ${v}") cf.extraOptions ); diff --git a/tests/modules/programs/ssh/match-blocks-attrs-expected.conf b/tests/modules/programs/ssh/match-blocks-attrs-expected.conf index 76bbe2e3..1bff480f 100644 --- a/tests/modules/programs/ssh/match-blocks-attrs-expected.conf +++ b/tests/modules/programs/ssh/match-blocks-attrs-expected.conf @@ -11,6 +11,7 @@ Host abc Host xyz ServerAliveInterval 60 IdentityFile file + LocalForward [localhost]:8080 [10.0.0.1]:80 Host * ForwardAgent no diff --git a/tests/modules/programs/ssh/match-blocks-attrs.nix b/tests/modules/programs/ssh/match-blocks-attrs.nix index cb554db2..3e09cd2d 100644 --- a/tests/modules/programs/ssh/match-blocks-attrs.nix +++ b/tests/modules/programs/ssh/match-blocks-attrs.nix @@ -15,6 +15,13 @@ with lib; xyz = { identityFile = "file"; serverAliveInterval = 60; + localForwards = [ + { + bind.port = 8080; + host.address = "10.0.0.1"; + host.port = 80; + } + ]; }; "* !github.com" = {