diff options
author | Artturi <Artturin@artturin.com> | 2023-11-03 03:16:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-03 03:16:07 +0200 |
commit | 891e7b46b9b416c3e7833b06ba18189de9ab9e00 (patch) | |
tree | 0fdb51e2ad11b959ef0a77ea4f1193a9530b4ff2 | |
parent | 4f3186b458189cf7095726792e8f183ea96e1a47 (diff) | |
parent | c15e1f61b005d2606b16efa8e36bdf3f96f6e09a (diff) |
Merge pull request #261356 from l0b0/test/ssh-audit
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/ssh-audit.nix | 103 | ||||
-rw-r--r-- | pkgs/tools/security/ssh-audit/default.nix | 5 |
3 files changed, 109 insertions, 0 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index f7f8ac8fec880..979eb3e1aa777 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -762,6 +762,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})") + ''; + } +) diff --git a/pkgs/tools/security/ssh-audit/default.nix b/pkgs/tools/security/ssh-audit/default.nix index 2a4abc11ea7b8..668f3c206f611 100644 --- a/pkgs/tools/security/ssh-audit/default.nix +++ b/pkgs/tools/security/ssh-audit/default.nix @@ -1,5 +1,6 @@ { lib , fetchFromGitHub +, nixosTests , python3Packages }: @@ -19,6 +20,10 @@ python3Packages.buildPythonApplication rec { pytestCheckHook ]; + passthru.tests = { + inherit (nixosTests) ssh-audit; + }; + meta = with lib; { description = "Tool for ssh server auditing"; homepage = "https://github.com/jtesta/ssh-audit"; |