diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index ce9353d58b35..0db7ee916baa 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -441,6 +441,7 @@
./system/activation/top-level.nix
./system/boot/coredump.nix
./system/boot/emergency-mode.nix
+ ./system/boot/initrd-network.nix
./system/boot/kernel.nix
./system/boot/kexec.nix
./system/boot/loader/efi.nix
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 ip 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 < $out/bin/openssl-wrap < $out/bin/openssl-wrap < $out/bin/nuke-refs < \$i.tmp
- if test -x \$i; then chmod +x \$i.tmp; fi
- mv \$i.tmp \$i
+
+excludes=""
+while getopts e: o; do
+ case "\$o" in
+ e) storeId=\$(echo "\$OPTARG" | sed -n "s|^$NIX_STORE/\\([a-z0-9]\{32\}\\)-.*|\1|p")
+ if [ -z "\$storeId" ]; then
+ echo "-e argument must be a Nix store path"
+ exit 1
+ fi
+ excludes="\$excludes(?!\$storeId)"
+ ;;
+ esac
+done
+shift \$((\$OPTIND-1))
+
+for i in "\$@"; do
+ if test ! -L "\$i" -a -f "\$i"; then
+ cat "\$i" | $perl/bin/perl -pe "s|$NIX_STORE/\$excludes[a-z0-9]{32}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" > "\$i.tmp"
+ if test -x "\$i"; then chmod +x "\$i.tmp"; fi
+ mv "\$i.tmp" "\$i"
fi
done
EOF
diff --git a/pkgs/build-support/nuke-references/default.nix b/pkgs/build-support/nuke-references/default.nix
index d672184553f6..8f976ad462cc 100644
--- a/pkgs/build-support/nuke-references/default.nix
+++ b/pkgs/build-support/nuke-references/default.nix
@@ -3,9 +3,10 @@
# path (/nix/store/eeee...). This is useful for getting rid of
# dependencies that you know are not actually needed at runtime.
-{stdenv}:
+{ stdenv, perl }:
stdenv.mkDerivation {
name = "nuke-references";
builder = ./builder.sh;
-}
\ No newline at end of file
+ inherit perl;
+}
diff --git a/pkgs/os-specific/linux/mkinitcpio-nfs-utils/default.nix b/pkgs/os-specific/linux/mkinitcpio-nfs-utils/default.nix
new file mode 100644
index 000000000000..f4e7ad1f2344
--- /dev/null
+++ b/pkgs/os-specific/linux/mkinitcpio-nfs-utils/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchurl, xz }:
+
+stdenv.mkDerivation rec {
+ name = "mkinitcpio-nfs-utils-0.3";
+
+ src = fetchurl {
+ url = "https://sources.archlinux.org/other/mkinitcpio/${name}.tar.xz";
+ sha256 = "0fc93sfk41ycpa33083kyd7i4y00ykpbhj5qlw611bjghj4x946j";
+ # ugh, upstream...
+ name = "${name}.tar.gz";
+ };
+
+ makeFlags = [ "DESTDIR=$(out)" "bindir=/bin" ];
+
+ postInstall = ''
+ rm -rf $out/usr
+ '';
+
+ meta = with stdenv.lib; {
+ homepage = https://archlinux.org/;
+ description = "ipconfig and nfsmount tools for root on NFS, ported from klibc";
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ abbradar ];
+ };
+}
diff --git a/pkgs/tools/networking/dropbear/default.nix b/pkgs/tools/networking/dropbear/default.nix
index 79a23ae38327..98ea4c82304b 100644
--- a/pkgs/tools/networking/dropbear/default.nix
+++ b/pkgs/tools/networking/dropbear/default.nix
@@ -35,9 +35,11 @@ stdenv.mkDerivation rec {
buildInputs = [ zlib ];
- meta = {
+ meta = with stdenv.lib; {
homepage = http://matt.ucc.asn.au/dropbear/dropbear.html;
description = "An small footprint implementation of the SSH 2 protocol";
- license = stdenv.lib.licenses.mit;
+ license = licenses.mit;
+ maintainers = with maintainers; [ abbradar ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/tools/networking/dropbear/pass-path.patch b/pkgs/tools/networking/dropbear/pass-path.patch
index 1e223e0ad64d..2ce08b05799d 100644
--- a/pkgs/tools/networking/dropbear/pass-path.patch
+++ b/pkgs/tools/networking/dropbear/pass-path.patch
@@ -1,31 +1,36 @@
diff --git a/svr-chansession.c b/svr-chansession.c
-index 23dad8c..32cac13 100644
+index e44299e..7ef750a 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
-@@ -823,6 +823,7 @@ static void addchildpid(struct ChanSess *chansess, pid_t pid) {
+@@ -893,6 +893,8 @@ static void addchildpid(struct ChanSess *chansess, pid_t pid) {
static void execchild(void *user_data) {
struct ChanSess *chansess = user_data;
char *usershell = NULL;
+ const char *path = DEFAULT_PATH;
++ const char *ldpath = NULL;
- /* with uClinux we'll have vfork()ed, so don't want to overwrite the
- * hostkey. can't think of a workaround to clear it */
-@@ -835,6 +836,9 @@ static void execchild(void *user_data) {
- reseedrandom();
+ /* with uClinux we'll have vfork()ed, so don't want to overwrite the
+ * hostkey. can't think of a workaround to clear it */
+@@ -905,6 +907,10 @@ static void execchild(void *user_data) {
+ seedrandom();
#endif
-+ if (getenv("PATH"))
-+ path = getenv("PATH");
++ if (getenv("PATH"))
++ path = getenv("PATH");
++ ldpath = getenv("LD_LIBRARY_PATH");
+
/* clear environment */
/* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD
* etc. This is hazardous, so should only be used for debugging. */
-@@ -878,7 +882,7 @@ static void execchild(void *user_data) {
+@@ -948,7 +954,10 @@ static void execchild(void *user_data) {
addnewvar("LOGNAME", ses.authstate.pw_name);
addnewvar("HOME", ses.authstate.pw_dir);
addnewvar("SHELL", get_user_shell());
- addnewvar("PATH", DEFAULT_PATH);
+ addnewvar("PATH", path);
++ if (ldpath != NULL) {
++ addnewvar("LD_LIBRARY_PATH", ldpath);
++ }
if (chansess->term != NULL) {
addnewvar("TERM", chansess->term);
}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index b0d5f22124f4..da80a4ee8cb4 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -10169,6 +10169,8 @@ let
systemd = systemd.override { enableKDbus = true; };
};
+ mkinitcpio-nfs-utils = callPackage ../os-specific/linux/mkinitcpio-nfs-utils { };
+
module_init_tools = callPackage ../os-specific/linux/module-init-tools { };
aggregateModules = modules: