Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

OpenSSL Command Cheat Sheet for DevOps

By Kokil Thapa | Last reviewed: September 2026

TLS breaks at 2 a.m. when a certificate expires, a chain is incomplete, or a private key does not match the cert on disk. An OpenSSL Command Cheat Sheet for DevOps saves you from guessing flags under pressure. OpenSSL ships on every Ubuntu server I maintain for Linux system administration, Laravel deployments, and Let's Encrypt renewals. This page collects the commands I reach for weekly: key generation, CSR creation, certificate inspection, live TLS checks, and format conversion before Nginx or Apache reloads.

What Should Your OpenSSL Command Cheat Sheet for DevOps Include?

A useful cheat sheet groups commands by task, not by subcommand alphabet. DevOps work falls into five buckets: generate secrets, request or create certificates, inspect what is already on disk, test what the server actually presents, and convert formats for load balancers or Windows clients. Keep paths consistent across your fleet. I use /etc/ssl/private/ for keys and /etc/ssl/certs/ for public material on Ubuntu 22/24 hosts.

OpenSSL 3.x is the default on current Ubuntu LTS releases. Syntax from OpenSSL 1.1.1 mostly still works, but legacy algorithms may require an explicit provider. Check your version first:

openssl version -a
openssl list -digest-algorithms
openssl list -cipher-algorithms

Store this output in your runbook. Algorithm support varies between OpenSSL 3.0 builds on shared hosting and self-managed EC2 instances. On sister sites I deploy with Deployer 7 and GitLab CI, the same OpenSSL build runs on staging and production. That consistency prevents "works on my laptop" TLS surprises.

OpenSSL DevOps WorkflowGenerate Keygenpkey / genrsaCreate CSRopenssl reqIssue CertCA or Let's EncryptDeployNginx / ApacheVerify Before Reloadx509 -noout | verify | s_client -connectCommon FailuresWrong key, expired cert, missing intermediate, weak cipher
OpenSSL command cheat sheet for DevOps: standard TLS lifecycle from key generation through verification

Minimum toolkit on every server

Install openssl, ca-certificates, and your web server package. On Ubuntu:

sudo apt update
sudo apt install openssl ca-certificates

For automated renewals, add Certbot. The Let's Encrypt documentation assumes you understand CSR and key basics. That is where this cheat sheet pays off during first-time setup and incident response.

How Do You Generate Private Keys and CSRs with OpenSSL?

Modern practice uses ECDSA P-256 or Ed25519 keys for public websites. RSA 2048 remains acceptable for legacy compatibility. RSA 4096 costs more CPU on high-traffic termination points. For a law-firm portal or booking site on modest EC2 hardware, P-256 is my default in 2026.

Generate an ECDSA private key

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
  -out /etc/ssl/private/example.com.key

chmod 600 /etc/ssl/private/example.com.key
chown root:root /etc/ssl/private/example.com.key

Generate an RSA private key

openssl genrsa -out /etc/ssl/private/legacy.example.com.key 2048
chmod 600 /etc/ssl/private/legacy.example.com.key

Create a Certificate Signing Request (CSR)

A CSR carries your public key and requested subject details. The private key never leaves the server. Use a config file for Subject Alternative Names (SAN). Single-host CSRs fail once you add www, api, or staging subdomains.

cat > /tmp/example.cnf <<'EOF'
[req]
default_bits       = 2048
prompt             = no
default_md         = sha256
distinguished_name = dn
req_extensions     = req_ext

[dn]
C  = NP
ST = Bagmati
L  = Kathmandu
O  = Example Org
CN = example.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
EOF

openssl req -new \
  -key /etc/ssl/private/example.com.key \
  -out /tmp/example.com.csr \
  -config /tmp/example.cnf

Inspect the CSR before submitting it to your CA:

openssl req -in /tmp/example.com.csr -noout -text

Confirm the SAN list and signature algorithm. A wrong CN with correct SAN still works in browsers, but messy CSRs confuse CAs and audit trails. For password-protected keys used in client auth, add -aes256 during key generation. Automation must supply the passphrase via a secrets manager, not a plain shell history entry. See the password generator tool for strong passphrases, then store them outside Git.

How Do You Inspect and Verify X.509 Certificates with OpenSSL?

Most production incidents are inspection problems. You deployed a cert, but it is the staging one. Or the intermediate bundle is missing. Or expiry is tomorrow. These read-only commands are safe on live systems.

Read certificate details

openssl x509 -in /etc/ssl/certs/example.com.crt -noout -text
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -dates -subject -issuer
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -ext subjectAltName

Check that a key matches a certificate

The modulus or public key fingerprint must match. Mismatch causes Nginx to fail at reload with a vague error.

openssl x509 -in /etc/ssl/certs/example.com.crt -noout -modulus | openssl md5
openssl rsa  -in /etc/ssl/private/example.com.key -noout -modulus | openssl md5

For EC keys, compare SPKI fingerprints instead:

openssl x509 -in /etc/ssl/certs/example.com.crt -noout -pubkey \
  | openssl pkey -pubin -outform der | openssl dgst -sha256
openssl pkey -in /etc/ssl/private/example.com.key -pubout -outform der \
  | openssl dgst -sha256

Verify a certificate chain

Build a chain file with leaf + intermediate certs. Root CA certs usually belong in the system trust store, not your vhost bundle.

cat /etc/ssl/certs/example.com.crt \
    /etc/ssl/certs/intermediate.crt > /etc/ssl/certs/example.com.chain.pem

openssl verify -CAfile /etc/ssl/certs/example.com.chain.pem \
  /etc/ssl/certs/example.com.crt

The official OpenSSL verification options document explains -untrusted, hostname checks, and policy flags. Read it once when debugging chain errors that look fine in the browser but fail in curl.

Certificate Chain VerificationLeaf Certificateexample.comIntermediate CAIssuing CA certRoot CASystem trust storeopenssl verify-CAfile chain.pemBrowser TrustRoot pre-installedMissing intermediate = mobile app and API client failures
Verify leaf, intermediate, and root relationships before deploying TLS certificates to production

How Do You Test Live TLS with openssl s_client?

File inspection is not enough. You need to see what the server presents on the wire. openssl s_client is the fastest pre-deploy and post-deploy check. I use it before every Certbot renewal on production hosts, including legal-tech portals like Notary Kathmandu where downtime blocks client document uploads.

openssl s_client -connect example.com:443 -servername example.com \
  -showcerts < /dev/null 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

Add -tls1_2 or -tls1_3 to force a protocol version when hunting compatibility bugs. Test STARTTLS on mail and legacy apps:

openssl s_client -connect mail.example.com:587 -starttls smtp \
  -servername mail.example.com < /dev/null

Dump negotiated cipher and protocol:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | grep -E 'Protocol|Cipher'

For deeper TLS debugging patterns, read the companion guide on debugging TLS issues with OpenSSL s_client. Pair it with TCP/IP fundamentals for DevOps when failures sit below the handshake layer.

Quick pre-deploy checklist

  1. Run s_client against the load balancer IP and the origin IP separately.
  2. Confirm SAN covers every hostname in Nginx server_name.
  3. Check expiry is at least 14 days out before a Friday deploy.
  4. Validate HTTP→HTTPS redirects after reload, not only the cert file.
  5. Test from an external network, not only SSH on the box.

How Do You Convert Certificate Formats with OpenSSL?

Linux web servers want PEM. Windows IIS and some load balancers want PKCS#12 (.pfx). Java truststores use JKS. OpenSSL handles most conversions without third-party tools.

FormatTypical UseOpenSSL CommandNotes
PEMNginx, Apache, HAProxyDefault OpenSSL outputBase64 text, multiple blocks in one file
DERJava, embedded firmwareopenssl x509 -outform derBinary, no headers
PKCS#12 (.pfx)IIS, Windows, some APIsopenssl pkcs12 -exportBundle key + cert + chain
PKCS#7 (.p7b)Legacy Windows CA importsopenssl pkcs12 / crl2pkcs7Often intermediates only

PEM to DER

openssl x509 -in /etc/ssl/certs/example.com.crt \
  -outform der -out /tmp/example.com.der

PEM cert + key to PKCS#12

openssl pkcs12 -export \
  -inkey /etc/ssl/private/example.com.key \
  -in /etc/ssl/certs/example.com.crt \
  -certfile /etc/ssl/certs/intermediate.crt \
  -out /tmp/example.com.pfx \
  -name "example.com"

Inspect PKCS#12 without importing to Windows

openssl pkcs12 -in /tmp/example.com.pfx -nokeys -info
openssl pkcs12 -in /tmp/example.com.pfx -nocerts -nodes -info

PEM files are Base64 under the hood. When debugging encoding issues, the Base64 encoder and decoder helps compare blocks stripped from cert files. Never paste private keys into online tools. Use local CLI only.

Certificate Format ConversionPEMNginx / ApacheDERBinary X.509PKCS#12Windows / IIS-outformpkcs12Round-trip convert and verify before production importNever commit .pfx or .key files to GitUse chmod 600 and secrets manager storage
OpenSSL pkcs12 and outform commands convert certificates between PEM, DER, and PKCS#12

How Do You Use This OpenSSL Command Cheat Sheet for DevOps in Production?

Cheat sheets fail when commands live only in chat logs. Promote recurring tasks into scripts, aliases, and CI checks. On servers I manage for domain registration and hosting, TLS expiry monitoring runs from cron and posts to Slack via a small Bash wrapper.

Expiry alert one-liner

openssl x509 -in /etc/ssl/certs/example.com.crt -noout -checkend 1209600 \
  || echo "Certificate expires within 14 days"

-checkend takes seconds until expiry. 1209600 seconds equals 14 days. Wire this into Nagios, Zabbix, or a GitLab scheduled pipeline. Certbot handles Let's Encrypt renewals, but commercial certs, origin certs, and client-auth certs still need manual tracking.

Self-signed cert for local Laravel or staging

openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -days 365 -nodes \
  -keyout /tmp/staging.key -out /tmp/staging.crt \
  -subj "/CN=staging.example.local" \
  -addext "subjectAltName=DNS:staging.example.local"

Trust the staging cert in your local browser or use mkcert for team-shared trust. Never reuse self-signed material in production. For Laravel apps behind Apache on Ubuntu, align vhost SSLCertificateFile paths with Deployer shared directories so renewals survive releases.

Hash and fingerprint commands

  • openssl x509 -noout -fingerprint -sha256 -in cert.crt — pin in mobile apps.
  • openssl dgst -sha256 file.pem — compare file integrity after SCP.
  • openssl rand -hex 32 — generate session secrets and API tokens.
  • openssl passwd -apr1 — htpasswd-compatible hashes for basic auth staging.

Automate random secret generation in CI instead of hand-typing. Pair with Bash scripting patterns for DevOps and Ubuntu command aliases to cut repetition during incident calls.

Production TLS MonitoringCron Jobcheckend dailyAlertSlack / emailRenewCertbot / CAReloadPHP-FPM / NginxPost-Renew Verificationopenssl s_client -connect host:443openssl verify chain.pemcurl -vI https://host
Automate certificate expiry checks and verify with OpenSSL after every renewal and web server reload

Security habits that matter more than flags

Permissions beat algorithms in incident postmortems. Private keys at mode 644 have caused real breaches on client projects. Rotate keys when staff leave, not only when certs expire. Disable TLS 1.0 and 1.1 at the web server layer. OpenSSL can still negotiate old protocols if the vhost allows them.

For managed hosting clients in Nepal, budget Rs 2,000–5,000/year (~USD 15–37) for commercial certs when Let's Encrypt is not an option. Internal mTLS and API gateways may need custom CA setup beyond this cheat sheet. Escalate to support and maintenance when HSM or cloud KMS integration enters scope.

Bookmark this page next to essential Ubuntu terminal commands and the DevOps roadmap for 2026. TLS touches DNS, HTTP, CI pipelines, and application config. Treat cert work as a cross-stack skill, not an openssl-only sidebar.

Key Takeaways

  • Generate keys with genpkey (EC P-256) or genrsa (RSA 2048), always chmod 600 private files.
  • Always include SAN entries in CSRs; CN alone is not enough for multi-host Laravel or API setups.
  • Verify key-cert match and chain completeness with openssl verify before reloading Nginx or Apache.
  • Use s_client -connect and -servername to test live TLS, not just on-disk PEM files.
  • Convert to PKCS#12 with openssl pkcs12 -export for Windows; never commit bundles to Git.
  • Automate expiry checks with x509 -checkend and alert at least 14 days before certificate expiration.

People Also Ask

What is the most common OpenSSL command for checking certificate expiry?

Run openssl x509 -in certificate.crt -noout -dates to print notBefore and notAfter timestamps. Add -checkend 86400 to exit non-zero when the cert expires within one day. This pattern fits cron and monitoring scripts on Ubuntu production servers.

How do I test if my SSL certificate and private key match?

Compare MD5 hashes of the RSA modulus from the cert and key with openssl x509 -noout -modulus piped to openssl md5, and the same for openssl rsa -noout -modulus. For EC keys, compare SHA-256 fingerprints of the public key material instead. Matching hashes confirm the pair belongs together.

What is the difference between PEM and PKCS#12 formats?

PEM is Base64-encoded ASCII, often one cert per block, used by Nginx and Apache. PKCS#12 is a binary container that bundles private key, leaf certificate, and intermediates into a single password-protected .pfx file for Windows IIS and some API gateways. OpenSSL converts between them with -outform der and pkcs12 -export.

Can OpenSSL replace Certbot for Let's Encrypt certificates?

OpenSSL can create CSRs and keys, but Let's Encrypt issuance needs ACME protocol handling, HTTP-01 or DNS-01 challenges, and automated renewal. Certbot wraps that workflow. Use OpenSSL for inspection, verification, and conversion; use Certbot or acme.sh for free public certificate lifecycle on production sites.

Build TLS Reliability Into Every Deploy

Keep this OpenSSL Command Cheat Sheet for DevOps in your team wiki, incident channel, and local notes. The commands are stable across years of OpenSSL releases, but your hostnames, SAN lists, and chain files change every project. Verify before reload, test after reload, and automate expiry alerts so TLS never surprises you on a Friday night. If you want help hardening TLS across Laravel apps, WordPress shops, or multi-site EC2 fleets, contact us or review how we ship secure portals on the Court Marriage in Nepal and Mijar Law Associates projects. For broader infrastructure work, see testing and optimization services and about Kokil Thapa.

Frequently Asked Questions

A useful cheat sheet groups commands by task, not alphabetically. DevOps TLS work falls into five buckets: generate secrets, request or create certificates, inspect what is on disk, test what the server presents live, and convert formats for load balancers or Windows clients. Minimum toolkit covers genpkey and genrsa for keys, req for CSRs, x509 for inspection, s_client for live checks, pkcs12 for bundles, and verify before every Nginx or Apache reload.

Run openssl x509 -in certificate.crt -noout -dates for notBefore and notAfter. Add -checkend 86400 to exit non-zero when expiry is within one day.

Modern practice uses openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 for ECDSA keys, or openssl genrsa with 2048 bits for legacy RSA compatibility. RSA 4096 costs more CPU on high-traffic termination points, so P-256 is my default on modest EC2 hardware in 2026. Write keys to /etc/ssl/private/, then chmod 600 and chown root:root. For client-auth keys, add -aes256 and store passphrases in a secrets manager, never shell history.

Single-host CSRs fail once you add www, api, or staging subdomains. Create a config file with req_extensions and subjectAltName listing every DNS entry, then run openssl req -new with -key and -config flags. Inspect before CA submission using openssl req -in your.csr -noout -text. Confirm the SAN list and signature algorithm. A wrong CN with correct SAN still works in browsers, but messy CSRs confuse CAs and audit trails on multi-host Laravel or API setups.

For RSA keys, compare MD5 hashes of the modulus from the certificate and private key using openssl x509 -noout -modulus and openssl rsa -noout -modulus, each piped through openssl md5. Matching output confirms the pair belongs together. For EC keys, compare SHA-256 fingerprints of the public key material using pkey -pubout and dgst -sha256 instead. Mismatch causes Nginx to fail at reload with a vague error even when the cert file on disk looks correct.

Build a chain file by concatenating the leaf certificate and intermediate certs into one PEM. Root CA certificates usually belong in the system trust store, not your vhost bundle. Run openssl verify -CAfile your.chain.pem against the leaf cert. Chain errors often look fine in a browser but fail in curl or application clients. I run this before every production deploy on Ubuntu hosts managed with Deployer 7 and GitLab CI, where staging and production must present identical chain material.

File inspection is not enough—you need what the server presents on the wire. Run openssl s_client -connect hostname:443 -servername hostname, optionally piping output through x509 -noout -dates. Add -tls1_2 or -tls1_3 to force protocol versions when hunting compatibility bugs. Test STARTTLS on mail with -starttls smtp on port 587. Run s_client against load balancer IP and origin IP separately, confirm SAN covers every Nginx server_name, and verify expiry is at least 14 days out before a Friday deploy.

PEM is Base64 ASCII used by Nginx and Apache. PKCS#12 is a binary .pfx container bundling key, leaf cert, and intermediates for Windows IIS.

Linux web servers want PEM by default. Convert to DER with openssl x509 -outform der. Export a PEM cert and key to PKCS#12 using openssl pkcs12 -export with -inkey, -in, and -certfile for intermediates. Inspect .pfx bundles locally using pkcs12 -nokeys -info without importing to Windows. PEM files are Base64 under the hood. Never paste private keys into online conversion tools—use local CLI only and never commit bundles to Git.

No. OpenSSL creates CSRs and keys, but Let's Encrypt issuance needs ACME protocol handling, HTTP-01 or DNS-01 challenges, and automated renewal. Certbot wraps that workflow on Ubuntu servers I maintain alongside ca-certificates. Use OpenSSL for inspection, verification, and format conversion. Use Certbot or acme.sh for free public certificate lifecycle on production sites. Understanding CSR and key basics from this cheat sheet pays off during first-time Certbot setup and incident response when renewals fail.

I use /etc/ssl/private/ for keys and /etc/ssl/certs/ for public material on Ubuntu 22 and 24 hosts. Private keys must be mode 600 owned by root:root—permissions beat algorithms in incident postmortems, and mode 644 has caused real breaches on client projects. For Laravel apps behind Apache deployed with Deployer 7, align vhost SSLCertificateFile paths with shared directories so Certbot renewals survive symlink release swaps without manual path edits after each deploy.

Wire openssl x509 -in cert.crt -noout -checkend 1209600 into cron or a GitLab scheduled pipeline—1209600 seconds equals 14 days. Non-zero exit means the cert expires soon; pipe that into Nagios, Zabbix, or a Bash wrapper posting to Slack. Certbot handles Let's Encrypt renewals, but commercial certs, origin certs, and client-auth certs still need manual tracking. I run expiry checks on legal-tech portals where expired TLS blocks client document uploads during renewal windows.

Run openssl version -a, then openssl list -digest-algorithms and openssl list -cipher-algorithms, and store the output in your runbook. OpenSSL 3.x is the default on current Ubuntu LTS releases. Syntax from OpenSSL 1.1.1 mostly still works, but legacy algorithms may require an explicit provider. Algorithm support varies between OpenSSL 3.0 builds on shared hosting and self-managed EC2 instances. Matching builds on staging and production prevents works-on-my-laptop TLS surprises during Deployer 7 releases.

For managed hosting clients in Nepal, budget Rs 2,000–5,000 per year, roughly USD 15–37, when Let's Encrypt cannot be used.

Rotate keys when staff leave, not only when certificates expire. Disable TLS 1.0 and 1.1 at the web server layer—OpenSSL can still negotiate old protocols if the vhost allows them. Always verify key-cert match and chain completeness with openssl verify before reload, then test with s_client after reload from an external network, not only over SSH. Automate expiry alerts at least 14 days ahead so TLS never surprises you on a Friday night deploy.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: