1 import ./make-test-python.nix (
3 sshKeys = import (pkgs.path + "/nixos/tests/ssh-keys.nix") pkgs;
4 sshUsername = "any-user";
13 networking.firewall.allowedTCPPorts = [
16 services.openssh.enable = true;
17 users.users."${sshUsername}" = {
19 openssh.authorizedKeys.keys = [
20 sshKeys.snakeOilPublicKey
28 "aes128-gcm@openssh.com"
31 "aes256-gcm@openssh.com"
32 "chacha20-poly1305@openssh.com"
39 "rsa-sha2-256-cert-v01@openssh.com"
41 "rsa-sha2-512-cert-v01@openssh.com"
42 "sk-ssh-ed25519-cert-v01@openssh.com"
43 "sk-ssh-ed25519@openssh.com"
45 "ssh-ed25519-cert-v01@openssh.com"
49 "curve25519-sha256@libssh.org"
50 "diffie-hellman-group-exchange-sha256"
51 "diffie-hellman-group16-sha512"
52 "diffie-hellman-group18-sha512"
53 "sntrup761x25519-sha512@openssh.com"
56 "hmac-sha2-256-etm@openssh.com"
57 "hmac-sha2-512-etm@openssh.com"
58 "umac-128-etm@openssh.com"
67 ${serverName}.wait_for_open_port(22)
69 # Should pass SSH server audit
70 ${serverName}.succeed("${pkgs.ssh-audit}/bin/ssh-audit 127.0.0.1")
72 # Wait for client to be able to connect to the server
73 ${clientName}.systemctl("start network-online.target")
74 ${clientName}.wait_for_unit("network-online.target")
76 # Set up trusted private key
77 ${clientName}.succeed("cat ${sshKeys.snakeOilPrivateKey} > privkey.snakeoil")
78 ${clientName}.succeed("chmod 600 privkey.snakeoil")
80 # Fail fast and disable interactivity
81 ssh_options = "-o BatchMode=yes -o ConnectTimeout=1 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
83 # Should deny root user
84 ${clientName}.fail(f"ssh {ssh_options} root@${serverName} true")
86 # Should deny non-root user password login
87 ${clientName}.fail(f"ssh {ssh_options} -o PasswordAuthentication=yes ${sshUsername}@${serverName} true")
89 # Should allow non-root user certificate login
90 ${clientName}.succeed(f"ssh {ssh_options} -i privkey.snakeoil ${sshUsername}@${serverName} true")
92 # Should pass SSH client audit
93 service_name = "ssh-audit.service"
94 ${serverName}.succeed(f"systemd-run --unit={service_name} ${pkgs.ssh-audit}/bin/ssh-audit --client-audit --port=${toString sshAuditPort}")
95 ${clientName}.sleep(5) # We can't use wait_for_open_port because ssh-audit exits as soon as anything talks to it
96 ${clientName}.execute(
97 f"ssh {ssh_options} -i privkey.snakeoil -p ${toString sshAuditPort} ${sshUsername}@${serverName} true",
101 ${serverName}.succeed(f"exit $(systemctl show --property=ExecMainStatus --value {service_name})")