google-compute-config: update config

Changed files
+47 -153
nixos
+6 -3
nixos/modules/security/google_oslogin.nix
···
let
cfg = config.security.googleOsLogin;
-
package = pkgs.google-compute-engine-oslogin;
+
package = pkgs.google-guest-oslogin;
in
···
type = types.bool;
default = false;
description = ''
-
Whether to enable Google OS Login
+
Whether to enable Google OS Login.
The OS Login package enables the following components:
AuthorizedKeysCommand to query valid SSH keys from the user's OS Login
···
security.pam.services.sshd = {
makeHomeDir = true;
googleOsLoginAccountVerification = true;
-
# disabled for now: googleOsLoginAuthentication = true;
+
googleOsLoginAuthentication = true;
};
security.sudo.extraConfig = ''
···
"d /run/google-sudoers.d 750 root root -"
"d /var/google-users.d 750 root root -"
];
+
+
systemd.packages = [ package ];
+
systemd.timers.google-oslogin-cache.wantedBy = [ "timers.target" ];
# enable the nss module, so user lookups etc. work
system.nssModules = [ package ];
+6 -6
nixos/modules/security/pam.nix
···
account sufficient ${pam_krb5}/lib/security/pam_krb5.so
'' +
optionalString cfg.googleOsLoginAccountVerification ''
-
account [success=ok ignore=ignore default=die] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so
-
account [success=ok default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so
+
account [success=ok ignore=ignore default=die] ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_login.so
+
account [success=ok default=ignore] ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_admin.so
'' +
''
# Authentication management.
'' +
optionalString cfg.googleOsLoginAuthentication ''
-
auth [success=done perm_denied=bad default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so
+
auth [success=done perm_denied=die default=ignore] ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_login.so
'' +
optionalString cfg.rootOK ''
auth sufficient pam_rootok.so
···
mr ${pam_ccreds}/lib/security/pam_ccreds.so,
'' +
optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
-
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
-
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so,
+
mr ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_login.so,
+
mr ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_admin.so,
'' +
optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication)) ''
-
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
+
mr ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_login.so,
'' +
optionalString (config.security.pam.enableSSHAgentAuth
&& isEnabled (cfg: cfg.sshAgentAuth)) ''
-36
nixos/modules/virtualisation/fetch-instance-ssh-keys.bash
···
-
#!/usr/bin/env bash
-
-
set -euo pipefail
-
-
WGET() {
-
wget --retry-connrefused -t 15 --waitretry=10 --header='Metadata-Flavor: Google' "$@"
-
}
-
-
# When dealing with cryptographic keys, we want to keep things private.
-
umask 077
-
mkdir -p /root/.ssh
-
-
echo "Fetching authorized keys..."
-
WGET -O /tmp/auth_keys http://metadata.google.internal/computeMetadata/v1/instance/attributes/sshKeys
-
-
# Read keys one by one, split in case Google decided
-
# to append metadata (it does sometimes) and add to
-
# authorized_keys if not already present.
-
touch /root/.ssh/authorized_keys
-
while IFS='' read -r line || [[ -n "$line" ]]; do
-
keyLine=$(echo -n "$line" | cut -d ':' -f2)
-
IFS=' ' read -r -a array <<<"$keyLine"
-
if [[ ${#array[@]} -ge 3 ]]; then
-
echo "${array[@]:0:3}" >>/tmp/new_keys
-
echo "Added ${array[*]:2} to authorized_keys"
-
fi
-
done </tmp/auth_keys
-
mv /tmp/new_keys /root/.ssh/authorized_keys
-
chmod 600 /root/.ssh/authorized_keys
-
-
echo "Fetching host keys..."
-
WGET -O /tmp/ssh_host_ed25519_key http://metadata.google.internal/computeMetadata/v1/instance/attributes/ssh_host_ed25519_key
-
WGET -O /tmp/ssh_host_ed25519_key.pub http://metadata.google.internal/computeMetadata/v1/instance/attributes/ssh_host_ed25519_key_pub
-
mv -f /tmp/ssh_host_ed25519_key* /etc/ssh/
-
chmod 600 /etc/ssh/ssh_host_ed25519_key
-
chmod 644 /etc/ssh/ssh_host_ed25519_key.pub
+31 -102
nixos/modules/virtualisation/google-compute-config.nix
···
{ config, lib, pkgs, ... }:
with lib;
-
let
-
gce = pkgs.google-compute-engine;
-
in
{
imports = [
../profiles/headless.nix
···
security.googleOsLogin.enable = true;
# Use GCE udev rules for dynamic disk volumes
-
services.udev.packages = [ gce ];
+
services.udev.packages = [ pkgs.google-guest-configs ];
+
services.udev.path = [ pkgs.google-guest-configs ];
# Force getting the hostname from Google Compute.
networking.hostName = mkDefault "";
# Always include cryptsetup so that NixOps can use it.
environment.systemPackages = [ pkgs.cryptsetup ];
-
-
# Make sure GCE image does not replace host key that NixOps sets
-
environment.etc."default/instance_configs.cfg".text = lib.mkDefault ''
-
[InstanceSetup]
-
set_host_keys = false
-
'';
# Rely on GCP's firewall instead
networking.firewall.enable = mkDefault false;
···
# GC has 1460 MTU
networking.interfaces.eth0.mtu = 1460;
-
# Used by NixOps
-
systemd.services.fetch-instance-ssh-keys = {
-
description = "Fetch host keys and authorized_keys for root user";
+
systemd.packages = [ pkgs.google-guest-agent ];
+
systemd.services.google-guest-agent = {
+
wantedBy = [ "multi-user.target" ];
+
restartTriggers = [ config.environment.etc."default/instance_configs.cfg".source ];
+
path = lib.optional config.users.mutableUsers pkgs.shadow;
+
};
+
systemd.services.google-startup-scripts.wantedBy = [ "multi-user.target" ];
+
systemd.services.google-shutdown-scripts.wantedBy = [ "multi-user.target" ];
-
wantedBy = [ "sshd.service" ];
-
before = [ "sshd.service" ];
-
after = [ "network-online.target" ];
-
wants = [ "network-online.target" ];
-
path = [ pkgs.wget ];
+
security.sudo.extraRules = mkIf config.users.mutableUsers [
+
{ groups = [ "google-sudoers" ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ]; }
+
];
-
serviceConfig = {
-
Type = "oneshot";
-
ExecStart = pkgs.runCommand "fetch-instance-ssh-keys" { } ''
-
cp ${./fetch-instance-ssh-keys.bash} $out
-
chmod +x $out
-
${pkgs.shfmt}/bin/shfmt -i 4 -d $out
-
${pkgs.shellcheck}/bin/shellcheck $out
-
patchShebangs $out
-
'';
-
PrivateTmp = true;
-
StandardError = "journal+console";
-
StandardOutput = "journal+console";
-
};
-
};
+
users.groups.google-sudoers = mkIf config.users.mutableUsers { };
-
systemd.services.google-instance-setup = {
-
description = "Google Compute Engine Instance Setup";
-
after = [ "network-online.target" "network.target" "rsyslog.service" ];
-
before = [ "sshd.service" ];
-
path = with pkgs; [ coreutils ethtool openssh ];
-
serviceConfig = {
-
ExecStart = "${gce}/bin/google_instance_setup";
-
StandardOutput="journal+console";
-
Type = "oneshot";
-
};
-
wantedBy = [ "sshd.service" "multi-user.target" ];
-
};
+
boot.extraModprobeConfig = lib.readFile "${pkgs.google-guest-configs}/etc/modprobe.d/gce-blacklist.conf";
-
systemd.services.google-network-daemon = {
-
description = "Google Compute Engine Network Daemon";
-
after = [ "network-online.target" "network.target" "google-instance-setup.service" ];
-
path = with pkgs; [ iproute2 ];
-
serviceConfig = {
-
ExecStart = "${gce}/bin/google_network_daemon";
-
StandardOutput="journal+console";
-
Type="simple";
-
};
-
wantedBy = [ "multi-user.target" ];
-
};
+
environment.etc."sysctl.d/60-gce-network-security.conf".source = "${pkgs.google-guest-configs}/etc/sysctl.d/60-gce-network-security.conf";
-
systemd.services.google-clock-skew-daemon = {
-
description = "Google Compute Engine Clock Skew Daemon";
-
after = [ "network.target" "google-instance-setup.service" "google-network-daemon.service" ];
-
serviceConfig = {
-
ExecStart = "${gce}/bin/google_clock_skew_daemon";
-
StandardOutput="journal+console";
-
Type = "simple";
-
};
-
wantedBy = ["multi-user.target"];
-
};
+
environment.etc."default/instance_configs.cfg".text = ''
+
[Accounts]
+
useradd_cmd = useradd -m -s /run/current-system/sw/bin/bash -p * {user}
+
[Daemons]
+
accounts_daemon = ${boolToString config.users.mutableUsers}
-
systemd.services.google-shutdown-scripts = {
-
description = "Google Compute Engine Shutdown Scripts";
-
after = [
-
"network-online.target"
-
"network.target"
-
"rsyslog.service"
-
"google-instance-setup.service"
-
"google-network-daemon.service"
-
];
-
serviceConfig = {
-
ExecStart = "${pkgs.coreutils}/bin/true";
-
ExecStop = "${gce}/bin/google_metadata_script_runner --script-type shutdown";
-
RemainAfterExit = true;
-
StandardOutput="journal+console";
-
TimeoutStopSec = "0";
-
Type = "oneshot";
-
};
-
wantedBy = [ "multi-user.target" ];
-
};
+
[InstanceSetup]
+
# Make sure GCE image does not replace host key that NixOps sets.
+
set_host_keys = false
-
systemd.services.google-startup-scripts = {
-
description = "Google Compute Engine Startup Scripts";
-
after = [
-
"network-online.target"
-
"network.target"
-
"rsyslog.service"
-
"google-instance-setup.service"
-
"google-network-daemon.service"
-
];
-
serviceConfig = {
-
ExecStart = "${gce}/bin/google_metadata_script_runner --script-type startup";
-
KillMode = "process";
-
StandardOutput = "journal+console";
-
Type = "oneshot";
-
};
-
wantedBy = [ "multi-user.target" ];
-
};
+
[MetadataScripts]
+
default_shell = ${pkgs.stdenv.shell}
-
environment.etc."sysctl.d/11-gce-network-security.conf".source = "${gce}/sysctl.d/11-gce-network-security.conf";
+
[NetworkInterfaces]
+
dhclient_script = ${pkgs.google-guest-configs}/bin/google-dhclient-script
+
# We set up network interfaces declaratively.
+
setup = false
+
'';
}
+2 -2
nixos/tests/google-oslogin/default.nix
···
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
server.succeed(
-
f'${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys {MOCKUSER} | grep -q "${snakeOilPublicKey}"'
+
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKUSER} | grep -q "${snakeOilPublicKey}"'
)
server.succeed(
-
f'${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys {MOCKADMIN} | grep -q "${snakeOilPublicKey}"'
+
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKADMIN} | grep -q "${snakeOilPublicKey}"'
)
# install snakeoil ssh key on the client, and provision .ssh/config file
+1 -3
nixos/tests/google-oslogin/server.nix
···
security.googleOsLogin.enable = true;
# Mock google service
-
networking.extraHosts = ''
-
127.0.0.1 metadata.google.internal
-
'';
+
networking.interfaces.lo.ipv4.addresses = [ { address = "169.254.169.254"; prefixLength = 32; } ];
}
nixos/tests/google-oslogin/server.py
+1 -1
nixos/tests/ssh-keys.nix
···
snakeOilPublicKey = pkgs.lib.concatStrings [
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
-
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil"
+
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= snakeoil"
];
}