1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-03-13 20:30:02 +00:00

support authorized_keys for users

This commit is contained in:
sbh69840 2023-05-09 15:57:49 +05:30
parent 379d42fad6
commit 64a15676ac
3 changed files with 74 additions and 9 deletions

View file

@ -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;

View file

@ -47,10 +47,56 @@ let
hostNames = mkDefault [ name ];
};
};
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}" {
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);
in
{
options = {
users.users = mkOption {
type = with types; attrsOf (submodule userOptions);
};
programs.ssh.knownHosts = mkOption {
default = {};
@ -80,12 +126,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 //
{ "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";
};
};
}

View file

@ -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 = ''
@ -63,7 +65,11 @@ in
for h in ''${etcSha256Hashes["$l"]}; do
if [ "$o" = "$h" ]; then
mv "$l" "$l.orig"
ln -s "$f" "$l"
if [ -e "$f".copy ]; then
cp "$f" "$l"
else
ln -s "$f" "$l"
fi
break
else
h=
@ -77,7 +83,11 @@ in
fi
fi
else
ln -s "$f" "$l"
if [ -e "$f".copy ]; then
cp "$f" "$l"
else
ln -s "$f" "$l"
fi
fi
done