From 5770af8fd817ee5f096b0ffcc22d330af219a1cc Mon Sep 17 00:00:00 2001 From: Christopher League Date: Mon, 8 May 2017 23:30:37 -0400 Subject: [PATCH] Add programs.ssh module to generate .ssh/config This doesn't embed ALL the options for the ssh client, but I based it on options I use regularly. Here's an example usage extracted and edited from my home.nix: ```nix programs.ssh = { enable = true; forwardAgent = true; controlMaster = "auto"; hosts = { "something.blah.edu" = { port = 1024; user = "cleague"; identitiesOnly = true; }; "host1 host2 host2.net host2.com" = { port = 7422; hostname = "example.com"; serverAliveInterval = 60; }; "lucian" = { forwardX11 = true; forwardX11Trusted = true; checkHostIP = false; }; }; }; ``` --- modules/default.nix | 1 + modules/programs/ssh.nix | 146 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 modules/programs/ssh.nix diff --git a/modules/default.nix b/modules/default.nix index ebec6c96..e1f6b652 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -20,6 +20,7 @@ let ./programs/git.nix ./programs/gnome-terminal.nix ./programs/lesspipe.nix + ./programs/ssh.nix ./programs/texlive.nix ./services/dunst.nix ./services/gnome-keyring.nix diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix new file mode 100644 index 00000000..508d92b5 --- /dev/null +++ b/modules/programs/ssh.nix @@ -0,0 +1,146 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.ssh; + + yn = flag: if flag then "yes" else "no"; + + hostModule = types.submodule ({...}: { + options = { + + port = mkOption { + type = types.nullOr types.int; + default = null; + description = "Specifies port number to connect on remote host."; + }; + + forwardX11 = mkOption { + type = types.bool; + default = false; + description = '' + Specifies whether X11 connections will be automatically redirected + over the secure channel and DISPLAY set. + ''; + }; + + forwardX11Trusted = mkOption { + type = types.bool; + default = false; + description = '' + Specifies whether remote X11 clients will have full access to the + original X11 display. + ''; + }; + + identitiesOnly = mkOption { + type = types.bool; + default = false; + description = '' + Specifies that ssh should only use the authentication identity + explicitly configured in the .ssh/config files or passed on the + ssh command-line, even if ssh-agent offers more identities. + ''; + }; + + identityFile = mkOption { + type = types.nullOr types.string; + default = null; + description = '' + Specifies a file from which user's identity is read. + ''; + }; + + user = mkOption { + type = types.nullOr types.string; + default = null; + description = "Specifies the user to log in as."; + }; + + hostname = mkOption { + type = types.nullOr types.string; + default = null; + description = "Specifies the real host name to log into."; + }; + + serverAliveInterval = mkOption { + type = types.int; + default = 0; + description = + "Set timeout in seconds after which response will be requested."; + }; + + checkHostIP = mkOption { + type = types.bool; + default = true; + description = "Check that host IP address in the known_hosts file."; + }; + }; + }); + + hostStr = host: cf: concatStringsSep "\n" ( + ["Host ${host}"] + ++ optional (cf.port != null) " Port ${toString cf.port}" + ++ optional cf.forwardX11 " ForwardX11 yes" + ++ optional cf.forwardX11Trusted " ForwardX11Trusted yes" + ++ optional cf.identitiesOnly " IdentitiesOnly yes" + ++ optional (cf.user != null) " User ${cf.user}" + ++ optional (cf.identityFile != null) " IdentityFile ${cf.identityFile}" + ++ optional (cf.hostname != null) " HostName ${cf.hostname}" + ++ optional (cf.serverAliveInterval != 0) + " ServerAliveInterval ${toString cf.serverAliveInterval}" + ++ optional (!cf.checkHostIP) " CheckHostIP no" + ); + +in + +{ + options.programs.ssh = { + enable = mkEnableOption "SSH Client Configuration"; + + forwardAgent = mkOption { + default = false; + type = types.bool; + description = '' + Whether connection to authentication agent (if any) will be forwarded + to remote machine. + ''; + }; + + controlMaster = mkOption { + default = "no"; + type = types.enum ["yes" "no" "ask" "auto" "autoask"]; + description = '' + Configure sharing of multiple sessions over a single network connection. + ''; + }; + + controlPath = mkOption { + type = types.string; + default = "~/.ssh/master-%r@%h:%p"; + description = '' + Specify path to the control socket used for connection sharing. + ''; + }; + + hosts = mkOption { + type = types.attrsOf hostModule; + default = {}; + description = '' + Specify per-host settings. + ''; + }; + }; + + config = mkIf cfg.enable { + home.file.".ssh/config".text = '' + ForwardAgent ${yn cfg.forwardAgent} + ControlMaster ${cfg.controlMaster} + ControlPath ${cfg.controlPath} + + ${concatStringsSep "\n\n" (mapAttrsToList hostStr cfg.hosts)} + ''; + }; +}