From e7684e34ec6b2c469f11dafc8759db4ef5e8431d Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Fri, 16 Oct 2015 20:33:51 +0300 Subject: [PATCH 1/8] mkinitcpio-nfs-utils: init at 0.3 --- .../linux/mkinitcpio-nfs-utils/default.nix | 26 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 pkgs/os-specific/linux/mkinitcpio-nfs-utils/default.nix 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/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 95a17101120b..83d5fe9ce917 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10063,6 +10063,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: From 919762e4bdc97694420f247328b6398f1d5e4f17 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Sat, 17 Oct 2015 13:24:17 +0300 Subject: [PATCH 2/8] dropbear: adopt --- pkgs/tools/networking/dropbear/default.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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; }; } From 8f967a3056f58739329e28f3612e695d3938e989 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Fri, 16 Oct 2015 21:16:13 +0300 Subject: [PATCH 3/8] nixos/stage-1: add postEarlyDeviceCommands hook --- nixos/modules/system/boot/stage-1-init.sh | 4 ++++ nixos/modules/system/boot/stage-1.nix | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) 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 ace2d10ec9c1..4399123f0c3c 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -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) 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; From cdc7e23e38caa11d42612734b90bf033619b2822 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Sun, 18 Oct 2015 18:29:46 +0300 Subject: [PATCH 4/8] dropbear: pass LD_LIBRARY_PATH through --- .../tools/networking/dropbear/pass-path.patch | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) 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); } From c81fb457c9f505c8093000f522df24b7482d0cb7 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Fri, 16 Oct 2015 20:35:18 +0300 Subject: [PATCH 5/8] nixos/initrd-network: add new module --- nixos/modules/module-list.nix | 1 + nixos/modules/system/boot/initrd-network.nix | 149 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 nixos/modules/system/boot/initrd-network.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2dafd19e0b47..fc95f7a8e914 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -436,6 +436,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 + ''; + + }; +} From 3c7871a1c027da0b22c8b280944e374273f2874b Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Sun, 18 Oct 2015 17:53:29 +0300 Subject: [PATCH 6/8] nuke-references: support -e option --- pkgs/build-support/nuke-references/builder.sh | 25 +++++++++++++++---- .../build-support/nuke-references/default.nix | 5 ++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pkgs/build-support/nuke-references/builder.sh b/pkgs/build-support/nuke-references/builder.sh index 9e8c464d8288..02eac664d437 100644 --- a/pkgs/build-support/nuke-references/builder.sh +++ b/pkgs/build-support/nuke-references/builder.sh @@ -3,11 +3,26 @@ source $stdenv/setup mkdir -p $out/bin cat > $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; +} From 1bd3d9de2acf17e4b727cbf4d1487d5ad5e42159 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Sun, 18 Oct 2015 17:55:28 +0300 Subject: [PATCH 7/8] nixos/luksroot: use 'nuke-refs -e' option to simplify things --- nixos/modules/system/boot/luksroot.nix | 7 ++----- nixos/modules/system/boot/stage-1.nix | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 4a14ff1879c9..0a680b2d5cf2 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -432,6 +432,8 @@ in cat > $out/bin/openssl-wrap < $out/bin/openssl-wrap < Date: Sun, 18 Oct 2015 13:50:36 +0300 Subject: [PATCH 8/8] nixos/luksroot: allow to enter passphrase from another console --- nixos/modules/system/boot/luksroot.nix | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 0a680b2d5cf2..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 <