← Back to list

TLS Mastery — Part 4: Hands-On OpenSSL — Self-Signed Cert + nginx | Shantayya Swami

Parts 1–3 covered theory. Now we get our hands dirty with OpenSSL.

Shantayya Swami · 2026-06-10 00:00 · 0 claps · 2.9 min read
#openssl #nginx #self-signed-certificate #tls
Open on Medium ↗

TLS Mastery — Part 4: Hands-On OpenSSL — Self-Signed Cert + nginx | Shantayya Swami

Parts 1–3 covered theory. Now we get our hands dirty with OpenSSL.

In this part:

  • Certificate types (single-domain, wildcard)
  • What a CSR is, and the standard workflow
  • Create a self-signed certificate with OpenSSL
  • Enable TLS on nginx and inspect the result

Certificate types

Single-domain — issued for exactly one domain, e.g. www.google.com. All URL paths under it (/gmail, /youtube) are covered automatically; paths don't need separate certificates.

Wildcard — covers a domain and all its subdomains via an asterisk: *.google.com.

Note: a wildcard covers one level of subdomain. `.google.commatchesmail.google.combut **not**a.b.google.com`. There are also multi-domain (SAN) certificates that list several specific names - more on SAN in Part 5.*

What is a CSR?

To get a certificate from a CA, you don’t hand over a bare public key — you send a Certificate Signing Request (CSR). A CSR bundles your public key with identity info:

  • Common Name (the domain, e.g. mynginx.com)
  • Organisation, Organisational Unit
  • Country, State, Locality
  • Email
  • (and the public key)

The CA reads the CSR, verifies you own the domain, checks the details, and only then issues a signed certificate.

Never send your private key. The CA only needs your public key (inside the CSR). Lose the private key and the certificate is useless.

How a CA verifies you

  • WHOIS lookups for domain ownership (try who.is — registrar, dates, country, org; emails are usually hidden).
  • Emailing the address in the CSR.
  • Checking government/business registries; sometimes requesting documents.

The standard workflow

There’s no separate “public key” step — the public key lives inside the CSR.

Hands-on: nginx over plain HTTP first

nginx serves from /usr/share/nginx/html and configures from /etc/nginx/nginx.conf. Open port 80, browse to the server, and you'll see the default page marked "Not secure" - no certificate yet.

Create a self-signed certificate

We’re not sending anything to a CA, so we don’t need a separate CSR file — OpenSSL can create the private key and self-signed certificate in one command:

Flag by flag:

  • req - work with a certificate request.
  • -x509 - output a self-signed certificate (not just a CSR).
  • -nodes - "no DES": don't lock the key with a passphrase.
  • -days 365 - valid one year.
  • -newkey rsa:2048 - new 2048-bit RSA key.
  • -keyout / -out - where to write the key and certificate.

OpenSSL prompts for details; the Common Name is the domain, e.g. mynginx.com. Internally it creates a temporary CSR, signs it with your key, and discards it - so no .csr file appears.

The long way (to see the moving parts)

Use `domain./server.names for **server** certificates - notuser.` (those are client certificates, covered in Part 8).*

Enable TLS in nginx

Open /etc/nginx/nginx.conf. The default server block listens on port 80; near the bottom is a commented-out "Settings for TLS" block listening on 443 ssl. The pattern:

  1. Comment out the plain HTTP server { listen 80; ... } block.
  2. Uncomment the TLS server block.
  3. Point it at your certificate and key:

Move your files into the expected paths (renaming to server.crt / server.key):

Open port 443, then browse to https://your-server. You'll see:

“Your connection is not private — NET::ERR_CERT_AUTHORITY_INVALID”

That’s expected. The traffic is encrypted (note https://), but you signed the certificate, not a trusted CA - so the browser can't verify identity. Click Advanced → Proceed.

Decode the certificate to see the problem

(-noout hides the raw public-key blob.) Look at two fields:

For a self-signed certificate, Subject and Issuer are identical — you issued your own certificate. That’s exactly why the browser won’t trust it, and why the certificate hierarchy shows no CA above it.

Coming up

You can now create a self-signed certificate and serve HTTPS from nginx — encrypted, but untrusted.

In Part 5 we’ll fix the trust problem the right way: build our own Certificate Authority, generate a proper CSR, handle Subject Alternative Names (SAN) (and the classic OpenSSL gotcha), and get the green padlock by trusting our CA in the browser.

Previous: Part 3 — The TLS Handshake, Classic & Modern “ · Next: Part 5 — Build Your Own CA “

Originally published at https://www.shantayyaswami.com on June 10, 2026.


메타데이터
post_id
d45cebacc06d
slug
tls-mastery-part-4-hands-on-openssl-self-signed-cert-nginx-shantayya-swami-d45cebacc06d
url
https://medium.com/@shantayyaswami/tls-mastery-part-4-hands-on-openssl-self-signed-cert-nginx-shantayya-swami-d45cebacc06d
canonical_url
https://medium.com/@shantayyaswami/tls-mastery-part-4-hands-on-openssl-self-signed-cert-nginx-shantayya-swami-d45cebacc06d
author_url
https://medium.com/@shantayyaswami
status
ok
fetched_at
2026-06-13 16:23:23