google-compute-config: update config
This commit is contained in:
parent
077d0524cc
commit
524aecf61e
|
@ -5,7 +5,7 @@ with lib;
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.security.googleOsLogin;
|
cfg = config.security.googleOsLogin;
|
||||||
package = pkgs.google-compute-engine-oslogin;
|
package = pkgs.google-guest-oslogin;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ in
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Whether to enable Google OS Login
|
Whether to enable Google OS Login.
|
||||||
|
|
||||||
The OS Login package enables the following components:
|
The OS Login package enables the following components:
|
||||||
AuthorizedKeysCommand to query valid SSH keys from the user's OS Login
|
AuthorizedKeysCommand to query valid SSH keys from the user's OS Login
|
||||||
|
@ -36,7 +36,7 @@ in
|
||||||
security.pam.services.sshd = {
|
security.pam.services.sshd = {
|
||||||
makeHomeDir = true;
|
makeHomeDir = true;
|
||||||
googleOsLoginAccountVerification = true;
|
googleOsLoginAccountVerification = true;
|
||||||
# disabled for now: googleOsLoginAuthentication = true;
|
googleOsLoginAuthentication = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
security.sudo.extraConfig = ''
|
security.sudo.extraConfig = ''
|
||||||
|
@ -47,6 +47,9 @@ in
|
||||||
"d /var/google-users.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
|
# enable the nss module, so user lookups etc. work
|
||||||
system.nssModules = [ package ];
|
system.nssModules = [ package ];
|
||||||
system.nssDatabases.passwd = [ "cache_oslogin" "oslogin" ];
|
system.nssDatabases.passwd = [ "cache_oslogin" "oslogin" ];
|
||||||
|
|
|
@ -444,15 +444,15 @@ let
|
||||||
account sufficient ${pam_krb5}/lib/security/pam_krb5.so
|
account sufficient ${pam_krb5}/lib/security/pam_krb5.so
|
||||||
'' +
|
'' +
|
||||||
optionalString cfg.googleOsLoginAccountVerification ''
|
optionalString cfg.googleOsLoginAccountVerification ''
|
||||||
account [success=ok ignore=ignore default=die] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.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-compute-engine-oslogin}/lib/pam_oslogin_admin.so
|
account [success=ok default=ignore] ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_admin.so
|
||||||
'' +
|
'' +
|
||||||
''
|
''
|
||||||
|
|
||||||
# Authentication management.
|
# Authentication management.
|
||||||
'' +
|
'' +
|
||||||
optionalString cfg.googleOsLoginAuthentication ''
|
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 ''
|
optionalString cfg.rootOK ''
|
||||||
auth sufficient pam_rootok.so
|
auth sufficient pam_rootok.so
|
||||||
|
@ -1091,11 +1091,11 @@ in
|
||||||
mr ${pam_ccreds}/lib/security/pam_ccreds.so,
|
mr ${pam_ccreds}/lib/security/pam_ccreds.so,
|
||||||
'' +
|
'' +
|
||||||
optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
|
optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
|
||||||
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
|
mr ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_login.so,
|
||||||
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so,
|
mr ${pkgs.google-guest-oslogin}/lib/security/pam_oslogin_admin.so,
|
||||||
'' +
|
'' +
|
||||||
optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication)) ''
|
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
|
optionalString (config.security.pam.enableSSHAgentAuth
|
||||||
&& isEnabled (cfg: cfg.sshAgentAuth)) ''
|
&& isEnabled (cfg: cfg.sshAgentAuth)) ''
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/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
|
|
|
@ -1,8 +1,5 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
|
||||||
gce = pkgs.google-compute-engine;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../profiles/headless.nix
|
../profiles/headless.nix
|
||||||
|
@ -40,7 +37,8 @@ in
|
||||||
security.googleOsLogin.enable = true;
|
security.googleOsLogin.enable = true;
|
||||||
|
|
||||||
# Use GCE udev rules for dynamic disk volumes
|
# 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.
|
# Force getting the hostname from Google Compute.
|
||||||
networking.hostName = mkDefault "";
|
networking.hostName = mkDefault "";
|
||||||
|
@ -48,12 +46,6 @@ in
|
||||||
# Always include cryptsetup so that NixOps can use it.
|
# Always include cryptsetup so that NixOps can use it.
|
||||||
environment.systemPackages = [ pkgs.cryptsetup ];
|
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
|
# Rely on GCP's firewall instead
|
||||||
networking.firewall.enable = mkDefault false;
|
networking.firewall.enable = mkDefault false;
|
||||||
|
|
||||||
|
@ -69,105 +61,42 @@ in
|
||||||
# GC has 1460 MTU
|
# GC has 1460 MTU
|
||||||
networking.interfaces.eth0.mtu = 1460;
|
networking.interfaces.eth0.mtu = 1460;
|
||||||
|
|
||||||
# Used by NixOps
|
systemd.packages = [ pkgs.google-guest-agent ];
|
||||||
systemd.services.fetch-instance-ssh-keys = {
|
systemd.services.google-guest-agent = {
|
||||||
description = "Fetch host keys and authorized_keys for root user";
|
|
||||||
|
|
||||||
wantedBy = [ "sshd.service" ];
|
|
||||||
before = [ "sshd.service" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
path = [ pkgs.wget ];
|
|
||||||
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
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" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
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" ];
|
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" ];
|
||||||
|
|
||||||
systemd.services.google-clock-skew-daemon = {
|
security.sudo.extraRules = mkIf config.users.mutableUsers [
|
||||||
description = "Google Compute Engine Clock Skew Daemon";
|
{ groups = [ "google-sudoers" ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ]; }
|
||||||
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"];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
users.groups.google-sudoers = mkIf config.users.mutableUsers { };
|
||||||
|
|
||||||
systemd.services.google-shutdown-scripts = {
|
boot.extraModprobeConfig = lib.readFile "${pkgs.google-guest-configs}/etc/modprobe.d/gce-blacklist.conf";
|
||||||
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" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.google-startup-scripts = {
|
environment.etc."sysctl.d/60-gce-network-security.conf".source = "${pkgs.google-guest-configs}/etc/sysctl.d/60-gce-network-security.conf";
|
||||||
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" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."sysctl.d/11-gce-network-security.conf".source = "${gce}/sysctl.d/11-gce-network-security.conf";
|
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}
|
||||||
|
|
||||||
|
[InstanceSetup]
|
||||||
|
# Make sure GCE image does not replace host key that NixOps sets.
|
||||||
|
set_host_keys = false
|
||||||
|
|
||||||
|
[MetadataScripts]
|
||||||
|
default_shell = ${pkgs.stdenv.shell}
|
||||||
|
|
||||||
|
[NetworkInterfaces]
|
||||||
|
dhclient_script = ${pkgs.google-guest-configs}/bin/google-dhclient-script
|
||||||
|
# We set up network interfaces declaratively.
|
||||||
|
setup = false
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ in {
|
||||||
|
|
||||||
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
|
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
|
||||||
server.succeed(
|
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(
|
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
|
# install snakeoil ssh key on the client, and provision .ssh/config file
|
||||||
|
|
|
@ -23,7 +23,5 @@ in {
|
||||||
security.googleOsLogin.enable = true;
|
security.googleOsLogin.enable = true;
|
||||||
|
|
||||||
# Mock google service
|
# Mock google service
|
||||||
networking.extraHosts = ''
|
networking.interfaces.lo.ipv4.addresses = [ { address = "169.254.169.254"; prefixLength = 32; } ];
|
||||||
127.0.0.1 metadata.google.internal
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|
0
nixos/tests/google-oslogin/server.py
Normal file → Executable file
0
nixos/tests/google-oslogin/server.py
Normal file → Executable file
|
@ -10,6 +10,6 @@ pkgs:
|
||||||
snakeOilPublicKey = pkgs.lib.concatStrings [
|
snakeOilPublicKey = pkgs.lib.concatStrings [
|
||||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
|
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
|
||||||
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
|
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
|
||||||
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil"
|
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= snakeoil"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user