Jump to content

Remote disk unlocking: Difference between revisions

Properly escape greater than signs
imported>Onny
mNo edit summary
(Properly escape greater than signs)
 
(17 intermediate revisions by 7 users not shown)
Line 6: Line 6:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# ssh-keygen -t rsa -N "" -f /etc/secrets/initrd/ssh_host_rsa_key
# ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key
</syntaxhighlight>
</syntaxhighlight>


Line 12: Line 12:


{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
boot.kernelParams = [ "ip=dhcp" ];
boot.initrd = {
boot.initrd.network = {
   availableKernelModules = [ "r8169" ];
   enable = true;
   network = {
   ssh = {
     enable = true;
     enable = true;
     port = 22;
     udhcpc.enable = true;
     shell = "/bin/cryptsetup-askpass";
     flushBeforeStage2 = true;
     authorizedKeys = [ "ssh-rsa AAAAyourpublic-key-here..." ];
     ssh = {
    hostKeys = [ "/etc/secrets/initrd/ssh_host_rsa_key" ];
      enable = true;
      port = 22;
      authorizedKeys = [ "ssh-rsa AAAAyourpublic-key-here..." ];
      hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
    };
    postCommands = ''
      # Automatically ask for the password on SSH login
      echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1'</nowiki> >> <nowiki>/root/.profile
    '';
   };
   };
};
};
</nowiki>}}
</nowiki>}}


Add the SSH public keys for the users which should be able to authenticate to the SSH daemon to the <code>authorizedKeys</code> option.
Adapt following parts according to your setup


The <code>shell</code> option is necessary to get a password prompt instead of a shell.
* '''authorizedKeys''': Add the SSH public keys for the users which should be able to authenticate to the SSH daemon to the <code>authorizedKeys</code> option.
If you omit it, you will get dropped into <code>/bin/ash</code>, and you will have to manually run <code>cryptsetup-askpass</code> to enter the password.
* '''availableKernelModules''': Most likely your network card is not working without its kernel module being part of the initrd, so you have to find out which module is used for your network. Use <code>lspci -v | grep -iA8 'network\|ethernet'</code> for that.
* '''kernelParams''': Instead of using DHCP you could also configure a static IP, for example with kernel parameter <code>boot.kernelParams = [ "ip=10.25.0.2::10.25.0.1:255.255.255.0:myhost::none" ];</code>, where <code>10.25.0.2</code> is the client IP, <code>10.25.0.1</code> is the gateway IP. See [https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt the kernel documentation] for more information on the <code>ip=</code> parameter. When using DHCP, make sure your computer is always attached to the network and is able to get an IP adress, or the boot process will hang.


Alternatively, the <code>shell</code> option can be set to <code>/bin/conspy</code> for passwords which expect stdin. This binary included by default, and provided by busybox.


You will also need to configure either a static IP address or DHCP. You can do this with the <code>ip=</code> kernel parameter. See [https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt the kernel documentation] for more information on the <code>ip=</code> parameter.
The <code>postCommands</code> option is necessary to get a password prompt instead of a shell.
If you omit it, you will get dropped into <code>/bin/ash</code>, and you will have to manually run <code>cryptsetup-askpass</code> to enter the password. Alternatively, the <code>boot.initrd.systemd.users.root.shell</code> option can be set to <code>/bin/conspy</code> for passwords which expect stdin. This binary included by default, and provided by busybox.


=== Network card drivers ===
== Usage ==


Most likely your network card is not working without its kernel module being part of the initrd, so you have to find out which module is used for your network. Use <code>lspci -v | grep -iA8 'network\|ethernet'</code> for that.
After reboot, connect to the initrd SSH daemon using
 
<syntaxhighlight lang="bash">
# ssh root@10.25.0.2
</syntaxhighlight>


<pre>boot.initrd.availableKernelModules = [ &quot;r8169&quot; ];</pre>
Where <code>10.25.0.2</code> is the IP which is acquired via DHCP or configured via the kernel parameter.


== Tips and tricks ==
== Tips and tricks ==
=== Bcachefs unlocking ===
Unlocking encrypted Bcachefs root filesystems is [https://github.com/NixOS/nixpkgs/issues/291529 not yet supported]. As a workaround, following script, in combination with the setup above, can be used as SSH shell, to unlock the disk <code>/dev/vda2</code>.
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
boot.initrd.systemd = let
  askPass = pkgs.writeShellScriptBin "bcachefs-askpass" ''
    keyctl link @u @s
    mkdir /sysroot
    until bcachefs mount /dev/vda2 /sysroot
    do
      sleep  1
    done
  '';
in {
  enable = true;
  initrdBin = with pkgs; [ keyutils ];
  storePaths = ["${askPass}/bin/bcachefs-askpass"];
  users.root.shell = "${askPass}/bin/bcachefs-askpass";
};
</nowiki>}}
Using systemd in initrd automatically continues the boot process after the target <code>/sysroot</code> is mounted.


=== Tor in initrd ===
=== Tor in initrd ===
Line 79: Line 115:
Now that you have your 3 files, you have to script a bit, but it’s not too complicated.
Now that you have your 3 files, you have to script a bit, but it’s not too complicated.


<pre># copy your onion folder
<syntaxhighlight lang="nix"># copy your onion folder
boot.initrd.secrets = {
boot.initrd.secrets = {
   &quot;/etc/tor/onion/bootup&quot; = /home/tony/tor/onion; # maybe find a better spot to store this.
   "/etc/tor/onion/bootup"; = /home/tony/tor/onion; # maybe find a better spot to store this.
};
};


Line 91: Line 127:
# start tor during boot process
# start tor during boot process
boot.initrd.network.postCommands = let
boot.initrd.network.postCommands = let
   torRc = (pkgs.writeText &quot;tor.rc&quot; ''
   torRc = (pkgs.writeText "tor.rc" ''
     DataDirectory /etc/tor
     DataDirectory /etc/tor
     SOCKSPort 127.0.0.1:9050 IsolateDestAddr
     SOCKSPort 127.0.0.1:9050 IsolateDestAddr
Line 99: Line 135:
   '');
   '');
in ''
in ''
   echo &quot;tor: preparing onion folder&quot;
   echo "tor: preparing onion folder"
   # have to do this otherwise tor does not want to start
   # have to do this otherwise tor does not want to start
   chmod -R 700 /etc/tor
   chmod -R 700 /etc/tor


   echo &quot;make sure localhost is up&quot;
   echo "make sure localhost is up"
   ip a a 127.0.0.1/8 dev lo
   ip a a 127.0.0.1/8 dev lo
   ip link set lo up
   ip link set lo up


   echo &quot;tor: starting tor&quot;
   echo "tor: starting tor"
   tor -f ${torRc} --verify-config
   tor -f ${torRc} --verify-config
   tor -f ${torRc} &amp;
   tor -f ${torRc} &
'';</pre>
'';</syntaxhighlight>
That was it. Tor should be running during your boot process.
That was it. Tor should be running during your boot process.


Line 122: Line 158:
</pre>
</pre>


Then use this snippet before <code>echo &quot;tor: starting tor&quot;</code> in your <code>boot.initrd.network.postCommands</code>.
Then use this snippet before <code>echo "tor: starting tor"</code> in your <code>boot.initrd.network.postCommands</code>.
<pre>
<pre>
       echo "haveged: starting haveged"
       echo "haveged: starting haveged"
Line 137: Line 173:
</pre>
</pre>


Then use this snippet before <code>echo &quot;tor: starting tor&quot;</code> in your <code>boot.initrd.network.postCommands</code>.
Then use this snippet before <code>echo "tor: starting tor"</code> in your <code>boot.initrd.network.postCommands</code>.
<pre>
<pre>
       echo "ntp: starting ntpdate"
       echo "ntp: starting ntpdate"
Line 149: Line 185:
When your computer boots, and asks for the LUKS password. Now you can unlock your encrypted Hard drive using:
When your computer boots, and asks for the LUKS password. Now you can unlock your encrypted Hard drive using:


<pre>torify ssh root@&lt;onion.id&gt;.onion -p 22 'my-secret-password'</pre>
<pre>torify ssh root@<onion.id>.onion -p 22 'my-secret-password'</pre>
 
=== Enable Wifi in initrd ===
Following example configuration by [https://discourse.nixos.org/t/wireless-connection-within-initrd/38317/13 @loutr] enables wifi connections inside initrd. Replace interface name <code>wlp0s20f0u4</code> with the name of your wifi adapter. Depending on your wifi device, you might need to add different kernel modules.<syntaxhighlight lang="nix">
boot.initrd = {
  # crypto coprocessor and wifi modules
  availableKernelModules = [ "ccm" "ctr" "iwlmvm" "iwlwifi" ];
 
  systemd = {
    enable = true;
 
    packages = [ pkgs.wpa_supplicant ];
    initrdBin = [ pkgs.wpa_supplicant ];
    targets.initrd.wants = [ "wpa_supplicant@wlp0s20f0u4.service" ];
 
    # prevent WPA supplicant from requiring `sysinit.target`.
    services."wpa_supplicant@".unitConfig.DefaultDependencies = false;
 
    users.root.shell = "/bin/systemd-tty-ask-password-agent";
 
    network = {
      enable = true;
      networks."10-wlan" = {
        matchConfig.Name = "wlp0s20f0u4";
        networkConfig.DHCP = "yes";
      };
      ssh = {
        enable = true;
        port = 22;
        hostKeys = [ "/etc/ssh/ssh_host_ed25519_key" ];
        authorizedKeys = default.user.openssh.authorizedKeys.keys;
      };
    };
 
    secrets."/etc/wpa_supplicant/wpa_supplicant-wlp0s20f0u4.conf" = /root/secrets/wpa_supplicant.conf;
 
  };
</syntaxhighlight>The file <code>wpa_supplicat-wlp0s20f0u4.conf</code> is the wireless profile used by [[wpa_supplicant]] which will get copied into the initramfs.
[[Category:Server]]
[[Category:Cookbook]]
3

edits