about summary refs log tree commit diff
path: root/nixos/modules/system
diff options
context:
space:
mode:
authorDomen Kožar <domen@dev.si>2015-11-11 12:53:36 +0100
committerDomen Kožar <domen@dev.si>2015-11-11 12:53:36 +0100
commit505117f3fb261713d159a36f00b7aa7fae4e9bbe (patch)
tree8a33db721e7fbacac885145fa0a7484e8ec6be2b /nixos/modules/system
parent3d02d332b0633dba21888de5fabac7cd412cf468 (diff)
parent1e39eb4e00c262aa003868aed5d027a588fc28d6 (diff)
downloadnixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar.gz
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar.bz2
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar.lz
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar.xz
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.tar.zst
nixlib-505117f3fb261713d159a36f00b7aa7fae4e9bbe.zip
Merge branch 'master' into staging
Diffstat (limited to 'nixos/modules/system')
-rw-r--r--nixos/modules/system/boot/initrd-network.nix149
-rw-r--r--nixos/modules/system/boot/luksroot.nix26
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixos/modules/system/boot/stage-1.nix12
4 files changed, 182 insertions, 9 deletions
diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
new file mode 100644
index 000000000000..6c6e2fafad43
--- /dev/null
+++ b/nixos/modules/system/boot/initrd-network.nix
@@ -0,0 +1,149 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.boot.initrd.network;
+
+in
+{
+
+  options = {
+
+    boot.initrd.network.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Add network connectivity support to initrd.
+
+        Network options are configured via <literal>ip</literal> kernel
+        option, according to the kernel documentation.
+      '';
+    };
+
+    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.kernelModules = [ "af_packet" ];
+
+    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 = ''
+      # Search for interface definitions in command line
+      for o in $(cat /proc/cmdline); do
+        case $o in
+          ip=*)
+            ipconfig $o && hasNetwork=1
+            ;;
+        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
+    '';
+
+  };
+}
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 4a14ff1879c9..763703205630 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -32,9 +32,12 @@ let
     ''}
 
     open_normally() {
-        cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
+        echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
           ${optionalString (header != null) "--header=${header}"} \
-          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"}
+          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \
+          > /.luksopen_args
+        cryptsetup-askpass
+        rm /.luksopen_args
     }
 
     ${optionalString (luks.yubikeySupport && (yubikey != null)) ''
@@ -418,6 +421,18 @@ in
     boot.initrd.extraUtilsCommands = ''
       copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
 
+      cat > $out/bin/cryptsetup-askpass <<EOF
+      #!$out/bin/sh -e
+      if [ -e /.luksopen_args ]; then
+        cryptsetup \$(cat /.luksopen_args)
+        killall cryptsetup
+      else
+        echo "Passphrase is not requested now"
+        exit 1
+      fi
+      EOF
+      chmod +x $out/bin/cryptsetup-askpass
+
       ${optionalString luks.yubikeySupport ''
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
@@ -432,6 +447,8 @@ in
 
         cat > $out/bin/openssl-wrap <<EOF
         #!$out/bin/sh
+        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
+        $out/bin/openssl "\$@"
         EOF
         chmod +x $out/bin/openssl-wrap
       ''}
@@ -442,11 +459,6 @@ in
       ${optionalString luks.yubikeySupport ''
         $out/bin/ykchalresp -V
         $out/bin/ykinfo -V
-        cat > $out/bin/openssl-wrap <<EOF
-        #!$out/bin/sh
-        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
-        $out/bin/openssl "\$@"
-        EOF
         $out/bin/openssl-wrap version
       ''}
     '';
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 51828c5c090b..2b5d547353f8 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -149,6 +149,10 @@ 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 fe34e8227289..58a0749c74e2 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -104,7 +104,7 @@ let
       stripDirs "lib bin" "-s"
 
       # Run patchelf to make the programs refer to the copied libraries.
-      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done
+      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs -e $out $i; fi; done
 
       for i in $out/bin/*; do
           if ! test -L $i; then
@@ -203,7 +203,7 @@ let
     inherit (config.boot) resumeDevice devSize runSize;
 
     inherit (config.boot.initrd) checkJournalingFS
-      preLVMCommands postDeviceCommands postMountCommands kernelModules;
+      postEarlyDeviceCommands preLVMCommands 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);
@@ -313,6 +313,14 @@ 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;