← Back to Blog

TIL: OpenSSL can serve HTTPS

Developer Note Published July 29, 2026 2 min read
OpenSSLTLSDebuggingCommand Line

TLDR

OpenSSL includes a small TLS server:

openssl s_server \
  -accept 8443 \
  -cert ./server.pem \
  -key ./server.key \
  -www

This listens on port 8443 and returns a small status page. Connect using the hostname or IP address from your certificate.

To serve files instead, replace lowercase -www with uppercase -WWW. OpenSSL then serves requested files from the current directory, so run it only where those files are safe to expose.

Why this is useful

OpenSSL already handles certificate inspection and verification. s_server adds another useful check: it presents the certificate and uses its matching private key in a real TLS handshake.

If OpenSSL is already installed, this gives you a temporary HTTPS endpoint without setting up Nginx, Caddy, or a small application only for the test. The terminal also shows incoming handshakes and TLS alerts.

I used this while debugging local HTTPS from an Android app. The OpenSSL output showed that the phone reached the TLS handshake but rejected the development certificate. Once the app trusted the development CA, the same endpoint returned the built-in status page. That separated server reachability from client trust with one command.

Useful options

s_server has many switches. These cover the common debugging cases without reproducing the whole manual:

OptionWhen it helps
-accept [host:]portChooses the listening address and port. Omitting the host, as in -accept 8443, does not restrict the listener to loopback. Use -accept 127.0.0.1:8443 when it should stay local to the machine.
-4 / -6Usually unnecessary. Use -4 when you explicitly need IPv4, or -6 when you explicitly need IPv6.
-cert_chain ./chain.pemSupplies the intermediate certificates that the server should send with the leaf. This is easy to miss when the leaf is not signed directly by the trusted root.
-tls1_2 / -tls1_3Forces exactly one TLS version. Without either flag, the server negotiates the highest version shared with the client. Use -min_protocol TLSv1.2 when the requirement is “TLS 1.2 or newer.”
-brief, -state, -msg, -tlsextdebugChooses how much connection detail to print: a short summary, state transitions, protocol messages, or received TLS extensions.
-naccept 1Exits after the specified number of connections. Useful for a one-request reproduction or a script.

The local installation describes its complete option set with:

openssl s_server -help

I checked these options with OpenSSL 3.6.3. OpenSSL builds can expose different switches, so check the local help before copying an option.

What it proves

If s_server starts, OpenSSL loaded the certificate and its matching private key. If a client receives the status page, that client reached the listener and completed the TLS handshake.

s_server is a debugging tool, not a production server.

OpenSSL documents the available s_server options.