mirror of
https://github.com/LnL7/nix-darwin.git
synced 2025-03-13 20:30:02 +00:00
Merge pull request #654 from shivaraj-bh/authorized-keys
Manage SSH authorized keys for users
This commit is contained in:
commit
0dbf1c2fb1
4 changed files with 83 additions and 7 deletions
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,9 +6,15 @@
|
|||
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
|
||||
};
|
||||
};
|
||||
users.users.foo.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA..." ];
|
||||
|
||||
test = ''
|
||||
echo >&2 "checking for github.com in /etc/ssh/ssh_known_hosts"
|
||||
grep 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' ${config.out}/etc/ssh/ssh_known_hosts
|
||||
|
||||
echo >&2 "checking for authorized keys for foo in /etc/ssh/authorized_keys.d/foo"
|
||||
grep 'ssh-ed25519 AAAA...' ${config.out}/etc/ssh/authorized_keys.d/foo
|
||||
echo >&2 "checking for authorized keys' path in /etc/ssh/sshd_config.d/101-authorized-keys.conf"
|
||||
grep 'AuthorizedKeysFile /etc/ssh/authorized_keys.d/%u' ${config.out}/etc/ssh/sshd_config.d/101-authorized-keys.conf
|
||||
'';
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue