testssl.sh
testssl.sh copied to clipboard
Client simulations send inappropriate ALPN to non-http services
I am running testssl.sh 3.2rc2 from https://testssl.sh/dev/, commit f0e1540bc656b44c73b806070cf429f7bd796a5e.
I am running testssl.sh against a mail service (POP3 and IMAP) behind nginx as a reverse proxy. Since nginx 1.21.4, this results in incorrect "No connection" for many client simulations. This is because several client simulations include ALPN in their client hello with services "http/1.1" and "h2", which is not appropriate for non-http services, and recent nginx rejects this to mitigate an ALPACA attack (behaviour recommended by RFC 7301).
A minimal nginx config to reproduce this: (doesn't need an actual working auth_http backend)
pid /tmp/nginx.pid;
events {}
mail {
auth_http localhost;
server {
listen 995 ssl;
protocol pop3;
ssl_certificate server.pem;
ssl_certificate_key server.key;
}
}
And run testssl -c localhost:995
against this:
Android 6.0 No connection
Android 7.0 (native) No connection
Android 8.1 (native) TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 253 bit ECDH (X25519)
Android 9.0 (native) No connection
Android 10.0 (native) No connection
Android 11 (native) No connection
Android 12 (native) No connection
...
This produces connection failures even if the server is configured with protocols/ciphers that in reality allow these clients. The simulation only fails because of the incorrect ALPN extension issued by testssl when using sockets.
The generic OS clients in client-simulation.txt should probably omit the ALPN extension in their handshake, or have an alternative handshake without ALPN for non-https testing (or with an application-specific ALPN if a mailclient eg. Thunderbird is observed to send it).
For comparison, testssl --ssl-native -c localhost:995
does not issue ALPN, and gives a more correct view on the client handshakes (within the limitations of the used openssl version).
Other mail servers (eg. postfix, dovecot, ...) ignore ALPN and can be tested just fine, only nginx recently added this extra check for security.
Hi Geert,
Looks like we want to remove the extension under some, to be defined, circumstances. If we don't want to remove that completely in ./etc/clientsimulation,txt it needs to be handled somewhere e.g. in client_simulation_sockets()
or run_client_simulation
.
The circumstances though are not quite clear to me. The best which popped up in my mind so far was to exclude port 995, 993, 465 and the like. The handshake would be not correct though when those ports are HTTPS.
It might be an issue with STARTTLS too.
Thanks! Dirk