OpenSSL s_client Tutorial and Examples


OpenSSL is an open-source toolkit implementing the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. OpenSSL client refers to software or command-line tools within OpenSSL that can connect to servers using SSL/TLS for secure communication.

OpenSSL provides a wide array of cryptographic operations like encryption, decryption, signing, and verification of digital signatures. It can generate keys, create and manage certificates, and perform various cryptographic tasks.

The s_client command within OpenSSL is specifically used for testing SSL/TLS connections.  We will demonstrate the use of the c_client of OpenSSL in this blog article.

The openssl s_client command has nearly 200 command-line options!😭😭😭

Here are some of the common options of s_client below:

-connect: Specifies host:port for connection

-servername: Specify the hostname it is trying to connect to during the TLS handshake,he server can use this information to present the appropriate SSL/TLS certificate

-cert: Client certificate file for authentication.  Used in mutual TLS (mTLS) scenarios, where both the client and server authenticate each other using certificates

-key: If the server requests a client certificate, pass a client private key file for authentication-CAfile: File with trusted CA certificates

-CApath: Provide a directory of CA certificates instead of a single file (as with -CAfile).

-showcerts: Displays server certificates when debugging, validating or testing

-debug: Detailed debugging information

-msg: Shows exchanged protocol messages

-starttls: testing and debugging protocols that begin with plaintext communication and then switch to TLS such as SMTP, IMAP, POP3, etc.

-tls1, -tls1_1, -tls1_2, -tls1_3: Forces the connection to use a specific version of the TLS protocol

-cipher <cipher>: Specifies the cipher suite to use for the connection

-state: Displays detailed SSL/TLS state information during the handshake process.

-verify <depth>: Sets the verification depth for the server certificate chain.

And many more options, as mentioned there are 200 options.

Now lets test out some basic usage of the openssl client tool.

$~ openssl s_client -connect linuxhint.com:443

Port 443 is used because it is the default port for HTTPS (HTTP Secure), which employs SSL/TLS to secure the communication between a client (like a browser or openssl s_client) and a server. Here is the output:

Brief Explanation of OpenSSL Output

Connection: Successfully connected to linuxhint.com on port 443 (HTTPS).

Certificate Chain: The chain of trust ensures that linuxhint.com is verified and trusted because its certificate was issued by Google Trust Services, a widely trusted Certificate Authority. This is why you can securely access linuxhint.com over HTTPS without certificate warnings.

Server Certificate: the actual certificate for the website (linuxhint.com) in PEM (Privacy-Enhanced Mail) format. This is the digital document presented by the server to prove its identity during the TLS handshake.

“Subject” and “Issuer”: The Subject specifies the domain (`linuxhint.com`) that the certificate secures, while the Issuer indicates that the certificate was issued and validated by Google Trust Services (`WE1`). This pairing ensures the certificate is authentic and correctly tied to the intended entity.

Client Cert: In some cases (e.g., mutual TLS), the server asks for a client certificate to verify the client’s identity. Since no CA names were sent, client authentication was not required for this connection.

Peer signing: The server’s certificate uses ECDSA (Elliptic Curve Digital Signature Algorithm) for creating a digital signature, paired with SHA256 as the hashing algorithm to ensure the certificate’s integrity and authenticity. This combination verifies that the certificate was issued by a trusted authority and has not been tampered with, providing secure and efficient authentication during the TLS handshake. The server uses the X25519 elliptic curve algorithm with a 253-bit key to securely exchange encryption keys, ensuring efficient, secure communication with forward secrecy.

SSL Handshake: The client exchanged 2831 bytes with the server to complete the TLS handshake, successfully verified the server’s certificate, and established a trusted, secure connection.

TLS connection details: This TLS 1.3 connection uses a strong cipher suite (TLS_AES_256_GCM_SHA384) and a 256-bit ECDSA public key. No compression, ALPN negotiation, or early data features were used, and the server certificate verification was successful (Verify return code: 0).

Post Handshake: A Session Ticket was received from the server after the TLS handshake. This ticket allows for session resumption in future connections, avoiding a full handshake and improving performance.

Now lets run through some more sample commands you might find useful:

openssl s_client Example Commands

Verify Server SSL/TLS Configuration

~$ openssl s_client -connect linuxhint.com:443 -showcerts

This command connects to the server at `linuxhint.com` on port 443, which is the standard HTTPS port. The `-showcerts` option displays all certificates in the chain from the server, including intermediate certificates, which helps in verifying the entire certificate path.

~$ openssl s_client -connect linuxhint.com:443 -tls1_2

Here, we specifically request that TLS version 1.2 be used for the connection. This helps in checking if the server supports and can negotiate a secure connection using this version of the TLS protocol, which is crucial for ensuring modern security standards are met.

~$ openssl s_client -connect linuxhint.com:443 -cipher AES256-SHA

This command tests whether the server accepts connections using the AES256-SHA cipher suite. It’s useful for verifying if specific encryption methods are supported, which can be important for compliance or security assessments.

Test STARTTLS for Protocols

~$ openssl s_client -connect mail.linuxhint.com:25 -starttls smtp

This command initiates an SMTP connection to the mail server at `mail.linuxhint.com` on port 25, then upgrades it to a secure connection via STARTTLS. This is crucial for ensuring that email communications are encrypted.

~$ openssl s_client -connect mail.linuxhint.com:143 -starttls imap

Similar to the SMTP test, this checks if the IMAP server supports STARTTLS for securing email retrieval connections, ensuring privacy and security in email access.

Debug and Analyze Certificates

~$ openssl s_client -connect linuxhint.com:443 -showcerts > certs.pem

This command saves all certificates presented by the server during the TLS handshake into a file named `certs.pem`. This is helpful for later analysis or troubleshooting of certificate issues offline.

~$ echo | openssl s_client -connect linuxhint.com:443 2>/dev/null | openssl x509 -noout -dates

By connecting to the server without sending actual data (`echo`), this command fetches and then parses only the certificate dates to check its validity period, ensuring the certificate hasn’t expired or isn’t prematurely valid.

Test Mutual TLS (mTLS)

~$ openssl s_client -connect linuxhint.com:443 -cert client-cert.pem -key client-key.pem

This tests mutual TLS authentication where the client also sends a certificate to the server. Here, we specify the client’s certificate and private key, which are necessary for servers that require client authentication for added security.

Test Hostname Verification (SNI)

~$ openssl s_client -connect linuxhint.com:443 -servername linuxhint.com

This command checks if Server Name Indication (SNI) works correctly, ensuring that the server returns the correct certificate for the requested hostname when multiple certificates are hosted on the same IP.

Verify Certificate Chain

~$ openssl s_client -connect linuxhint.com:443 -CAfile ca.pem

By specifying a custom CA file, this command verifies if the server’s certificate can be trusted using a particular Certificate Authority’s root or intermediate certificates, which is useful in environments with private or custom CAs.

Analyze Supported Features

~$ openssl s_client -connect linuxhint.com:443 -alpn h2

This tests if the server supports Application-Layer Protocol Negotiation (ALPN) for HTTP/2, which is essential for modern web performance optimizations.

~$ openssl s_client -connect linuxhint.com:443 -sess_out session.pem

Saves the TLS session parameters for later reuse, which can speed up subsequent connections by skipping the full handshake.

~$ openssl s_client -connect linuxhint.com:443 -sess_in session.pem

Attempts to resume a TLS session using previously saved session parameters, showcasing how session resumption can work.

Send Custom HTTP Requests

~$ openssl s_client -connect linuxhint.com:443

After connecting enter this code:

GET / HTTP/1.1
Host: linuxhint.com

After establishing a secure connection, you can manually send HTTP requests. For example to fetch the homepage.

Debug Handshake and Protocols

~$ openssl s_client -connect linuxhint.com:443 -debug

Enables low-level debugging information about the connection process, which is invaluable for diagnosing issues in SSL/TLS handshake.

~$ openssl s_client -connect linuxhint.com:443 -msg

Shows the raw messages exchanged during the TLS handshake, useful for in-depth protocol analysis.

Check SSL/TLS State

~$ openssl s_client -connect linuxhint.com:443 -state

This command prints out the internal state of the SSL/TLS connection, providing insights into what’s happening at each step of the handshake process.

Conclusion

In conclusion, OpenSSL is an open-source toolkit essential for implementing and testing SSL/TLS protocols, offering a plethora of cryptographic functionalities from encryption to digital signatures. The s_client command, with its extensive array of nearly 200 options, provides a tool set for diagnosing, verifying, and interacting with SSL/TLS configurations in various scenarios. Our blog demonstrated how to use s_client for basic connection tests, certificate verification, and protocol-specific debugging. It has utility in ensuring secure and compliant network communications.