jtesta / ssh-audit Goto Github PK
View Code? Open in Web Editor NEWSSH server & client security auditing (banner, key exchange, encryption, mac, compression, compatibility, security, etc)
License: MIT License
SSH server & client security auditing (banner, key exchange, encryption, mac, compression, compatibility, security, etc)
License: MIT License
$ cd pypi
$ python setup.py build
Traceback (most recent call last):
File "setup.py", line 8, in <module>
version = re.search('^VERSION\s*=\s*\'v(\d\.\d\.\d)\'', open('sshaudit/sshaudit.py').read(), re.M).group(1)
FileNotFoundError: [Errno 2] No such file or directory: 'sshaudit/sshaudit.py'
$ python setup.py build
Traceback (most recent call last):
File "setup.py", line 11, in <module>
with open("sshaudit/README.md", "rb") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'sshaudit/README.md'
There is no sshaudit.py
in pypi/sshaudit/
, I suspect you are using a symbolic link locally.
Also it's not the right filename (dash missing). Same for the README.
So the workaround was:
$ cp ../ssh-audit.py sshaudit/sshaudit.py
$ cp ../README.md sshaudit/README.md
Maybe you can detach this repo from the not maintained fork?
You can this either do it manually or – which I recommend – just contact the GitHub support to do it for you.
This…
Not ALL types of "ssh-rsa" keys are going to be deprecated - only the ones signed by SHA-1. The phrasing is confusing in the announcement.
They do say:
"For this reason, we will be disabling the "ssh-rsa" public key signature algorithm that depends on SHA-1 by default in a near-future release."
but then go on to mention as one alternative:
"The RFC8332 RSA SHA-2 signature algorithms rsa-sha2-256/512. These algorithms have the advantage of using the same key type as "ssh-rsa" but use the safe SHA-2 hash algorithms. These have been supported since OpenSSH 7.2 and are already used by default if the client and server support them."
And sure enough, examining the ssh-keygen
manpage reveals:
-t dsa | ecdsa | ed25519 | rsa
Specifies the type of key to create. The possible values are “dsa”, “ecdsa”, “ed25519”, or “rsa”.
This flag may also be used to specify the desired signature type when signing certificates using an RSA CA key. The available RSA signature variants are “ssh-rsa” (SHA1 signatures, not recommended), “rsa-sha2-256”, and “rsa-sha2-512” (the default)
So the ssh-rsa
key type is still valid for the latter two options, only the 1024 SHA-2 type is being eliminated, and most modern systems have been generating SHA-2 keys for a while now - the support for them went into version 7.2 back in early 2016.
There should be a client configuration test mode. The tool could listen on localhost:22, then parse the options supported by the incoming client connection.
Hence, client-side hardening can be done to prevent weak connections to lax servers.
The tool should be able to parse a policy file and test a server for compliance. This would help admins with many machines immediately know what server(s) are not adhering to their policy.
Strong default policies should be included for Ubuntu Server and CentOS.
I'd like to be able to get a csv or xml report of the audit. Json manipulation is great but it's easier to add better reporting options.
Related:
arthepsy/ssh-audit#5
8.2 in particular adds support for FIDO sticks but there are a number of other improvements and changes that probably require more checks be added (including CVEs). https://www.openssh.com/releasenotes.html
I did see you started working a tiny bit on it in your dev branch so this issue should be a tracker for visibly showing support for these versions.
This tool is designed to increase security but itself is insecure and uses unsupported imports.
The following changes need to be made to get it at the very least python 3.6 compatible:
Update get-opt to argparse (or choose something else like click but argparse is the easiest supported transition)
Remove future, base64 and others that are only needed below python3.6.
The following projects will likely help (including ironically the use of futurize):
https://github.com/PythonCharmers/python-future
https://github.com/asottile/pyupgrade (run all but the py37-plus flag)
You may also find https://github.com/python-poetry/poetry helpful for dependency management.
Also try to ensure the script is PEP compliant using mypy and pylint.
Firstly, thank you for taking over the maintenance of a very useful tool.
Professionally my work involves a lot of automation which frequently involves the use of SSH and SFTP client tools and libraries. From time-to-time it's necessary to audit these tools and libraries to check whether they're using any weak or deprecated algorithms to ensure we're not connecting to remote servers or sending files insecurely.
It would be extremely useful to be able to feed the list of algorithms that a client tool/library supports into ssh-audit and produce a report.
I've written a proof of concept (it's not a perfect implementation) to demonstrate how this might work, see:
https://gist.github.com/thecliguy/682c12c26c8d72da3e08ad4d36f2f027
Syntax:
--lookup Perform an algorithm lookup
--algtype=<AlgorithmType> Algorithm Type (enc|kex|key|mac)
--algname=<AlgorithmName> Algorithm Name (accepts a comma separated list)
[--ssh1|--ssh2] SSH1 or SSH2 (implicit default is SSH2)
Example Usage:
Protocol: SSH1, Algorithm Type: Host Key, Algorithm Name(s): ssh-rsa1
ssh-audit.py --lookup --algtype=key --algname=ssh-rsa1 --ssh1
# host-key algorithms
(key) ssh-rsa1 -- [info] available since OpenSSH 1.2.2
Protocol: SSH1, Algorithm Type: Encryption (Cipher), Algorithm Name(s): des
ssh-audit.py --lookup --algtype=enc--algname=des --ssh1
# encryption algorithms (ciphers)
(enc) des -- [fail] not implemented in OpenSSH (server), unsafe algorithm
`- [info] available since OpenSSH 2.3.0 (client only)
Protocol: SSH2, Algorithm Type: Key Exchange, Algorithm Name(s): diffie-hellman-group1-sha1
, diffie-hellman-group14-sha1
and diffie-hellman-group-exchange-sha256
ssh-audit.py --lookup --algtype=kex --algname=diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256
# key exchange algorithms
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
`- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
`- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
`- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group-exchange-sha256 -- [info] available since OpenSSH 4.4
Protocol: SSH2, Algorithm Type: Host Key, Algorithm Name(s): ssh-ed25519
, ecdsa-sha2-nistp256
, ssh-rsa
and rsa-sha2-256
ssh-audit.py --lookup --algtype=key --algname=ssh-ed25519,ecdsa-sha2-nistp256,ssh-rsa,rsa-sha2-256
# host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-rsa -- [fail] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) rsa-sha2-256 -- [info] available since OpenSSH 7.2
Protocol: SSH2, Algorithm Type: Encryption (Cipher), Algorithm Name(s): [email protected]
, aes256-ctr
, aes192-ctr
and aes128-ctr
ssh-audit.py --lookup --algtype=enc [email protected],aes256-ctr,aes192-ctr,aes128-ctr
(enc) [email protected] -- [info] available since OpenSSH 6.2
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
Protocol: SSH2, Algorithm Type: Message Authentication Code, Algorithm Name(s): [email protected]
, [email protected]
and hmac-sha2-256
ssh-audit.py --lookup --algtype=mac [email protected],[email protected],hmac-sha2-256
# message authentication code algorithms
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
I'd be grateful for your feedback.
The tool should output the server's fingerprints in SHA-1 and SHA256 formats.
Without having a deeper look what the Docker tests actually do, I ran the script while on the current master.
I am on Ubuntu 18.04, but I'd assume the Docker tests should(?) be independent of the host.
Signature on TinySSH sources verified.
Uncompressing OpenSSH 4.0p1...
Compiling OpenSSH 4.0p1...
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking whether byte ordering is bigendian... no
checking for gawk... no
checking for mawk... mawk
checking how to run the C preprocessor... gcc -E
checking for ranlib... ranlib
checking for a BSD-compatible install... /usr/bin/install -c
checking for ar... /usr/bin/ar
checking for cat... /bin/cat
checking for kill... /bin/kill
checking for perl5... no
checking for perl... /usr/bin/perl
checking for sed... /bin/sed
checking for ent... no
checking for bash... /bin/bash
checking for ksh... (cached) /bin/bash
checking for sh... (cached) /bin/bash
checking for sh... /bin/sh
checking for groupadd... /usr/sbin/groupadd
checking for useradd... /usr/sbin/useradd
checking for pkgmk... no
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking for _LARGE_FILES value needed for large files... no
checking for login... /bin/login
checking for passwd... /usr/bin/passwd
checking for inline... inline
checking compiler and flags for sanity... yes
checking for egrep... grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking bstring.h usability... no
checking bstring.h presence... no
checking for bstring.h... no
checking crypt.h usability... yes
checking crypt.h presence... yes
checking for crypt.h... yes
checking dirent.h usability... yes
checking dirent.h presence... yes
checking for dirent.h... yes
checking endian.h usability... yes
checking endian.h presence... yes
checking for endian.h... yes
checking features.h usability... yes
checking features.h presence... yes
checking for features.h... yes
checking floatingpoint.h usability... no
checking floatingpoint.h presence... no
checking for floatingpoint.h... no
checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking glob.h usability... yes
checking glob.h presence... yes
checking for glob.h... yes
checking ia.h usability... no
checking ia.h presence... no
checking for ia.h... no
checking lastlog.h usability... yes
checking lastlog.h presence... yes
checking for lastlog.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking login.h usability... no
checking login.h presence... no
checking for login.h... no
checking login_cap.h usability... no
checking login_cap.h presence... no
checking for login_cap.h... no
checking maillock.h usability... no
checking maillock.h presence... no
checking for maillock.h... no
checking ndir.h usability... no
checking ndir.h presence... no
checking for ndir.h... no
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netgroup.h usability... no
checking netgroup.h presence... no
checking for netgroup.h... no
checking netinet/in_systm.h usability... yes
checking netinet/in_systm.h presence... yes
checking for netinet/in_systm.h... yes
checking pam/pam_appl.h usability... no
checking pam/pam_appl.h presence... no
checking for pam/pam_appl.h... no
checking paths.h usability... yes
checking paths.h presence... yes
checking for paths.h... yes
checking pty.h usability... yes
checking pty.h presence... yes
checking for pty.h... yes
checking readpassphrase.h usability... no
checking readpassphrase.h presence... no
checking for readpassphrase.h... no
checking rpc/types.h usability... yes
checking rpc/types.h presence... yes
checking for rpc/types.h... yes
checking security/pam_appl.h usability... no
checking security/pam_appl.h presence... no
checking for security/pam_appl.h... no
checking shadow.h usability... yes
checking shadow.h presence... yes
checking for shadow.h... yes
checking stddef.h usability... yes
checking stddef.h presence... yes
checking for stddef.h... yes
checking for stdint.h... (cached) yes
checking for strings.h... (cached) yes
checking sys/dir.h usability... yes
checking sys/dir.h presence... yes
checking for sys/dir.h... yes
checking sys/strtio.h usability... no
checking sys/strtio.h presence... no
checking for sys/strtio.h... no
checking sys/audit.h usability... no
checking sys/audit.h presence... no
checking for sys/audit.h... no
checking sys/bitypes.h usability... yes
checking sys/bitypes.h presence... yes
checking for sys/bitypes.h... yes
checking sys/bsdtty.h usability... no
checking sys/bsdtty.h presence... no
checking for sys/bsdtty.h... no
checking sys/cdefs.h usability... yes
checking sys/cdefs.h presence... yes
checking for sys/cdefs.h... yes
checking sys/mman.h usability... yes
checking sys/mman.h presence... yes
checking for sys/mman.h... yes
checking sys/ndir.h usability... no
checking sys/ndir.h presence... no
checking for sys/ndir.h... no
checking sys/prctl.h usability... yes
checking sys/prctl.h presence... yes
checking for sys/prctl.h... yes
checking sys/pstat.h usability... no
checking sys/pstat.h presence... no
checking for sys/pstat.h... no
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for sys/stat.h... (cached) yes
checking sys/stream.h usability... no
checking sys/stream.h presence... no
checking for sys/stream.h... no
checking sys/stropts.h usability... yes
checking sys/stropts.h presence... yes
checking for sys/stropts.h... yes
checking sys/sysmacros.h usability... yes
checking sys/sysmacros.h presence... yes
checking for sys/sysmacros.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking sys/timers.h usability... no
checking sys/timers.h presence... no
checking for sys/timers.h... no
checking sys/un.h usability... yes
checking sys/un.h presence... yes
checking for sys/un.h... yes
checking time.h usability... yes
checking time.h presence... yes
checking for time.h... yes
checking tmpdir.h usability... no
checking tmpdir.h presence... no
checking for tmpdir.h... no
checking ttyent.h usability... yes
checking ttyent.h presence... yes
checking for ttyent.h... yes
checking usersec.h usability... no
checking usersec.h presence... no
checking for usersec.h... no
checking util.h usability... no
checking util.h presence... no
checking for util.h... no
checking utime.h usability... yes
checking utime.h presence... yes
checking for utime.h... yes
checking utmp.h usability... yes
checking utmp.h presence... yes
checking for utmp.h... yes
checking utmpx.h usability... yes
checking utmpx.h presence... yes
checking for utmpx.h... yes
checking vis.h usability... no
checking vis.h presence... no
checking for vis.h... no
checking for sys/ptms.h... no
checking for yp_match... no
checking for yp_match in -lnsl... yes
checking for setsockopt... yes
checking for dirname... yes
checking libgen.h usability... yes
checking libgen.h presence... yes
checking for libgen.h... yes
checking for getspnam... yes
checking for library containing basename... none required
checking for deflate in -lz... yes
checking zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking for zlib 1.1.4 or greater... yes
checking for strcasecmp... yes
checking for utimes... yes
checking libutil.h usability... no
checking libutil.h presence... no
checking for libutil.h... no
checking for library containing login... -lutil
checking for logout... yes
checking for updwtmp... yes
checking for logwtmp... yes
checking for strftime... yes
checking for GLOB_ALTDIRFUNC support... yes
checking for gl_matchc field in glob_t... no
checking whether struct dirent allocates space for d_name... yes
checking for /proc/pid/fd directory... yes
checking for arc4random... no
checking for __b64_ntop... no
checking for b64_ntop... no
checking for __b64_pton... no
checking for b64_pton... no
checking for bcopy... yes
checking for bindresvport_sa... no
checking for clock... yes
checking for closefrom... no
checking for dirfd... yes
checking for fchdir... yes
checking for fchmod... yes
checking for fchown... yes
checking for freeaddrinfo... yes
checking for futimes... yes
checking for getaddrinfo... yes
checking for getcwd... yes
checking for getgrouplist... yes
checking for getnameinfo... yes
checking for getopt... yes
checking for getpeereid... no
checking for _getpty... no
checking for getrlimit... yes
checking for getttyent... yes
checking for glob... yes
checking for inet_aton... yes
checking for inet_ntoa... yes
checking for inet_ntop... yes
checking for innetgr... yes
checking for login_getcapbool... no
checking for md5_crypt... no
checking for memmove... yes
checking for mkdtemp... yes
checking for mmap... yes
checking for ngetaddrinfo... no
checking for nsleep... no
checking for ogetaddrinfo... no
checking for openlog_r... no
checking for openpty... yes
checking for pstat... no
checking for prctl... yes
checking for readpassphrase... no
checking for realpath... yes
checking for recvmsg... yes
checking for rresvport_af... yes
checking for sendmsg... yes
checking for setdtablesize... no
checking for setegid... yes
checking for setenv... yes
checking for seteuid... yes
checking for setgroups... yes
checking for setlogin... no
checking for setpcred... no
checking for setproctitle... no
checking for setregid... yes
checking for setreuid... yes
checking for setrlimit... yes
checking for setsid... yes
checking for setvbuf... yes
checking for sigaction... yes
checking for sigvec... no
checking for snprintf... yes
checking for socketpair... yes
checking for strerror... yes
checking for strlcat... no
checking for strlcpy... no
checking for strmode... no
checking for strnvis... no
checking for strtoul... yes
checking for sysconf... yes
checking for tcgetpgrp... yes
checking for truncate... yes
checking for unsetenv... yes
checking for updwtmpx... yes
checking for utimes... (cached) yes
checking for vhangup... yes
checking for vsnprintf... yes
checking for waitpid... yes
checking for gai_strerror... yes
checking for library containing nanosleep... none required
checking whether strsep is declared... yes
checking for strsep... yes
checking whether getrusage is declared... no
checking whether tcsendbreak is declared... yes
checking whether h_errno is declared... yes
checking for setresuid... yes
checking if setresuid seems to work... yes
checking for setresgid... yes
checking if setresgid seems to work... yes
checking for gettimeofday... yes
checking for time... yes
checking for endutent... yes
checking for getutent... yes
checking for getutid... yes
checking for getutline... yes
checking for pututline... yes
checking for setutent... yes
checking for utmpname... yes
checking for endutxent... yes
checking for getutxent... yes
checking for getutxid... yes
checking for getutxline... yes
checking for pututxline... yes
checking for setutxent... yes
checking for utmpxname... yes
checking for daemon... yes
checking for getpagesize... yes
checking whether snprintf correctly terminates long strings... yes
checking whether system supports SO_PEERCRED getsockopt... yes
checking for (overly) strict mkstemp... yes
checking if openpty correctly handles controlling tty... yes
checking whether getpgrp requires zero arguments... yes
checking OpenSSL header version... 1010100f (OpenSSL 1.1.1 11 Sep 2018)
checking OpenSSL library version... 1010100f (OpenSSL 1.1.1 11 Sep 2018)
checking whether OpenSSL's headers match the library... no
configure: error: Your OpenSSL headers do not match your library.
Check config.log for details.
Also see contrib/findssl.sh for help identifying header/library mismatches.
Error: sshd not built!
Add TinySSH support (https://tinyssh.org/). Currently, the tool thinks it is OpenSSH and makes recommendations to add algorithms it doesn't have.
With #29 I got the mypy check at least running again, and it now shows:
Found 189 errors in 1 file (checked 1 source file)
What is your take on typing?
Currently, tox runs the mypy checks, but I changed the tox setting so it does not fail the tox run.
Maybe this is something to look into once Python 2 is dropped completely and then one could use type annotations instead of type comments?
This is an area in Python I have not much experience yet, as I mostly worked in Python 2 code bases until recently.
I just saw the following code
unused = None # pylint: disable=unused-variable
unused2 = None # pylint: disable=unused-variable
unused, unused2, err = s.get_banner()
In Python, for variables which value does not matter, usually you use an underscore.
So, above code could (and should) be rewritten into
_, _, err = s.get_banner()
P.S.: I did not update the code as I am in midst of the typing issue. Maybe you want to label this one as "good-first-issue"?
As @thecliguy detailed in this response, the policy output should be improved.
In #5 you mentioned:
Python 3.5 is the minimum version I'm supporting.
What does this mean to Python 2.7?
Lines 37 to 51 in bbc4ab5
Originally posted by @jtesta in #5 (comment)
After fixing all the other tests and make tox run again, there is one failing test left, which unfortunately is not super easy to fix without further research (at least not for me).
I marked test_ssh2_server_simple
to be skipped in test runs (temporarily), so at least, when working on new features, there is working test suite, now.
ssh-audit.py
is now over 3,500 lines long. It's time to split it into multiple files to make development and maintenance easier.
I've no particular interest in using GSSAPI key exchange algorithms and can't claim to understand how they work, my question simply concerns whether ssh-audit
should be capable of detecting these algorithms if present...
I've been working with Bitvise SSH Server version 8.43 and noticed that there are six gss-*
Key Exchange Algorithms (four of which are enabled by default):
Enabled by default:
1. gss-gex-sha1 with Kerberos
2. gss-group15-sha512 with Kerberos
3. gss-group14-sha256 with Kerberos
4. gss-group14-sha1 with Kerberos
Disabled by default:
5. gss-group16-sha512 with Kerberos
6. gss-group1-sha1 with Kerberos
When I audit a machine running Bitvise SSH Server, the four enabled gss-*
algorithms are not detected. I'm not sure if this is because the server lacks some prerequisite for presenting these KEX algorithms or if ssh-audit
is failing to detect them.
I've checked the ssh-audit
catalogue of KEX algorithms (SSH2.KexDB.ALGORITHMS['kex']
) to see whether it contains these algorithms. I think that 1, 4 and 6 are present but the others are not:
Bitvise KEX Name Equivalent ssh-audit KEX Name
---------------- -----------------------------
1. gss-gex-sha1 with Kerberos gss-gex-sha1-
2. gss-group15-sha512 with Kerberos ?
3. gss-group14-sha256 with Kerberos ?
4. gss-group14-sha1 with Kerberos gss-group14-sha1-
5. gss-group16-sha512 with Kerberos ?
6. gss-group1-sha1 with Kerberos gss-group1-sha1-
I've also looked into OpenSSH's (version 8.2p1) GSSAPI Key Exchange implementation, man sshd_config
:
GSSAPIKexAlgorithms
The list of key exchange algorithms that are accepted by GSSAPI key exchange. Possible values are
gss-gex-sha1-,
gss-group1-sha1-,
gss-group14-sha1-,
gss-group14-sha256-,
gss-group16-sha512-,
gss-nistp256-sha256-,
gss-curve25519-sha256-
The default is “gss-gex-sha1-,gss-group14-sha1-”. This option only applies to protocol version 2 connections using GSSAPI
Again, the ssh-audit
catalogue of KEX algorithms (SSH2.KexDB.ALGORITHMS['kex']
) seems to contain some of the algorithms but not others:
OpenSSH Algorithm Name Present in ssh-audit?
---------------------- ---------------------
1. gss-gex-sha1- Yes
2. gss-group1-sha1- Yes
3. gss-group14-sha1- Yes
4. gss-group14-sha256- No
5. gss-group16-sha512- No
6. gss-nistp256-sha256- No
7. gss-curve25519-sha256- No
So my questions are:
ssh-audit
be capable of detecting enabled GSSAPI key exchange algorithms?SSH2.KexDB.ALGORITHMS['kex']
?Hi @jtesta
I just discovered the client hardening mode.
I run Ubuntu 18.04 on my laptop.
I applied the changes from your hardening guide
https://www.ssh-audit.com/hardening_guides.html#ubuntu_18_04_linux_mint_19
and then I started the client audit via python3.8 ssh-audit.py -c
and then on a second terminal, I sshed into localhost port 2222.
Expected
I expected all output to be green.
what I got
# general
(gen) client IP: 127.0.0.1
(gen) banner: SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
(gen) software: OpenSSH 7.6p1
(gen) compression: enabled ([email protected], zlib)
# key exchange algorithms
(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) [email protected] -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256 -- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group-exchange-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
`- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) ext-info-c
# host-key algorithms
(key) [email protected] -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7
(key) [email protected] -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7
(key) [email protected] -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7
(key) [email protected] -- [info] available since OpenSSH 6.5
(key) [email protected] -- [info] available since OpenSSH 5.6
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ecdsa-sha2-nistp384 -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ecdsa-sha2-nistp521 -- [fail] using weak elliptic curves
`- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
(key) rsa-sha2-512 -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 -- [info] available since OpenSSH 7.2
(key) ssh-rsa -- [fail] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
# encryption algorithms (ciphers)
(enc) [email protected] -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) [email protected] -- [info] available since OpenSSH 6.2
(enc) [email protected] -- [info] available since OpenSSH 6.2
# message authentication code algorithms
(mac) [email protected] -- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 6.2
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) [email protected] -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 6.2
(mac) [email protected] -- [warn] using encrypt-and-MAC mode
`- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) [email protected] -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
`- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# algorithm recommendations (for OpenSSH 7.6)
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove
(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove
(rec) [email protected] -- key algorithm to remove
(rec) -ecdsa-sha2-nistp384 -- key algorithm to remove
(rec) [email protected] -- key algorithm to remove
(rec) -ecdsa-sha2-nistp521 -- key algorithm to remove
(rec) [email protected] -- key algorithm to remove
(rec) -ssh-rsa -- key algorithm to remove
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove
(rec) -hmac-sha1 -- mac algorithm to remove
(rec) [email protected] -- mac algorithm to remove
(rec) -hmac-sha2-256 -- mac algorithm to remove
(rec) -hmac-sha2-512 -- mac algorithm to remove
(rec) [email protected] -- mac algorithm to remove
(rec) [email protected] -- mac algorithm to remove
(rec) [email protected] -- mac algorithm to remove
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>
My ssh config contains some jumphost configurtations, and then on the bottom your suggested changes which I echoed into the file.
# lots of hosts...
Host xxx
Hostname 192.168.1.220
ProxyJump yyy
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
MACs [email protected],[email protected],[email protected]
HostKeyAlgorithms ssh-ed25519,[email protected],rsa-sha2-256,rsa-sha2-512,[email protected]
I tried to google about client hardening, but almost all information out there is about server hardening.
Any hint for me what to do?
Thanks!
In #29 I disabled all Flake8 warnings for now - as there are just too many. The plan is to tackle them one by one once the test suite is passing again.
Also, in future setup.py
and the tests should be linted.
While most of the issues are easy to fix, @jtesta maybe you want to have a look at the dictionary key 'ecdsa-sha2-1.3.132.0.10' - which seems to be declared twice. This easy to avoid issue shows that it is very desirable to get a working linter and test suite back again.
948 E117 over-indented
26 E126 continuation line over-indented for hanging indent
50 E128 continuation line under-indented for visual indent
2 E226 missing whitespace around arithmetic operator
8 E231 missing whitespace after ','
24 E251 unexpected spaces around keyword / parameter equals
24 E261 at least two spaces before inline comment
20 E265 block comment should start with '# '
2 E301 expected 1 blank line, found 0
6 E302 expected 2 blank lines, found 1
8 E303 too many blank lines (2)
1 E305 expected 2 blank lines after class or function definition, found 1
1 E711 comparison to None should be 'if cond is not None:'
2 E712 comparison to False should be 'if cond is False:' or 'if not cond:'
3 E722 do not use bare 'except'
4 E741 ambiguous variable name 'l'
2 F601 dictionary key 'ecdsa-sha2-1.3.132.0.10' repeated with different values
14 F841 local variable 'e' is assigned to but never used
4 W504 line break after binary operator
7 W605 invalid escape sequence '\s'
1156
As of OpenSSH 8.2, there is now notice that ssh-rsa will be deprecated in the near future.
https://www.openssh.com/releasenotes.html
It is now possible[1] to perform chosen-prefix attacks against the
SHA-1 hash algorithm for less than USD$50K. For this reason, we will
be disabling the "ssh-rsa" public key signature algorithm that depends
on SHA-1 by default in a near-future release.
Is there any switch/flag that I can call a list of IP's to perform this audit ??
python3 ssh-audit.py --json -p 22 127.0.0.1
Traceback (most recent call last):
File "/home/luke/documents/python/ape-web/Tools/ssh/ssh-audit/ssh-audit.py", line 3350, in
main()
File "/home/luke/documents/python/ape-web/Tools/ssh/ssh-audit/ssh-audit.py", line 3347, in main
audit(conf)
File "/home/luke/documents/python/ape-web/Tools/ssh/ssh-audit/ssh-audit.py", line 3337, in audit
print(json.dumps(build_struct(banner, kex=kex, client_host=s.client_host), sort_keys=True))
File "/home/luke/documents/python/ape-web/Tools/ssh/ssh-audit/ssh-audit.py", line 3245, in build_struct
for host_key_type in host_keys.keys():
RuntimeError: dictionary keys changed during iteration
Similar to #24 but for word documents instead. Same output from the audits but generating different type of report able to be formatted in MS Word, LibreOffice, etc.
Yeah, SSH client 'ControlMaster' should also be checked as 'disabled' as well.
Just unclear as how to enable an SSH client to see if such server can support 'ControlMaster'
IMHO, ControlMaster should have been compiled out by default. But they took that compile options out way back in OpenSSH v3.9.
In my bash alias file, I have the following:
alias ssh='ssh -o "ControlMaster=no" -o "ControlPath=/dev/null" -o "ControlPersist=0"'
Currently running ssh-audit --port=22 example.com
would fail with the error option --port must not have an argument
Travis CI needs to be enabled on this repo. This may take quite a lot of tweaking to get working...
It should be possible for an input file to be given to the tool, with a list of target servers inside. This would make policy scanning of many machines very easy to do.
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521 are claimed as 'weak' when enabled in HostKeyAlgorithms. But OpenSSH directs to use them as one of possible algorithms (see: https://www.openssh.com/txt/release-8.2):
The better alternatives include:
The RFC8332 RSA SHA-2 signature algorithms rsa-sha2-256/512. These
algorithms have the advantage of using the same key type as
"ssh-rsa" but use the safe SHA-2 hash algorithms. These have been
supported since OpenSSH 7.2 and are already used by default if the
client and server support them.
The ssh-ed25519 signature algorithm. It has been supported in
OpenSSH since release 6.5.
The RFC5656 ECDSA algorithms: ecdsa-sha2-nistp256/384/521. These
have been supported by OpenSSH since release 5.7.
I assume this is the issue, but am using your script to test vulnerability fixes on some Solaris hosts and the ones with Openssh installed work correctly. On the hosts with sun_ssh I get:
ssh-audit.py solaristst2
Traceback (most recent call last):
File "/usr/local/bin/ssh-audit.py", line 3016, in <module>
audit(conf)
File "/usr/local/bin/ssh-audit.py", line 3007, in audit
SSH2.HostKeyTest.run(s, kex)
File "/usr/local/bin/ssh-audit.py", line 625, in run
SSH2.HostKeyTest.__test(s, server_kex, kex_str, kex_group, SSH2.HostKeyTest.HOST_KEY_TYPES)
File "/usr/local/bin/ssh-audit.py", line 670, in __test
host_key = kex_group.recv_reply(s, variable_key_len)
File "/usr/local/bin/ssh-audit.py", line 2205, in recv_reply
raise Exception('Expected MSG_KEXDH_REPLY (%d) or MSG_KEXDH_GEX_REPLY (%d), but got %d instead.' % (SSH.Protocol.MSG_KEXDH_REPLY, SSH.Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
Exception: Expected MSG_KEXDH_REPLY (31) or MSG_KEXDH_GEX_REPLY (33), but got 4 instead.
Installed ssh is:
root@solaristst2:~# ssh -V
Sun_SSH_2.4, SSH protocols 1.5/2.0, OpenSSL 0x100020cf
System isn't fully updated but is fairly recent:
SunOS solaristst2 5.11 11.3 sun4v sparc sun4v
A system that returned usable info is set up as:
root@solarisprd2:# uname -a
SunOS solarisprd2 5.11 11.4.2.3.0 sun4v sparc sun4v
root@solarisprd2:# ssh -V
OpenSSH_7.5p1, OpenSSL 1.0.2p 14 Aug 2018
Let me know if there's any other data/info you need or how I could help.
@jtesta Hi Joe,
At the end of July you mentioned that you were hoping to release v2.3.0.
Are there some specific issues that you want to close before releasing v2.3.0? If so, perhaps they could be tagged as milestones.
The CONTRIBUTING guide says to submit pull requests to the dev
branch - but there doesn't seem to be a dev
branch anymore.
So do we develop against master
now?
Hi Joe,
The tool currently suggests recommended settings for OpenSSH 7.6 but I currently have OpenSSH_8.0p1, OpenSSL 1.1.1c 28 May 2019
, so it would be great to have up-to-date kex/mac/etc recommendations what to enable, disable, and so on. There might be such in the official docs but the tool should make it easy to find them via its output.
# algorithm recommendations (for OpenSSH 7.6)
...
First of all I want to say I love your script.
On Ubuntu 18.04 LTS systems (+latest updates) = SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3 ,
with your latest ssh-audit (2.2.0) , there is some issue with -ssh-rsa, that isnt there on Debian.
I think it could be related to a bug in the OpenSSH version.
I can't follow the hardening guide directly to remove my RSA host key entirely, so I have just re-generated it with 4096 bit, but still ran into an issue.
No amount of sshd_config configuration will simultaneously allow me to keep the rsa-sha2 version active while disabling the weak sha1 one. I believe its due to the confusion between "ssh-rsa" and "rsa-sha2" (indirectly mentioned on here https://utcc.utoronto.ca/~cks/space/blog/tech/OpenSSHAndSHA1Deprecation and possibly related to this bug differentiating the two, which persists on ALL my systems, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854650 )
On Ubuntu 18.04 LTS The script reports this:
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
(key) ssh-rsa (4096-bit) -- [fail] using weak hashing algorithm
- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) rsa-sha2-512 (4096-bit) -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (4096-bit) -- [info] available since OpenSSH 7.2
...
# algorithm recommendations (for OpenSSH 7.6)
(rec) -ssh-rsa -- key algorithm to remove
In the sshd_config, I have this Line (also for HostBasedAcceptedKeyTypes):
HostKeyAlgorithms [email protected],[email protected],ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
Removing ONLY the "ssh-rsa" off the end of the line, results in ALL of my RSA host key being completely disabled. The script reports that all three RSAs get removed, even the SHA2 ones that were OK.
This behavior doesn't add up, because doing the same thing on Debian 10 Buster = SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2 works properly and does NOT result in this complete RSA disablement, and the config files are otherwise identical.
I can only assume theres an issue in this Ubuntu 7.6 version of OpenSSH and if thats the case, your script needs to know about it, so it can issue a warning saying disabling the weak one will also disable the safe ones.
Running ssh-keygen -lf ssh_host_rsa_key
produces 4096 SHA256:XXYYZZABC123etc so I'm pretty sure the key itself is valid SHA2.
If you know of a workaround or would like me to test any further stuff, let me know.
Thank You for undertaking this security project. Also, I support you and all your endeavors, after I found out about your valiant failed attempts to get DJM to add X448 curves on the OpenSSH mailing list, and then the dead maintainer on the old broken audit script, which you succeeded with on Debian. Keep up the good work!
I'm using ssh-audit --lookup=
to look up information on all the supported algorithms (encryption ciphers, key exchange, host key and MAC) in WinSCP 5.17.7.
A list of WinSCP's supported algorithms can be produced using the command:
"C:\Program Files (x86)\WinSCP\WinSCP.com" /info
.
There is one algorithm supported by WinSCP that's not present in the ssh-audit database which is the encryption algorithm [email protected]
.
A comment in the WinSCP source code suggests that des-cbc
and [email protected]
are the same thing: /* Same as ssh_des_cbc, but with a different SSH-2 ID */
, see: https://github.com/winscp/winscp/blob/master/source/putty/sshdes.c#L693-L704
The SSH-2 ID
referred to in the comment relates to the ninth property of an ssh_cipheralg
struct:
The ssh-audit database already contains des-cbc
, do you have any objection to adding [email protected]
so it's possible to run a complete audit of WinSCP?
Not working function - cleint-audit. Error:
ssh-audit --client-audit --timeout=300 --verbose
# general
(gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0
[exception] error reading packet (empty)
Check with python 3.7 and python 3.8.
Running with -j
or --json
with Python 3.8.x cause the following error
± ./ssh-audit.py -j raspberrypi2.local
Traceback (most recent call last):
File "./ssh-audit.py", line 3350, in <module>
main()
File "./ssh-audit.py", line 3347, in main
audit(conf)
File "./ssh-audit.py", line 3337, in audit
print(json.dumps(build_struct(banner, kex=kex, client_host=s.client_host), sort_keys=True))
File "./ssh-audit.py", line 3245, in build_struct
for host_key_type in host_keys.keys():
RuntimeError: dictionary keys changed during iteration
The code in question is
Lines 3245 to 3249 in e447c42
The fix for the immediate is straightforward, replace host_keys.keys()
with list(host_keys.keys())
so the loop iterates over a copy.
However, I'm concerned about the rest of the loop. I think its
I need to confirm whether an ssh server can have multiple RSA keys (perhaps with different key lengths).
Other details
± python3 --version
Python 3.8.2
± git show --summary | cat
commit e447c42a79df49841d5269eacde6dbeb811a6be4
Author: Joe Testa <[email protected]>
Date: Wed Mar 11 11:55:14 2020 -0400
Bumped version to v2.2.0.
This is what's in my sshd config, I've taken the values from the value taken from https://www.ssh-audit.com/hardening_guides.html#ubuntu_18_04_lts :
root@hex-bastion2:/etc/ssh# grep -i Hostkey sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKeyAlgorithms ssh-ed25519,[email protected]
what the program does?
[root@d213856bed13 /]# ssh-audit -p 2022 example.com #
# general
(gen) banner: SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
(gen) software: OpenSSH 7.6p1
[exception] error reading packet (empty)
where's the server says:
Mar 30 21:44:01 hex-bastion2 sshd[10221]: rexec line 29: Deprecated option UsePrivilegeSeparation
Mar 30 21:44:01 hex-bastion2 sshd[10221]: rexec line 60: Deprecated option UseLogin
Mar 30 21:44:01 hex-bastion2 sshd[10221]: fatal: No supported key exchange algorithms [preauth]
minimal working example, the program gives the same output:
root@hex-bastion2:/etc/ssh# grep -i Hostkey sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKeyAlgorithms [email protected]
Commenting out HostKeyAlgorithms makes the program run fine.
This is a fresh pip install
in a archlinux:latest
docker container.
cast128-ctr and blowfish-ctr (correctly) fail in the client (-c) report:
[snipped]
(enc) [email protected] -- [info] available since OpenSSH 6.2
(enc) [email protected] -- [info] available since OpenSSH 6.2
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) blowfish-ctr -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
- [fail] disabled since Dropbear SSH 0.53
- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
- [warn] using weak cipher mode
- [warn] using small 64-bit block size
(enc) cast128-ctr -- [fail] deprecated cipher
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
- [warn] using weak cipher
But aren't mentioned in the recommendations report:
(rec) -arcfour -- enc algorithm to remove
A peek at the code doesn't show any obvious reason why this should happen, and I know it's minor, but the program is otherwise so thorough I felt I should let you know.
When SSHv1 is found, only a message in red is displayed in the general information section that it is enabled.
A recommendation should be included that suggests it be disabled entirely. Furthermore, perhaps a CVE exists for the version 2 -> version 1 downgrade attack?
Hi @jtesta,
According to opnsense/core#3975, there will be new SSH config options in OPNsense 20.7, so it'd be great to add these to the common OS list at https://www.ssh-audit.com/hardening_guides.html maybe below pfSense (as OPNsense is its fork).
Until the new settings are released, users can enable them by running these commands on their OPNsense box/vm:
opnsense-patch 5df590c
opnsense-patch 1165119
service configd restart
As there are no ordering in the chosen algos (limitation of the UI), advanced users that mess with these settings should pick their choices to be the most hard that their SSH clients support. I'm happy that they added support to tweaking these at least.
This will help maintainers of the package.
Hi,
when upgrading the used pytest
version, the following warning is issued:
.tox/py38-test/lib/python3.8/site-packages/_pytest/junitxml.py:417
/home/jugmac00/Projects/ssh-audit/.tox/py38-test/lib/python3.8/site-packages/_pytest/junitxml.py:417: PytestDeprecationWarning: The 'junit_family' default value will change to 'xunit2' in pytest 6.0.
Add 'junit_family=xunit1' to your pytest.ini file to keep the current format in future versions of pytest and silence this warning.
_issue_warning_captured(deprecated.JUNIT_XML_DEFAULT_FAMILY, config.hook, 2)
Is it ok to drop the xml generation or do you use it?
It is triggered by
test: pytest -v --junitxml={toxinidir}/reports/junit.{envname}.xml {posargs:test}
=> I currently set pytest
< 6.0
We need a CONTRIBUTING.md file to tell new developers about our tox tests, docker tests, unit tests, and documentation (these would be nice for them to update as necessary, but not strictly required).
Some of us wants the sshd_config
to get to the point of 'maximum' security before customization so I've included the OpenSSH server config file here for your enjoyment:
Output of this ssh_audit.py
is ALL GREEN:
# general
(gen) banner: SSH-2.0-OpenSSH_7.9p1 Debian-10
(gen) software: OpenSSH 7.9p1
(gen) compatibility: OpenSSH 7.3+, Dropbear SSH 2016.73+
(gen) compression: disabled
# key exchange algorithms
(kex) [email protected] -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62
(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
# host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
(key) rsa-sha2-512 (2048-bit) -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (2048-bit) -- [info] available since OpenSSH 7.2
(key) ssh-rsa (2048-bit) -- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
# encryption algorithms (ciphers)
(enc) [email protected] -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
(enc) [email protected] -- [info] available since OpenSSH 6.2
# message authentication code algorithms
(mac) [email protected] -- [info] available since OpenSSH 6.2
(mac) [email protected] -- [info] available since OpenSSH 6.2
# fingerprints
(fin) ssh-ed25519: SHA256:+vw/a0wCEwzjzPw/DZcM3m2NEQ7QFjI18aq1+0nsrKQ
(fin) ssh-rsa: SHA256:s1ODbwUBztZ1qE7N9J3fmO5avWcK7rPTunACXSkHYJ4
# algorithm recommendations (for OpenSSH 7.9)
(rec) +aes128-ctr -- enc algorithm to append
(rec) [email protected] -- enc algorithm to append
(rec) +aes192-ctr -- enc algorithm to append
(rec) +aes256-ctr -- enc algorithm to append
(rec) +curve25519-sha256 -- kex algorithm to append
(rec) +diffie-hellman-group-exchange-sha256-- kex algorithm to append
(rec) [email protected] -- mac algorithm to append
sshd_config
for the above ALL green is:
# Package generated configuration file
# See the sshd_config(5) manpage for details
# What ports, IPs and protocols we listen for
Port 22
# Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_ed25519_key
# Note: As soon as mobile can support ed25519, turn off RSA
HostKey /etc/ssh/ssh_host_rsa_key
# HostKey /etc/ssh/ssh_host_ecdsa_key
# HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
# UsePrivilegeSeparation yes # deprecated v7.9
# Lifetime and size of ephemeral version 1 server key
# KeyRegenerationInterval 3600 # deprecated v7.9
# ServerKeyBits 2048 # deprecated v7.9
# Logging
SyslogFacility AUTH
# LogLevel INFO
LogLevel VERBOSE
# Authentication:
LoginGraceTime 35
PermitRootLogin no
StrictModes yes
# RSAAuthentication no # deprecated v7.9
PubkeyAuthentication yes
# Be explicit with AuthorizedKeysFile config item, never its default
#AuthorizedKeysFile %h/.ssh/authorized_keys
AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
# RhostsRSAAuthentication no # deprecated v7.9
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd yes
PrintLastLog yes
TCPKeepAlive no
#UseLogin no
#MaxStartups 10:30:60
Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
IgnoreUserKnownHosts no
GatewayPorts no
AllowTcpForwarding no
KeepAlive yes
AllowGroups ssh
# Need to execute the following commands for safer KexAlgorithms
# ssh-keygen -G moduli-2048.candidates -b 2048
# ssh-keygen -T moduli-2048 -f moduli-2048.candidates
#
# KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
KexAlgorithms [email protected],diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256
# diffie-hellman-group1-sha1
# diffie-hellman-group14-sha1
# diffie-hellman-group14-sha256
# diffie-hellman-group16-sha512
# diffie-hellman-group18-sha512
# diffie-hellman-group-exchange-sha1
# diffie-hellman-group-exchange-sha256
# ecdh-sha2-nistp256
# ecdh-sha2-nistp384
# ecdh-sha2-nistp521
# diffie-hellman-group1-sha1
# [email protected]
Ciphers [email protected],[email protected]
# Following MACs does not work on Mac OSX 10.10 or older
# MACs [email protected],[email protected],[email protected],hmac-sha1 (old)
MACs [email protected],[email protected]
# UsePrivilegeSeparation sandbox # deprecated v7.9
# LEO customizations
DenyUsers root
DenyGroups root
ClientAliveInterval 600
ClientAliveCountMax 3
Compression no
MaxAuthTries 4
MaxSessions 3
AllowAgentForwarding no
PermitUserEnvironment no
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes # default
PasswordAuthentication yes
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
# ChallengeResponseAuthentication no # default
ChallengeResponseAuthentication yes
❯ python3.8 ssh-audit.py xx.xxx.xxx.xxx -p 22022 --json
Traceback (most recent call last):
File "ssh-audit.py", line 3103, in <module>
main()
File "ssh-audit.py", line 3099, in main
audit(conf)
File "ssh-audit.py", line 3088, in audit
print(json.dumps(build_struct(banner, kex=kex, client_host=s.client_host), sort_keys=True))
File "ssh-audit.py", line 2996, in build_struct
for host_key_type in host_keys.keys():
RuntimeError: dictionary keys changed during iteration
This is reproducible for one of my old, inherited SSH Servers, but not for the new one, which I configured after your guide.
I can provide you the address in private if you need it to debug.
Anyway, the problem is pretty obvious, and the exception says it clearly. It is no good idea to change an Iterable while iterating over it.
The fix is trivial - just wrap host_keys.keys()
from above in a list()
.
The above line is not covered by a test, though, as all the JSON generation. So, this is good chance to raise test coverage.
I'll try to find some time and create a PR for this issue.
Add the recently released Github Super Linter https://github.com/github/super-linter for python as a GH action (it's in the GH Action Marketplace).
From their README:
The end goal of this tool:
Prevent broken code from being uploaded to the default branch (Usually master)
Help establish coding best practices across multiple languages
Build guidelines for code layout and format
Automate the process to help streamline code reviews
Proposed technical implementation details (optional)
Just add the action and choose the linters for usage. For this project that should include pylint and mypy. You could optionally add others but those two provide the most coverage. I noticed usage of mypy at least has already started. So this helps provide linter errors in PRs.
It would be great if there are installation instructions.
I discovered that on Mac with Homebrew you can do: brew install ssh-audit
On Debian and Ubuntu you can do: apt install ssh-audit
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.