Unverified Commit 8b3baa14 authored by Jacek Galowicz's avatar Jacek Galowicz Committed by GitHub
Browse files

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

parents 907e98d6 8869265f
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -63,6 +63,35 @@ using:
Once the connection is established, you can enter commands in the socat terminal
where socat is running.

## SSH Access for test machines {#sec-nixos-test-ssh-access}

An SSH-based backdoor to log into machines can be enabled with

```nix
{
  name = "…";
  nodes.machines = { /* … */ };
  sshBackdoor.enable = true;
}
```

This creates a [vsock socket](https://man7.org/linux/man-pages/man7/vsock.7.html)
for each VM to log in with SSH. This configures root login with an empty password.

When the VMs get started interactively with the test-driver, it's possible to
connect to `machine` with

```
$ ssh vsock/3 -o User=root
```

The socket numbers correspond to the node number of the test VM, but start
at three instead of one because that's the lowest possible
vsock number.

On non-NixOS systems you'll probably need to enable
the SSH config from {manpage}`systemd-ssh-proxy(1)` yourself.

## Port forwarding to NixOS test VMs {#sec-nixos-test-port-forwarding}

If your test has only a single VM, you may use e.g.
+6 −0
Original line number Diff line number Diff line
@@ -1823,6 +1823,9 @@
  "sec-test-options-reference": [
    "index.html#sec-test-options-reference"
  ],
  "test-opt-sshBackdoor.enable": [
    "index.html#test-opt-sshBackdoor.enable"
  ],
  "test-opt-defaults": [
    "index.html#test-opt-defaults"
  ],
@@ -1910,6 +1913,9 @@
  "sec-nixos-test-shell-access": [
    "index.html#sec-nixos-test-shell-access"
  ],
  "sec-nixos-test-ssh-access": [
    "index.html#sec-nixos-test-ssh-access"
  ],
  "sec-nixos-test-port-forwarding": [
    "index.html#sec-nixos-test-port-forwarding"
  ],
+7 −0
Original line number Diff line number Diff line
@@ -109,6 +109,11 @@ def main() -> None:
        help="the test script to run",
        type=Path,
    )
    arg_parser.add_argument(
        "--dump-vsocks",
        help="indicates that the interactive SSH backdoor is active and dumps information about it on start",
        action="store_true",
    )

    args = arg_parser.parse_args()

@@ -136,6 +141,8 @@ def main() -> None:
        if args.interactive:
            history_dir = os.getcwd()
            history_path = os.path.join(history_dir, ".nixos-test-history")
            if args.dump_vsocks:
                driver.dump_machine_ssh()
            ptpython.ipython.embed(
                user_ns=driver.test_symbols(),
                history_filename=history_path,
+15 −0
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@ from pathlib import Path
from typing import Any
from unittest import TestCase

from colorama import Style

from test_driver.errors import MachineError, RequestedAssertionFailed
from test_driver.logger import AbstractLogger
from test_driver.machine import Machine, NixStartScript, retry
@@ -176,6 +178,19 @@ class Driver:
        )
        return {**general_symbols, **machine_symbols, **vlan_symbols}

    def dump_machine_ssh(self) -> None:
        print("SSH backdoor enabled, the machines can be accessed like this:")
        print(
            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)."
        )
        names = [machine.name for machine in self.machines]
        longest_name = len(max(names, key=len))
        for num, name in enumerate(names, start=3):
            spaces = " " * (longest_name - len(name) + 2)
            print(
                f"    {name}:{spaces}{Style.BRIGHT}ssh -o User=root vsock/{num}{Style.RESET_ALL}"
            )

    def test_script(self) -> None:
        """Run the test script"""
        with self.logger.nested("run the VM test script"):
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ pkgs.lib.throwIf (args ? specialArgs)
          ),
        extraPythonPackages ? (_: [ ]),
        interactive ? { },
        sshBackdoor ? { },
      }@t:
      let
        testConfig =
Loading