Tools · Nmap and network discovery · 15 / 25
How to check TLS versions and ciphers with nmap ssl-enum-ciphers
Run ssl-enum-ciphers against your own HTTPS, SMTP, and LDAPS services, read the letter grades, and disable TLS 1.0 and 1.1 with confidence.
What the script does
ssl-enum-ciphers connects repeatedly to a TLS service, offering one protocol version and cipher at a time, and records what the server accepts. It prints every accepted cipher suite grouped by protocol, with a letter grade from A to F based on key exchange strength and cipher properties, and a least-strength grade for the whole server.
It works on any port that speaks TLS directly: 443, 465, 636, 993, 995, 8443. For services that upgrade with STARTTLS, such as SMTP on 25 or 587, Nmap negotiates the upgrade first when the service is recognized.
sudo nmap -sV -p 443,465,636,993 --script ssl-enum-ciphers 192.168.56.101
Reading the output
Look first at the protocol headings. TLSv1.0 and TLSv1.1 were formally deprecated by RFC 8996 in 2021, and modern browsers refuse them. If they appear, the server still accepts them. Next, read the warnings: “Broken cipher RC4 is deprecated”, “64-bit block cipher 3DES vulnerable to SWEET32”, or “Key exchange of lower strength than certificate key”.
TLS 1.3 suites are always strong and the list is short. Most real-world configuration work is about pruning TLS 1.2 down to ECDHE key exchange with AES-GCM or ChaCha20-Poly1305.
Lab: weaken, scan, fix, rescan
On an nginx lab VM, set ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 and reload. Scan and confirm the old protocols appear with a lower grade. Then change to ssl_protocols TLSv1.2 TLSv1.3 and a modern cipher list, reload, and rescan.
Before tightening real servers, check which clients still connect with old protocols. Web server logs can record the negotiated protocol, for example $ssl_protocol in nginx’s log_format. If nothing has used TLS 1.0 for a month, disabling it is low risk.
# /etc/nginx/conf.d/tls.conf ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off; sudo nginx -t && sudo systemctl reload nginx sudo nmap -p 443 --script ssl-enum-ciphers 192.168.56.101
Pair it with certificate checks
ssl-cert prints the certificate subject, issuer, validity dates, and key size. Run it together with ssl-enum-ciphers to catch expiring certificates and 1024-bit keys in the same pass.
For public sites, an external scanner sees the configuration that clients see, including CDN or load balancer termination. Scan both the origin and the edge when they differ.
Diagram
A TLS listener before and after hardening
What ssl-enum-ciphers reports.
Protocols. TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3
Warnings. 3DES SWEET32, CBC suites
Least strength. C
Protocols. TLSv1.2, TLSv1.3
Suites. ECDHE with AES-GCM or ChaCha20-Poly1305
Least strength. A
Check yourself
1. Which protocol versions should a modern public HTTPS server accept?
2. ssl-enum-ciphers warns about SWEET32. Which cipher is the cause?
3. What should you check before disabling TLS 1.0 on a production server?