diff options
author | Victor Engmark <victor@engmark.name> | 2023-10-16 21:31:39 +1300 |
---|---|---|
committer | Artturin <Artturin@artturin.com> | 2023-10-27 22:07:52 +0300 |
commit | c15e1f61b005d2606b16efa8e36bdf3f96f6e09a (patch) | |
tree | 44751934c3f5ddad1ead83e20008ca5ff4d52b9a /nixos | |
parent | 3e8e17821822ef190d72db3a612ea9be5a441ca9 (diff) |
ssh-audit: add test of audited configuration
On current nixpkgs, no modifications to the server settings were necessary to pass the audit. However, some of the client algorithms were considered insecure. The client configuration lists all algorithms which were listed as acceptable by `ssh-audit`. This can be used as an example of a configuration currently considered acceptable by `ssh-audit`, and verifies that such a configuration results in a compatible client/server configuration. Beware that this test will continue passing when future versions of `ssh-audit` add support for new algorithms. In other words, the example configuration represents a subset of what the current version of `ssh-audit` would consider acceptable.
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/ssh-audit.nix | 103 |
2 files changed, 104 insertions, 0 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 4a3f4a331ca80..21b11fe7d9f14 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -750,6 +750,7 @@ in { spark = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./spark {}; sqlite3-to-mysql = handleTest ./sqlite3-to-mysql.nix {}; sslh = handleTest ./sslh.nix {}; + ssh-audit = handleTest ./ssh-audit.nix {}; sssd = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd.nix {}; sssd-ldap = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd-ldap.nix {}; stalwart-mail = handleTest ./stalwart-mail.nix {}; diff --git a/nixos/tests/ssh-audit.nix b/nixos/tests/ssh-audit.nix new file mode 100644 index 0000000000000..bd6255b8044d9 --- /dev/null +++ b/nixos/tests/ssh-audit.nix @@ -0,0 +1,103 @@ +import ./make-test-python.nix ( + {pkgs, ...}: let + sshKeys = import (pkgs.path + "/nixos/tests/ssh-keys.nix") pkgs; + sshUsername = "any-user"; + serverName = "server"; + clientName = "client"; + sshAuditPort = 2222; + in { + name = "ssh"; + + nodes = { + "${serverName}" = { + networking.firewall.allowedTCPPorts = [ + sshAuditPort + ]; + services.openssh.enable = true; + users.users."${sshUsername}" = { + isNormalUser = true; + openssh.authorizedKeys.keys = [ + sshKeys.snakeOilPublicKey + ]; + }; + }; + "${clientName}" = { + programs.ssh = { + ciphers = [ + "aes128-ctr" + "aes128-gcm@openssh.com" + "aes192-ctr" + "aes256-ctr" + "aes256-gcm@openssh.com" + "chacha20-poly1305@openssh.com" + ]; + extraConfig = '' + IdentitiesOnly yes + ''; + hostKeyAlgorithms = [ + "rsa-sha2-256" + "rsa-sha2-256-cert-v01@openssh.com" + "rsa-sha2-512" + "rsa-sha2-512-cert-v01@openssh.com" + "sk-ssh-ed25519-cert-v01@openssh.com" + "sk-ssh-ed25519@openssh.com" + "ssh-ed25519" + "ssh-ed25519-cert-v01@openssh.com" + ]; + kexAlgorithms = [ + "curve25519-sha256" + "curve25519-sha256@libssh.org" + "diffie-hellman-group-exchange-sha256" + "diffie-hellman-group16-sha512" + "diffie-hellman-group18-sha512" + "sntrup761x25519-sha512@openssh.com" + ]; + macs = [ + "hmac-sha2-256-etm@openssh.com" + "hmac-sha2-512-etm@openssh.com" + "umac-128-etm@openssh.com" + ]; + }; + }; + }; + + testScript = '' + start_all() + + ${serverName}.wait_for_open_port(22) + + # Should pass SSH server audit + ${serverName}.succeed("${pkgs.ssh-audit}/bin/ssh-audit 127.0.0.1") + + # Wait for client to be able to connect to the server + ${clientName}.wait_for_unit("network-online.target") + + # Set up trusted private key + ${clientName}.succeed("cat ${sshKeys.snakeOilPrivateKey} > privkey.snakeoil") + ${clientName}.succeed("chmod 600 privkey.snakeoil") + + # Fail fast and disable interactivity + ssh_options = "-o BatchMode=yes -o ConnectTimeout=1 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" + + # Should deny root user + ${clientName}.fail(f"ssh {ssh_options} root@${serverName} true") + + # Should deny non-root user password login + ${clientName}.fail(f"ssh {ssh_options} -o PasswordAuthentication=yes ${sshUsername}@${serverName} true") + + # Should allow non-root user certificate login + ${clientName}.succeed(f"ssh {ssh_options} -i privkey.snakeoil ${sshUsername}@${serverName} true") + + # Should pass SSH client audit + service_name = "ssh-audit.service" + ${serverName}.succeed(f"systemd-run --unit={service_name} ${pkgs.ssh-audit}/bin/ssh-audit --client-audit --port=${toString sshAuditPort}") + ${clientName}.sleep(5) # We can't use wait_for_open_port because ssh-audit exits as soon as anything talks to it + ${clientName}.execute( + f"ssh {ssh_options} -i privkey.snakeoil -p ${toString sshAuditPort} ${sshUsername}@${serverName} true", + check_return=False, + timeout=10 + ) + ${serverName}.succeed(f"exit $(systemctl show --property=ExecMainStatus --value {service_name})") + ''; + } +) |