1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.boot.initrd.network.ssh; 8 9in 10 11{ 12 13 options = { 14 15 boot.initrd.network.ssh.enable = mkOption { 16 type = types.bool; 17 default = false; 18 description = '' 19 Start SSH service during initrd boot. It can be used to debug failing 20 boot on a remote server, enter pasphrase for an encrypted partition etc. 21 Service is killed when stage-1 boot is finished. 22 ''; 23 }; 24 25 boot.initrd.network.ssh.port = mkOption { 26 type = types.int; 27 default = 22; 28 description = '' 29 Port on which SSH initrd service should listen. 30 ''; 31 }; 32 33 boot.initrd.network.ssh.shell = mkOption { 34 type = types.str; 35 default = "/bin/ash"; 36 description = '' 37 Login shell of the remote user. Can be used to limit actions user can do. 38 ''; 39 }; 40 41 boot.initrd.network.ssh.hostRSAKey = mkOption { 42 type = types.nullOr types.path; 43 default = null; 44 description = '' 45 RSA SSH private key file in the Dropbear format. 46 47 WARNING: This key is contained insecurely in the global Nix store. Do NOT 48 use your regular SSH host private keys for this purpose or you'll expose 49 them to regular users! 50 ''; 51 }; 52 53 boot.initrd.network.ssh.hostDSSKey = mkOption { 54 type = types.nullOr types.path; 55 default = null; 56 description = '' 57 DSS SSH private key file in the Dropbear format. 58 59 WARNING: This key is contained insecurely in the global Nix store. Do NOT 60 use your regular SSH host private keys for this purpose or you'll expose 61 them to regular users! 62 ''; 63 }; 64 65 boot.initrd.network.ssh.hostECDSAKey = mkOption { 66 type = types.nullOr types.path; 67 default = null; 68 description = '' 69 ECDSA SSH private key file in the Dropbear format. 70 71 WARNING: This key is contained insecurely in the global Nix store. Do NOT 72 use your regular SSH host private keys for this purpose or you'll expose 73 them to regular users! 74 ''; 75 }; 76 77 boot.initrd.network.ssh.authorizedKeys = mkOption { 78 type = types.listOf types.str; 79 default = config.users.extraUsers.root.openssh.authorizedKeys.keys; 80 description = '' 81 Authorized keys for the root user on initrd. 82 ''; 83 }; 84 85 }; 86 87 config = mkIf (config.boot.initrd.network.enable && cfg.enable) { 88 89 boot.initrd.extraUtilsCommands = '' 90 copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear 91 cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib 92 ''; 93 94 boot.initrd.extraUtilsCommandsTest = '' 95 $out/bin/dropbear -V 96 ''; 97 98 boot.initrd.network.postCommands = '' 99 mkdir /dev/pts 100 mount -t devpts devpts /dev/pts 101 102 echo '${cfg.shell}' > /etc/shells 103 echo 'root:x:0:0:root:/root:${cfg.shell}' > /etc/passwd 104 echo 'passwd: files' > /etc/nsswitch.conf 105 106 mkdir -p /var/log 107 touch /var/log/lastlog 108 109 mkdir -p /etc/dropbear 110 ${optionalString (cfg.hostRSAKey != null) "ln -s ${cfg.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"} 111 ${optionalString (cfg.hostDSSKey != null) "ln -s ${cfg.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"} 112 ${optionalString (cfg.hostECDSAKey != null) "ln -s ${cfg.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"} 113 114 mkdir -p /root/.ssh 115 ${concatStrings (map (key: '' 116 echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys 117 '') cfg.authorizedKeys)} 118 119 dropbear -s -j -k -E -m -p ${toString cfg.port} 120 ''; 121 122 }; 123 124}