Inspect Full Remote SSL Certificate Details via OpenSSL CLI
curl's verbose mode (-vvI) only exposes basic certificate common names during HTTPS connections, making it insufficient for verifying issuer chains, validity dates, Subject Alternative Names, or signature algorithms. OpenSSL's s_client combined with openssl x509 provides complete x509 certificate metadata from the command line without requiring a browser. This technique is applicable to diagnostics, automation scripts, and certificate monitoring pipelines.
Indicators
- curl -vvI only shows certificate common names, not full certificate metadata
- Unable to verify SSL certificate validity dates, issuer, or SANs from the CLI
- Need to confirm certificate properties on a remote host without browser access
- Browser displays full certificate details but no equivalent CLI output is available
- Uncertainty whether the correct certificate is being served on a multi-virtual-host server
Likely causes
- curl is designed for connection-level inspection and does not expose full x509 certificate fields
- No native curl flag exists to dump complete certificate metadata in human-readable form
- SNI (Server Name Indication) not being specified may cause the server to return the wrong certificate on shared-hosting or multi-vhost environments
Diagnostic steps
-
Confirm the limitation of curl output: run 'curl -vvI https://gnupg.org' and observe that only certificate common names are shown, with no validity dates, SANs, or issuer chain detail.
-
Use openssl s_client to retrieve the full certificate chain in PEM format: echo | openssl s_client -showcerts -servername gnupg.org -connect gnupg.org:443 2>/dev/null
-
Pipe the PEM output through openssl x509 to parse and display all certificate fields: echo | openssl s_client -showcerts -servername gnupg.org -connect gnupg.org:443 2>/dev/null | openssl x509 -inform pem -noout -text
-
Review the parsed output for: Subject, Issuer, Validity (Not Before / Not After), Subject Alternative Names (SANs), Public Key algorithm, and Signature algorithm.
-
If the target server hosts multiple virtual hosts, verify the -servername parameter exactly matches the intended hostname to ensure SNI triggers selection of the correct certificate.
-
To check expiry dates only (useful in monitoring scripts), run: echo | openssl s_client -servername gnupg.org -connect gnupg.org:443 2>/dev/null | openssl x509 -noout -dates
Resolution path
- Run the full inspection command: echo | openssl s_client -showcerts -servername <hostname> -connect <hostname>:443 2>/dev/null | openssl x509 -inform pem -noout -text
- The -showcerts flag instructs s_client to output the full certificate chain in PEM format, not just the leaf certificate.
- The -servername flag sets the TLS SNI extension, ensuring the server returns the certificate associated with the target hostname on shared or multi-vhost infrastructure.
- Redirecting stderr to /dev/null (2>/dev/null) suppresses TLS handshake noise and connection state output, isolating the PEM certificate block.
- Piping through openssl x509 -inform pem -noout -text decodes the PEM block into human-readable x509 field output.
- For expiry-only checks in scripts, substitute '-text' with '-noout -dates' to return only the Not Before and Not After fields.
Prevention
- Standardise on openssl s_client as the CLI tool for certificate inspection in runbooks, automation, and monitoring scripts rather than relying on curl.
- Always include the -servername parameter when connecting to any SNI-enabled server to guarantee the correct certificate is retrieved.
- Incorporate certificate expiry monitoring using 'openssl x509 -noout -dates' in CI/CD pipelines or infrastructure health checks to detect expiring certificates before they cause outages.
- Document the full openssl inspection command in team runbooks so engineers do not default to incomplete curl output during incident triage.
- For internal PKI environments, extend this technique to non-443 ports (e.g., LDAPS on 636, SMTP on 587) by adjusting the -connect port parameter accordingly.
Tools
- openssl s_client
- openssl x509
- curl
- echo (provides empty stdin to allow openssl s_client to complete the handshake and exit)