* ssh: add generic Match support for matchBlocks
Introduce conservative support for actual `Match`
blocks in ssh config.
"Conservative" means this PR doesn'tt try to process
the `match` expression and simply uses it as a string
provided by the user.
If set, `match` has precedence over `host` meaning
if both are set, `match` is used and `host` is ignored.
* Add news entry
Attempting to build a flake configuration using `ssh.remoteForwards' results in
evaluation errors when `port' is undefined, as `!(entry ? port)' evaluates to
false. This was verified in the nix repl, and also occurs for `nix flake
check'.
Set optional attrs in `bindOptions' and `forwardModule' to `null' by default
and adjust the assertion to check for `null' instead of attr definitions.
This switches the type of `matchBlocks` from `loaOf` to `listOrDagOf`.
The former has been deprecated in Nixpkgs. The latter allows
dependencies between entries to be expressed using the DAG functions.
Instead of using the hostname `%h`, which can be changed by the
~/.ssh/config file, use the commandline-given hostname `%n`.
This allows to alias a host with different hostnames, which then point
to different configurations. A common use-case for this is if you have
multiple accounts on github with each access to different private repos:
Host github.com
IdentitiesOnly yes
User git
IdentityFile ~/.ssh/id_rsa
Host customer.github.com
IdentitiesOnly yes
User git
IdentityFile ~/.ssh/customer
HostName github.com
Without this change, if a connection was established with the first
github.com alias, then the user would try to pull a repo from the second
account, ssh would re-use the SSH connection which doesn't have access
to that repository.
This is needed to support overriding these options inside match
blocks. A new option `programs.ssh.extraOptionOverrides` has been
added to allow global overrides.
This module generates a `.ssh/config` file. This doesn't embed _all_
options for the ssh client, but the most common ones should be there.
Example usage:
```nix
programs.ssh = {
enable = true;
forwardAgent = true;
controlMaster = "auto";
matchBlocks = [
{
host = "something.blah.edu";
port = 1024;
user = "cleague";
identitiesOnly = true;
}
{
host = "host1 host2 host2.net host2.com";
port = 7422;
hostname = "example.com";
serverAliveInterval = 60;
}
{
host = "lucian";
forwardX11 = true;
forwardX11Trusted = true;
checkHostIP = false;
};
};
};
```
Each entry in `programs.ssh.matchBlocks` must contain a `host` field,
which will be used for the block condition.