nixos/tests/initrd-openvpn: Add test for openvpn in the initramfs
The module in this commit adds new options that allows the
integration of an OpenVPN client into the initrd.
This can be used e.g. to remotely unlock LUKS devices.
This commit also adds two tests for `boot.initrd.network.openvpn`.
The first one is a basic test to validate that a failing connection
does not prevent the machine from booting.
The second test validates that this module actually creates a valid
openvpn connection.
For this, it spawns three nodes:
  - The client that uses boot.initrd.network.openvpn
  - An OpenVPN server that acts as gateway and forwards a port
    to the client
  - A node that is external to the OpenVPN network
The client connects to the OpenVPN server and spawns a netcat instance
that echos a value to every client.
Afterwards, the external node checks if it receives this value over the
forwarded port on the OpenVPN gateway.
		
	
			
		
			
				
	
	
		
			82 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
with lib;
 | 
						|
 | 
						|
let
 | 
						|
 | 
						|
  cfg = config.boot.initrd.network.openvpn;
 | 
						|
  
 | 
						|
in
 | 
						|
 | 
						|
{
 | 
						|
 | 
						|
  options = {
 | 
						|
 | 
						|
    boot.initrd.network.openvpn.enable = mkOption {
 | 
						|
      type = types.bool;
 | 
						|
      default = false;
 | 
						|
      description = ''
 | 
						|
        Starts an OpenVPN client during initrd boot. It can be used to e.g. 
 | 
						|
        remotely accessing the SSH service controlled by 
 | 
						|
        <option>boot.initrd.network.ssh</option> or other network services 
 | 
						|
        included. Service is killed when stage-1 boot is finished.
 | 
						|
      '';
 | 
						|
    };
 | 
						|
    
 | 
						|
    boot.initrd.network.openvpn.configuration = mkOption {
 | 
						|
      type = types.path; # Same type as boot.initrd.secrets
 | 
						|
      description = ''
 | 
						|
        The configuration file for OpenVPN. 
 | 
						|
 | 
						|
        <warning>
 | 
						|
          <para>
 | 
						|
            Unless your bootloader supports initrd secrets, this configuration
 | 
						|
            is stored insecurely in the global Nix store.
 | 
						|
          </para>
 | 
						|
        </warning>
 | 
						|
      '';
 | 
						|
      example = "./configuration.ovpn";
 | 
						|
    };
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
  config = mkIf (config.boot.initrd.network.enable && cfg.enable) {
 | 
						|
    assertions = [
 | 
						|
      {
 | 
						|
        assertion = cfg.configuration != null;
 | 
						|
        message = "You should specify a configuration for initrd OpenVPN";
 | 
						|
      }
 | 
						|
    ];
 | 
						|
    
 | 
						|
    # Add kernel modules needed for OpenVPN
 | 
						|
    boot.initrd.kernelModules = [ "tun" "tap" ];
 | 
						|
 | 
						|
    # Add openvpn and ip binaries to the initrd
 | 
						|
    # The shared libraries are required for DNS resolution
 | 
						|
    boot.initrd.extraUtilsCommands = ''
 | 
						|
      copy_bin_and_libs ${pkgs.openvpn}/bin/openvpn
 | 
						|
      copy_bin_and_libs ${pkgs.iproute}/bin/ip
 | 
						|
 | 
						|
      cp -pv ${pkgs.glibc}/lib/libresolv.so.2 $out/lib
 | 
						|
      cp -pv ${pkgs.glibc}/lib/libnss_dns.so.2 $out/lib
 | 
						|
    '';
 | 
						|
    
 | 
						|
    boot.initrd.secrets = {
 | 
						|
      "/etc/initrd.ovpn" = cfg.configuration;
 | 
						|
    };
 | 
						|
    
 | 
						|
    # openvpn --version would exit with 1 instead of 0
 | 
						|
    boot.initrd.extraUtilsCommandsTest = ''
 | 
						|
      $out/bin/openvpn --show-gateway
 | 
						|
    '';
 | 
						|
 | 
						|
    # Add `iproute /bin/ip` to the config, to ensure that openvpn
 | 
						|
    # is able to set the routes
 | 
						|
    boot.initrd.network.postCommands = ''
 | 
						|
      (cat /etc/initrd.ovpn; echo -e '\niproute /bin/ip') | \
 | 
						|
        openvpn /dev/stdin &
 | 
						|
    '';
 | 
						|
  };
 | 
						|
 | 
						|
}
 |