For administrative purposes, SSH is used quite often. Almost everyone in IT knows it. Keywords: OpenSSH, simply using “ssh <hostname>” on your machine, PuTTY for Windows, username + password or public key authentication, TCP port 22, simple firewall rules, ignoring the fingerprints 🤦♂️, SCP and SFTP. That’s it – basically.
However, it gets much more complicated if you look into the details. You have to deal with many different types and representations of fingerprints, as well as crypto algorithms. Troubleshooting specific connection problems is challenging.
To get an overview of your SSH server’s configuration is to scan them with appropriate tools. I’m showing two of them here: ssh_scan and the Nmap script “ssh2-enum-algos“.
I’m using an Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-139-generic x86_64) for the following.
mozilla/ssh_scan
“An SSH configuration and policy scanner“. Unfortunately, the GitHub repository has been marked as deprecated. However, you can still install it:
sudo apt install ruby ruby-dev gcc gem sudo gem install ssh_scan
Usage is simple: ssh_scan -t <hostname|ip>. The output gives you many insights about the keys (along with their fingerprints), the encryption-, mac-, and key-algorithms, SSHFP dns_keys, and so forth. IPv6 is preferred, as it should be.
This is a test run against an Ubuntu 18.04.6 LTS:
weberjoh@vm32-test2:~$ ssh_scan -t test1.weberlab.de [ { "ssh_scan_version": "0.0.44", "ip": "194.247.5.25", "hostname": "test1.weberlab.de", "port": 22, "server_banner": "SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7", "ssh_version": 2.0, "os": "ubuntu", "os_cpe": "o:canonical:ubuntu", "ssh_lib": "openssh", "ssh_lib_cpe": "a:openssh:openssh:7.6p1", "key_algorithms": [ "curve25519-sha256", "curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group16-sha512", "diffie-hellman-group18-sha512", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1" ], "encryption_algorithms_client_to_server": [ "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com" ], "encryption_algorithms_server_to_client": [ "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com" ], "mac_algorithms_client_to_server": [ "umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1" ], "mac_algorithms_server_to_client": [ "umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1" ], "compression_algorithms_client_to_server": [ "none", "zlib@openssh.com" ], "compression_algorithms_server_to_client": [ "none", "zlib@openssh.com" ], "languages_client_to_server": [ ], "languages_server_to_client": [ ], "auth_methods": [ "publickey", "password" ], "keys": { "rsa": { "raw": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDhLLYj+v5tChro3/H0EYUj1sePBEh89Z1IDyQpaxsMNmbXxmt3Q/H26jDlCCIoVUrnsdcYSsa8zRnumRDgb1mGUUs18ri7bQhT+NOfwox/c29VQj7tYCF1tw8LMehn2bhAZgVyUJohsXoAe6Aa8N47aQ8ddCu09DSCBMpbZJgKONqVkc/lYZ+yBhxHUVmCrTjfuX2z3ycM8cJ6pGCsBvzZx2aJXJFmvsNiwjaXJz6rhm0UwP/9haKiC3PCvHwNNMMQfM9yUWm0eRcxtitLw/B51m4aoLpEkomomcwPSBbpPzUWrPtNXWStfFajjr2GFO7NY9AGylV25scjb+YIz2x7", "length": 2048, "fingerprints": { "md5": "42:5a:52:28:d3:f1:6d:bf:22:ba:26:26:2b:65:29:24", "sha1": "48:62:51:71:25:04:1d:d1:ea:7f:14:7e:ce:91:1c:0a:21:92:3d:cb", "sha256": "ee:70:d2:6e:e3:a5:db:2c:45:e8:6b:43:01:3d:85:8c:83:2b:95:94:ba:93:23:c2:db:19:3b:d4:09:f4:cf:1a" } }, "ecdsa-sha2-nistp256": { "raw": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPfD/EKxAETdEr8oP1JEuDNj2MZUPNmqakQrzgsqOSirgbDCVDZrjU5Au1aM4k0KzMFRVjTT4jvs64ea45F5SN8=", "length": 520, "fingerprints": { "md5": "08:cc:6a:15:be:a6:0c:6a:ae:0c:0d:87:f2:cb:a4:90", "sha1": "5c:db:59:67:1c:30:1e:74:96:a6:87:8d:fe:6c:3f:d0:6c:9a:4f:f5", "sha256": "fa:f3:d7:2b:51:69:7e:62:cd:1b:36:f9:d3:86:5b:dc:52:62:da:9f:3a:db:ef:5f:3b:a8:81:7b:2d:15:e8:00" } }, "ed25519": { "raw": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICg8/9MH7OjCSDevCKVZY5XBKMInGWb8Jb2Sm7driEI", "length": 256, "fingerprints": { "md5": "97:38:e8:8e:81:83:56:6e:0f:bc:77:06:88:75:37:d3", "sha1": "41:09:8f:a4:0e:be:90:f7:38:83:62:ec:40:7e:b2:2c:49:bf:c2:d1", "sha256": "76:f2:b1:40:5b:8b:ea:0e:0c:97:6b:20:ce:0a:0b:5d:19:f9:f3:ce:99:bb:24:6d:93:8b:4d:3c:e7:28:ac:44" } } }, "dns_keys": [ { "fptype": "sha256", "algo": "ed25519", "hex": "76:f2:b1:40:5b:8b:ea:0e:0c:97:6b:20:ce:0a:0b:5d:19:f9:f3:ce:99:bb:24:6d:93:8b:4d:3c:e7:28:ac:44" }, { "fptype": "sha256", "algo": "rsa", "hex": "ee:70:d2:6e:e3:a5:db:2c:45:e8:6b:43:01:3d:85:8c:83:2b:95:94:ba:93:23:c2:db:19:3b:d4:09:f4:cf:1a" }, { "fptype": "sha256", "algo": "ecdsa", "hex": "fa:f3:d7:2b:51:69:7e:62:cd:1b:36:f9:d3:86:5b:dc:52:62:da:9f:3a:db:ef:5f:3b:a8:81:7b:2d:15:e8:00" } ], "duplicate_host_key_ips": [ ], "compliance": { "policy": "Mozilla Modern", "compliant": false, "recommendations": [ "Remove these key exchange algorithms: diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1", "Remove these MAC algorithms: umac-64-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com, hmac-sha1", "Remove these authentication methods: password" ], "references": [ "https://wiki.mozilla.org/Security/Guidelines/OpenSSH" ], "grade": "D" }, "start_time": "2023-02-22 15:33:47 +0000", "end_time": "2023-02-22 15:33:48 +0000", "scan_duration_seconds": 0.806951794 } ]
And this is against an old Cisco 2811 router with IOS version 12.3(8r)T7:
weberjoh@vm32-test2:~$ ssh_scan -t router1.weberlab.de [ { "ssh_scan_version": "0.0.44", "ip": "2001:470:1f0a:319::2", "hostname": "router1.weberlab.de", "port": 22, "server_banner": "SSH-2.0-Cisco-1.25", "ssh_version": 2.0, "os": "cisco", "os_cpe": "o:cisco:cisco", "ssh_lib": "ciscossh", "ssh_lib_cpe": "a:cisco:ciscossh", "key_algorithms": [ "diffie-hellman-group-exchange-sha1", "diffie-hellman-group14-sha1", "diffie-hellman-group1-sha1" ], "encryption_algorithms_client_to_server": [ "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc" ], "encryption_algorithms_server_to_client": [ "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc" ], "mac_algorithms_client_to_server": [ "hmac-sha1", "hmac-sha1-96", "hmac-md5", "hmac-md5-96" ], "mac_algorithms_server_to_client": [ "hmac-sha1", "hmac-sha1-96", "hmac-md5", "hmac-md5-96" ], "compression_algorithms_client_to_server": [ "none" ], "compression_algorithms_server_to_client": [ "none" ], "languages_client_to_server": [ ], "languages_server_to_client": [ ], "auth_methods": [ ], "keys": { }, "dns_keys": [ { "fptype": "sha256", "algo": "rsa", "hex": "cc:88:fd:4a:a1:cb:8e:40:8f:13:01:ee:a5:16:1e:77:51:54:42:0a:d1:56:bf:39:0b:b3:13:6b:1e:2f:bf:cb" } ], "duplicate_host_key_ips": [ ], "compliance": { "policy": "Mozilla Modern", "compliant": false, "recommendations": [ "Add these key exchange algorithms: curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256", "Add these MAC algorithms: hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com", "Add these encryption ciphers: chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr", "Remove these key exchange algorithms: diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1, diffie-hellman-group1-sha1", "Remove these MAC algorithms: hmac-sha1, hmac-sha1-96, hmac-md5, hmac-md5-96", "Remove these encryption ciphers: aes128-cbc, 3des-cbc, aes192-cbc, aes256-cbc" ], "references": [ "https://wiki.mozilla.org/Security/Guidelines/OpenSSH" ], "grade": "F" }, "start_time": "2023-02-22 15:42:52 +0000", "end_time": "2023-02-22 15:42:52 +0000", "scan_duration_seconds": 0.499461599, "error": "could not settle on encryption_client algorithm\nServer encryption_client preferences: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc\nClient encryption_client preferences: aes256-ctr,aes192-ctr,aes128-ctr" } ]
Note the recommendations and the grade.
Nmap Script ssh2-enum-algos
Another way is to use Nmap along with an NSE (Nmap Scripting Engine) script: ssh2-enum-algos. The call is simple as well: nmap --script ssh2-enum-algos <hostname|ip>. The output shows the algorithms only, as the name of the script suggests. As always with Nmap: If you want to scan via IPv6, you have to specify it with “-6” explicitly.
Again, this is a test run against the Ubuntu 18.04.6 LTS:
weberjoh@vm32-test2:~$ nmap --script ssh2-enum-algos test1.weberlab.de Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-23 09:36 UTC Nmap scan report for test1.weberlab.de (194.247.5.25) Host is up (0.00040s latency). Not shown: 999 closed tcp ports (conn-refused) PORT STATE SERVICE 22/tcp open ssh | ssh2-enum-algos: | kex_algorithms: (10) | curve25519-sha256 | curve25519-sha256@libssh.org | ecdh-sha2-nistp256 | ecdh-sha2-nistp384 | ecdh-sha2-nistp521 | diffie-hellman-group-exchange-sha256 | diffie-hellman-group16-sha512 | diffie-hellman-group18-sha512 | diffie-hellman-group14-sha256 | diffie-hellman-group14-sha1 | server_host_key_algorithms: (5) | ssh-rsa | rsa-sha2-512 | rsa-sha2-256 | ecdsa-sha2-nistp256 | ssh-ed25519 | encryption_algorithms: (6) | chacha20-poly1305@openssh.com | aes128-ctr | aes192-ctr | aes256-ctr | aes128-gcm@openssh.com | aes256-gcm@openssh.com | mac_algorithms: (10) | umac-64-etm@openssh.com | umac-128-etm@openssh.com | hmac-sha2-256-etm@openssh.com | hmac-sha2-512-etm@openssh.com | hmac-sha1-etm@openssh.com | umac-64@openssh.com | umac-128@openssh.com | hmac-sha2-256 | hmac-sha2-512 | hmac-sha1 | compression_algorithms: (2) | none |_ zlib@openssh.com Nmap done: 1 IP address (1 host up) scanned in 0.62 seconds
And this is against the old Cisco 2811 router with IOS version 12.3(8r)T7:
weberjoh@vm32-test2:~$ nmap -6 --script ssh2-enum-algos router1.weberlab.de Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-23 09:38 UTC Nmap scan report for router1.weberlab.de (2001:470:1f0a:319::2) Host is up (0.028s latency). Other addresses for router1.weberlab.de (not scanned): 37.24.166.89 rDNS record for 2001:470:1f0a:319::2: tunnel643592-pt.tunnel.tserv6.fra1.ipv6.he.net Not shown: 997 closed tcp ports (conn-refused) PORT STATE SERVICE 22/tcp open ssh | ssh2-enum-algos: | kex_algorithms: (3) | diffie-hellman-group-exchange-sha1 | diffie-hellman-group14-sha1 | diffie-hellman-group1-sha1 | server_host_key_algorithms: (1) | ssh-rsa | encryption_algorithms: (4) | aes128-cbc | 3des-cbc | aes192-cbc | aes256-cbc | mac_algorithms: (4) | hmac-sha1 | hmac-sha1-96 | hmac-md5 | hmac-md5-96 | compression_algorithms: (1) |_ none 5060/tcp open sip 8008/tcp open http Nmap done: 1 IP address (1 host up) scanned in 13.29 seconds
Conclusion
It’s just the very first step to merely look at your SSH servers. If you have to troubleshoot connection errors, you have to capture and analyse them in-depth. But if you want to know which protocols, keys, and so forth are possible, those SSH scanners do a great job.
If you want to improve your SSH server configuration, have a look at this guide.