nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
fork

Configure Feed

Select the types of activity you want to include in your feed.

nixos/test-driver: add backdoor based on systemd-ssh-proxy & AF_VSOCK (#392030)

authored by

Jacek Galowicz and committed by
GitHub
8b3baa14 907e98d6

+100 -4
+29
nixos/doc/manual/development/running-nixos-tests-interactively.section.md
··· 63 63 Once the connection is established, you can enter commands in the socat terminal 64 64 where socat is running. 65 65 66 + ## SSH Access for test machines {#sec-nixos-test-ssh-access} 67 + 68 + An SSH-based backdoor to log into machines can be enabled with 69 + 70 + ```nix 71 + { 72 + name = "…"; 73 + nodes.machines = { /* … */ }; 74 + sshBackdoor.enable = true; 75 + } 76 + ``` 77 + 78 + This creates a [vsock socket](https://man7.org/linux/man-pages/man7/vsock.7.html) 79 + for each VM to log in with SSH. This configures root login with an empty password. 80 + 81 + When the VMs get started interactively with the test-driver, it's possible to 82 + connect to `machine` with 83 + 84 + ``` 85 + $ ssh vsock/3 -o User=root 86 + ``` 87 + 88 + The socket numbers correspond to the node number of the test VM, but start 89 + at three instead of one because that's the lowest possible 90 + vsock number. 91 + 92 + On non-NixOS systems you'll probably need to enable 93 + the SSH config from {manpage}`systemd-ssh-proxy(1)` yourself. 94 + 66 95 ## Port forwarding to NixOS test VMs {#sec-nixos-test-port-forwarding} 67 96 68 97 If your test has only a single VM, you may use e.g.
+6
nixos/doc/manual/redirects.json
··· 1823 1823 "sec-test-options-reference": [ 1824 1824 "index.html#sec-test-options-reference" 1825 1825 ], 1826 + "test-opt-sshBackdoor.enable": [ 1827 + "index.html#test-opt-sshBackdoor.enable" 1828 + ], 1826 1829 "test-opt-defaults": [ 1827 1830 "index.html#test-opt-defaults" 1828 1831 ], ··· 1912 1909 ], 1913 1910 "sec-nixos-test-shell-access": [ 1914 1911 "index.html#sec-nixos-test-shell-access" 1912 + ], 1913 + "sec-nixos-test-ssh-access": [ 1914 + "index.html#sec-nixos-test-ssh-access" 1915 1915 ], 1916 1916 "sec-nixos-test-port-forwarding": [ 1917 1917 "index.html#sec-nixos-test-port-forwarding"
+7
nixos/lib/test-driver/src/test_driver/__init__.py
··· 109 109 help="the test script to run", 110 110 type=Path, 111 111 ) 112 + arg_parser.add_argument( 113 + "--dump-vsocks", 114 + help="indicates that the interactive SSH backdoor is active and dumps information about it on start", 115 + action="store_true", 116 + ) 112 117 113 118 args = arg_parser.parse_args() 114 119 ··· 141 136 if args.interactive: 142 137 history_dir = os.getcwd() 143 138 history_path = os.path.join(history_dir, ".nixos-test-history") 139 + if args.dump_vsocks: 140 + driver.dump_machine_ssh() 144 141 ptpython.ipython.embed( 145 142 user_ns=driver.test_symbols(), 146 143 history_filename=history_path,
+15
nixos/lib/test-driver/src/test_driver/driver.py
··· 11 11 from typing import Any 12 12 from unittest import TestCase 13 13 14 + from colorama import Style 15 + 14 16 from test_driver.errors import MachineError, RequestedAssertionFailed 15 17 from test_driver.logger import AbstractLogger 16 18 from test_driver.machine import Machine, NixStartScript, retry ··· 177 175 + ", ".join(list(general_symbols.keys())) 178 176 ) 179 177 return {**general_symbols, **machine_symbols, **vlan_symbols} 178 + 179 + def dump_machine_ssh(self) -> None: 180 + print("SSH backdoor enabled, the machines can be accessed like this:") 181 + print( 182 + f"{Style.BRIGHT}Note:{Style.RESET_ALL} this requires {Style.BRIGHT}systemd-ssh-proxy(1){Style.RESET_ALL} to be enabled (default on NixOS 25.05 and newer)." 183 + ) 184 + names = [machine.name for machine in self.machines] 185 + longest_name = len(max(names, key=len)) 186 + for num, name in enumerate(names, start=3): 187 + spaces = " " * (longest_name - len(name) + 2) 188 + print( 189 + f" {name}:{spaces}{Style.BRIGHT}ssh -o User=root vsock/{num}{Style.RESET_ALL}" 190 + ) 180 191 181 192 def test_script(self) -> None: 182 193 """Run the test script"""
+1
nixos/lib/testing-python.nix
··· 75 75 ), 76 76 extraPythonPackages ? (_: [ ]), 77 77 interactive ? { }, 78 + sshBackdoor ? { }, 78 79 }@t: 79 80 let 80 81 testConfig =
+22 -4
nixos/lib/testing/nodes.nix
··· 13 13 mapAttrs 14 14 mkDefault 15 15 mkIf 16 + mkMerge 16 17 mkOption 17 18 mkForce 18 19 optional ··· 78 77 { 79 78 80 79 options = { 80 + sshBackdoor = { 81 + enable = mkOption { 82 + default = false; 83 + type = types.bool; 84 + description = "Whether to turn on the VSOCK-based access to all VMs. This provides an unauthenticated access intended for debugging."; 85 + }; 86 + }; 87 + 81 88 node.type = mkOption { 82 89 type = types.raw; 83 90 default = baseOS.type; ··· 181 172 182 173 passthru.nodes = config.nodesCompat; 183 174 184 - defaults = mkIf config.node.pkgsReadOnly { 185 - nixpkgs.pkgs = config.node.pkgs; 186 - imports = [ ../../modules/misc/nixpkgs/read-only.nix ]; 187 - }; 175 + extraDriverArgs = mkIf config.sshBackdoor.enable [ 176 + "--dump-vsocks" 177 + ]; 178 + 179 + defaults = mkMerge [ 180 + (mkIf config.node.pkgsReadOnly { 181 + nixpkgs.pkgs = config.node.pkgs; 182 + imports = [ ../../modules/misc/nixpkgs/read-only.nix ]; 183 + }) 184 + (mkIf config.sshBackdoor.enable { 185 + testing.sshBackdoor.enable = true; 186 + }) 187 + ]; 188 188 189 189 }; 190 190 }
+20
nixos/modules/testing/test-instrumentation.nix
··· 87 87 machine.switch_root() to leave stage 1 and proceed to stage 2 88 88 ''; 89 89 90 + sshBackdoor = { 91 + enable = mkEnableOption "vsock-based ssh backdoor for the VM"; 92 + }; 93 + 90 94 }; 91 95 92 96 config = { ··· 103 99 ''; 104 100 } 105 101 ]; 102 + 103 + services.openssh = mkIf config.testing.sshBackdoor.enable { 104 + enable = true; 105 + settings = { 106 + PermitRootLogin = "yes"; 107 + PermitEmptyPasswords = "yes"; 108 + }; 109 + }; 110 + 111 + security.pam.services.sshd = mkIf config.testing.sshBackdoor.enable { 112 + allowNullPassword = true; 113 + }; 106 114 107 115 systemd.services.backdoor = lib.mkMerge [ 108 116 backdoorService ··· 191 175 # we avoid defining attributes if not possible. 192 176 # TODO: refactor such that test-instrumentation can import qemu-vm 193 177 package = lib.mkDefault pkgs.qemu_test; 178 + 179 + options = mkIf config.testing.sshBackdoor.enable [ 180 + "-device vhost-vsock-pci,guest-cid=${toString (config.virtualisation.test.nodeNumber + 2)}" 181 + ]; 194 182 }; 195 183 }; 196 184