nixpkgs/nixos/modules/virtualisation/ec2-data.nix
talyz bd35e1cb5f nixos/ec2-data: sshd.service -> sshd-keygen.service
SSH key generation was split out into its own systemd service in
https://github.com/NixOS/nixpkgs/pull/372979, but dependent service
definitions weren't updated.

The `apply-ec2-data` service needs to run before SSH key generation,
as it fetches host keys defined in ec2 user data and these keys should
take priority over generating new ones. Currently, the ordering
doesn't specify which should run first of `apply-ec2-data` and
`sshd-keygen`; in practice it seems that `sshd-keygen` often wins the
race, though.

Update the dependencies so that `apply-ec2-data` always runs first.

(cherry picked from commit d9ac3ba30b)
2025-09-20 09:05:48 +00:00

102 lines
3.2 KiB
Nix

# This module defines a systemd service that sets the SSH host key and
# authorized client key and host name of virtual machines running on
# Amazon EC2, Eucalyptus and OpenStack Compute (Nova).
{
config,
lib,
pkgs,
...
}:
with lib;
{
imports = [
(mkRemovedOptionModule [ "ec2" "metadata" ] "")
];
config = {
systemd.services.apply-ec2-data = {
description = "Apply EC2 Data";
wantedBy = [
"multi-user.target"
"sshd-keygen.service"
];
before = [ "sshd-keygen.service" ];
after = [ "fetch-ec2-metadata.service" ];
path = [ pkgs.iproute2 ];
script = ''
${optionalString (config.networking.hostName == "") ''
echo "setting host name..."
if [ -s /etc/ec2-metadata/hostname ]; then
${pkgs.nettools}/bin/hostname $(cat /etc/ec2-metadata/hostname)
fi
''}
if ! [ -e /root/.ssh/authorized_keys ]; then
echo "obtaining SSH key..."
mkdir -p /root/.ssh
chmod 0700 /root/.ssh
if [ -s /etc/ec2-metadata/public-keys-0-openssh-key ]; then
(umask 177; cat /etc/ec2-metadata/public-keys-0-openssh-key >> /root/.ssh/authorized_keys)
echo "new key added to authorized_keys"
fi
fi
# Extract the intended SSH host key for this machine from
# the supplied user data, if available. Otherwise sshd will
# generate one normally.
userData=/etc/ec2-metadata/user-data
mkdir -p /etc/ssh
chmod 0755 /etc/ssh
if [ -s "$userData" ]; then
key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' $userData)"
key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' $userData)"
if [ -n "$key" ] && [ -n "$key_pub" ] && [ ! -e /etc/ssh/ssh_host_dsa_key ]; then
(umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key)
echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
fi
key="$(sed 's/|/\n/g; s/SSH_HOST_ED25519_KEY://; t; d' $userData)"
key_pub="$(sed 's/SSH_HOST_ED25519_KEY_PUB://; t; d' $userData)"
if [ -n "$key" ] && [ -n "$key_pub" ] && [ ! -e /etc/ssh/ssh_host_ed25519_key ]; then
(umask 077; echo "$key" > /etc/ssh/ssh_host_ed25519_key)
echo "$key_pub" > /etc/ssh/ssh_host_ed25519_key.pub
fi
fi
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
};
systemd.services.print-host-key = {
description = "Print SSH Host Key";
wantedBy = [ "multi-user.target" ];
after = [ "sshd-keygen.service" ];
script = ''
# Print the host public key on the console so that the user
# can obtain it securely by parsing the output of
# ec2-get-console-output.
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console
for i in /etc/ssh/ssh_host_*_key.pub; do
${config.programs.ssh.package}/bin/ssh-keygen -l -f "$i" > /dev/console || true
done
echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
};
};
meta.maintainers = with maintainers; [ arianvp ];
}