summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorDomen Kožar <domen@dev.si>2023-05-15 11:59:31 +0100
committerGitHub <noreply@github.com>2023-05-15 11:59:31 +0100
commit0dbf1c2fb1a5a0372a324eff1ba44f9da66febd2 (patch)
tree535d771ee4325f365365e9093a04e411fe2480e8 /modules
parent252541bd05a7f55f3704a3d014ad1badc1e3360d (diff)
parent3d22883cdb4226306be7583f5513b3ca23a72e24 (diff)
Merge pull request #654 from shivaraj-bh/authorized-keys
Manage SSH authorized keys for users
Diffstat (limited to 'modules')
-rw-r--r--modules/lib/write-text.nix8
-rw-r--r--modules/programs/ssh/default.nix70
-rw-r--r--modules/system/etc.nix6
3 files changed, 77 insertions, 7 deletions
diff --git a/modules/lib/write-text.nix b/modules/lib/write-text.nix
index ddf4076..2fe02af 100644
--- a/modules/lib/write-text.nix
+++ b/modules/lib/write-text.nix
@@ -45,6 +45,14 @@ in
'';
};
+ copy = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether this file should be copied instead of symlinking.
+ '';
+ };
+
knownSha256Hashes = mkOption {
internal = true;
type = types.listOf types.str;
diff --git a/modules/programs/ssh/default.nix b/modules/programs/ssh/default.nix
index f93890f..f1dde9a 100644
--- a/modules/programs/ssh/default.nix
+++ b/modules/programs/ssh/default.nix
@@ -47,10 +47,65 @@ let
hostNames = mkDefault [ name ];
};
};
+ # Taken from: https://github.com/NixOS/nixpkgs/blob/f4aa6afa5f934ece2d1eb3157e392d056be01617/nixos/modules/services/networking/ssh/sshd.nix#L46-L93
+ userOptions = {
+
+ options.openssh.authorizedKeys = {
+ keys = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ A list of verbatim OpenSSH public keys that should be added to the
+ user's authorized keys. The keys are added to a file that the SSH
+ daemon reads in addition to the the user's authorized_keys file.
+ You can combine the <literal>keys</literal> and
+ <literal>keyFiles</literal> options.
+ Warning: If you are using <literal>NixOps</literal> then don't use this
+ option since it will replace the key required for deployment via ssh.
+ '';
+ };
+
+ keyFiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = ''
+ A list of files each containing one OpenSSH public key that should be
+ added to the user's authorized keys. The contents of the files are
+ read at build time and added to a file that the SSH daemon reads in
+ addition to the the user's authorized_keys file. You can combine the
+ <literal>keyFiles</literal> and <literal>keys</literal> options.
+ '';
+ };
+ };
+
+ };
+ authKeysFiles = let
+ mkAuthKeyFile = u: nameValuePair "ssh/authorized_keys.d/${u.name}" {
+ copy = true;
+ text = ''
+ ${concatStringsSep "\n" u.openssh.authorizedKeys.keys}
+ ${concatMapStrings (f: readFile f + "\n") u.openssh.authorizedKeys.keyFiles}
+ '';
+ };
+ usersWithKeys = attrValues (flip filterAttrs config.users.users (n: u:
+ length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
+ ));
+ in listToAttrs (map mkAuthKeyFile usersWithKeys);
+ authKeysConfiguration =
+ {
+ "ssh/sshd_config.d/101-authorized-keys.conf" = {
+ copy = true;
+ text = "AuthorizedKeysFile /etc/ssh/authorized_keys.d/%u\n";
+ };
+ };
in
{
options = {
+
+ users.users = mkOption {
+ type = with types; attrsOf (submodule userOptions);
+ };
programs.ssh.knownHosts = mkOption {
default = {};
@@ -80,12 +135,13 @@ in
(data.publicKey != null && data.publicKeyFile == null);
message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
});
-
- environment.etc."ssh/ssh_known_hosts".text = (flip (concatMapStringsSep "\n") knownHosts
- (h: assert h.hostNames != [];
- concatStringsSep "," h.hostNames + " "
- + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
- )) + "\n";
-
+
+ environment.etc = authKeysFiles // authKeysConfiguration //
+ { "ssh/ssh_known_hosts".text = (flip (concatMapStringsSep "\n") knownHosts
+ (h: assert h.hostNames != [];
+ concatStringsSep "," h.hostNames + " "
+ + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
+ )) + "\n";
+ };
};
}
diff --git a/modules/system/etc.nix b/modules/system/etc.nix
index cccb2b0..4b45e3a 100644
--- a/modules/system/etc.nix
+++ b/modules/system/etc.nix
@@ -12,6 +12,7 @@ let
hasDir = path: length (splitString "/" path) > 1;
etc = filter (f: f.enable) (attrValues config.environment.etc);
+ etcCopy = filter (f: f.copy) (attrValues config.environment.etc);
etcDirs = filter (attr: hasDir attr.target) (attrValues config.environment.etc);
in
@@ -38,6 +39,7 @@ in
cd $out/etc
${concatMapStringsSep "\n" (attr: "mkdir -p $(dirname '${attr.target}')") etc}
${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") etc}
+ ${concatMapStringsSep "\n" (attr: "touch '${attr.target}'.copy") etcCopy}
'';
system.activationScripts.etc.text = ''
@@ -55,6 +57,10 @@ in
if [ ! -e "$d" ]; then
mkdir -p "$d"
fi
+ if [ -e "$f".copy ]; then
+ cp "$f" "$l"
+ continue
+ fi
if [ -e "$l" ]; then
if [ "$(readlink "$l")" != "$f" ]; then
if ! grep -q /etc/static "$l"; then