From 901163c0c707d36323400394bf6e75adc4621e2f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Feb 2016 17:25:18 +0100 Subject: Split the initrd sshd support into a separate module Also, drop boot.initrd.postEarlyDeviceCommands since preLVMCommands should work fine. --- nixos/modules/system/boot/initrd-network.nix | 110 +++--------------------- nixos/modules/system/boot/initrd-ssh.nix | 124 +++++++++++++++++++++++++++ nixos/modules/system/boot/stage-1-init.sh | 9 +- nixos/modules/system/boot/stage-1.nix | 10 +-- 4 files changed, 141 insertions(+), 112 deletions(-) create mode 100644 nixos/modules/system/boot/initrd-ssh.nix (limited to 'nixos/modules/system/boot') diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix index 6c6e2fafad43..e1e49bce6938 100644 --- a/nixos/modules/system/boot/initrd-network.nix +++ b/nixos/modules/system/boot/initrd-network.nix @@ -3,9 +3,11 @@ with lib; let + cfg = config.boot.initrd.network; in + { options = { @@ -21,75 +23,15 @@ in ''; }; - boot.initrd.network.ssh.enable = mkOption { - type = types.bool; - default = false; - description = '' - Start SSH service during initrd boot. It can be used to debug failing - boot on a remote server, enter pasphrase for an encrypted partition etc. - Service is killed when stage-1 boot is finished. - ''; - }; - - boot.initrd.network.ssh.port = mkOption { - type = types.int; - default = 22; - description = '' - Port on which SSH initrd service should listen. - ''; - }; - - boot.initrd.network.ssh.shell = mkOption { - type = types.str; - default = "/bin/ash"; + boot.initrd.network.postCommands = mkOption { + default = ""; + type = types.lines; description = '' - Login shell of the remote user. Can be used to limit actions user can do. + Shell commands to be executed after stage 1 of the + boot has initialised the network. ''; }; - boot.initrd.network.ssh.hostRSAKey = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - RSA SSH private key file in the Dropbear format. - - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! - ''; - }; - - boot.initrd.network.ssh.hostDSSKey = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - DSS SSH private key file in the Dropbear format. - - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! - ''; - }; - - boot.initrd.network.ssh.hostECDSAKey = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - ECDSA SSH private key file in the Dropbear format. - - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! - ''; - }; - - boot.initrd.network.ssh.authorizedKeys = mkOption { - type = types.listOf types.str; - default = config.users.extraUsers.root.openssh.authorizedKeys.keys; - description = '' - Authorized keys for the root user on initrd. - ''; - }; }; @@ -99,17 +41,9 @@ in boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig - '' + optionalString cfg.ssh.enable '' - copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear - - cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib ''; - boot.initrd.extraUtilsCommandsTest = optionalString cfg.ssh.enable '' - $out/bin/dropbear -V - ''; - - boot.initrd.postEarlyDeviceCommands = '' + boot.initrd.preLVMCommands = '' # Search for interface definitions in command line for o in $(cat /proc/cmdline); do case $o in @@ -118,32 +52,10 @@ in ;; esac done - '' + optionalString cfg.ssh.enable '' - if [ -n "$hasNetwork" ]; then - mkdir /dev/pts - mount -t devpts devpts /dev/pts - - mkdir -p /etc - echo 'root:x:0:0:root:/root:${cfg.ssh.shell}' > /etc/passwd - echo '${cfg.ssh.shell}' > /etc/shells - echo 'passwd: files' > /etc/nsswitch.conf - - mkdir -p /var/log - touch /var/log/lastlog - - mkdir -p /etc/dropbear - ${optionalString (cfg.ssh.hostRSAKey != null) "ln -s ${cfg.ssh.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"} - ${optionalString (cfg.ssh.hostDSSKey != null) "ln -s ${cfg.ssh.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"} - ${optionalString (cfg.ssh.hostECDSAKey != null) "ln -s ${cfg.ssh.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"} - - mkdir -p /root/.ssh - ${concatStrings (map (key: '' - echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys - '') cfg.ssh.authorizedKeys)} - - dropbear -s -j -k -E -m -p ${toString cfg.ssh.port} - fi + + ${cfg.postCommands} ''; }; + } diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix new file mode 100644 index 000000000000..9f2fd4da9c4c --- /dev/null +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -0,0 +1,124 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.boot.initrd.network.ssh; + +in + +{ + + options = { + + boot.initrd.network.ssh.enable = mkOption { + type = types.bool; + default = false; + description = '' + Start SSH service during initrd boot. It can be used to debug failing + boot on a remote server, enter pasphrase for an encrypted partition etc. + Service is killed when stage-1 boot is finished. + ''; + }; + + boot.initrd.network.ssh.port = mkOption { + type = types.int; + default = 22; + description = '' + Port on which SSH initrd service should listen. + ''; + }; + + boot.initrd.network.ssh.shell = mkOption { + type = types.str; + default = "/bin/ash"; + description = '' + Login shell of the remote user. Can be used to limit actions user can do. + ''; + }; + + boot.initrd.network.ssh.hostRSAKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + RSA SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.hostDSSKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + DSS SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.hostECDSAKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + ECDSA SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.authorizedKeys = mkOption { + type = types.listOf types.str; + default = config.users.extraUsers.root.openssh.authorizedKeys.keys; + description = '' + Authorized keys for the root user on initrd. + ''; + }; + + }; + + config = mkIf cfg.enable { + + boot.initrd.extraUtilsCommands = '' + copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear + cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib + ''; + + boot.initrd.extraUtilsCommandsTest = '' + $out/bin/dropbear -V + ''; + + boot.initrd.network.postCommands = '' + if [ -n "$hasNetwork" ]; then + mkdir /dev/pts + mount -t devpts devpts /dev/pts + + echo '${cfg.shell}' > /etc/shells + + mkdir -p /var/log + touch /var/log/lastlog + + mkdir -p /etc/dropbear + ${optionalString (cfg.hostRSAKey != null) "ln -s ${cfg.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"} + ${optionalString (cfg.hostDSSKey != null) "ln -s ${cfg.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"} + ${optionalString (cfg.hostECDSAKey != null) "ln -s ${cfg.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"} + + mkdir -p /root/.ssh + ${concatStrings (map (key: '' + echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys + '') cfg.authorizedKeys)} + + dropbear -s -j -k -E -m -p ${toString cfg.port} + fi + ''; + + }; + +} diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index 7fb368e8c44f..c3d402eca042 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -72,6 +72,11 @@ mkdir -p /run mount -t tmpfs -o "mode=0755,size=@runSize@" tmpfs /run +# Initialise /etc. +echo 'root:x:0:0:root:/root:${cfg.shell}' > /etc/passwd +echo 'passwd: files' > /etc/nsswitch.conf + + # Process the kernel command line. export stage2Init=/init for o in $(cat /proc/cmdline); do @@ -150,10 +155,6 @@ udevadm trigger --action=add udevadm settle -# Additional devices initialization. -@postEarlyDeviceCommands@ - - # Load boot-time keymap before any LVM/LUKS initialization @extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@" diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index baa5bf6c69fd..98ef7ba024b4 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -199,7 +199,7 @@ let inherit (config.boot) resumeDevice devSize runSize; inherit (config.boot.initrd) checkJournalingFS - preLVMCommands preDeviceCommands postEarlyDeviceCommands postDeviceCommands postMountCommands kernelModules; + preLVMCommands preDeviceCommands postDeviceCommands postMountCommands kernelModules; resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}") (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices); @@ -318,14 +318,6 @@ in ''; }; - boot.initrd.postEarlyDeviceCommands = mkOption { - default = ""; - type = types.lines; - description = '' - Shell commands to be executed early after creation of device nodes. - ''; - }; - boot.initrd.postMountCommands = mkOption { default = ""; type = types.lines; -- cgit 1.4.1