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:
1 2 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
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.
I tried this on “Ubuntu 22.04.3 LTS” jammy and it didn’t work :-(
$ sudo gem install ssh_scan
Fetching sshkey-2.0.0.gem
Fetching net-ssh-6.0.2.gem
Fetching netaddr-2.0.4.gem
Fetching bindata-2.4.3.gem
Fetching bcrypt_pbkdf-1.0.1.gem
Fetching ed25519-1.2.4.gem
Fetching ssh_scan-0.0.44.gem
…
$ ssh_scan -t tower
# terminated with exception (report_on_exception is true):
/var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/openssl.rb:152:in
public_key=': pkeys are immutable on OpenSSL 3.0 (OpenSSL::PKey::PKeyError)
read_keyblob’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/openssl.rb:152:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/buffer.rb:325:in
read_keyblob'
read_key’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/buffer.rb:248:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:148:in
block (2 levels) in keys_for'
each_line’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:132:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:132:in
block in keys_for'
open’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:131:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:131:in
keys_for'
block in search_in’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:61:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:61:in
each'
flat_map’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:61:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:61:in
search_in'
search_for’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/known_hosts.rb:55:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/session.rb:98:in
host_keys'
prepare_preferred_algorithms!’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/algorithms.rb:278:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/algorithms.rb:154:in
initialize'
new’from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/session.rb:88:in
from /var/lib/gems/3.0.0/gems/net-ssh-6.0.2/lib/net/ssh/transport/session.rb:88:in
initialize'
new’from /var/lib/gems/3.0.0/gems/ssh_scan-0.0.44/lib/ssh_scan/scan_engine.rb:97:in
from /var/lib/gems/3.0.0/gems/ssh_scan-0.0.44/lib/ssh_scan/scan_engine.rb:97:in
scan_target'
block (2 levels) in scan’from /var/lib/gems/3.0.0/gems/ssh_scan-0.0.44/lib/ssh_scan/scan_engine.rb:184:in
This is with openssl 3.0.2-0ubuntu1.10 amd64