How to Create a Self-Signed SSL Certificate in Linux Using OpenSSL

While public production websites mandate SSL/TLS certificates issued by trusted Certificate Authorities (CAs) like Let’s Encrypt or DigiCert, local development staging servers, testing environments, intra-office intranet dashboards, and testing sandboxes do not always require commercial validation. When you need to test HTTPS communication, encrypt internal microservices, or configure local reverse proxies on Nginx or Apache, generating a self-signed SSL certificate directly in Linux using OpenSSL is the fastest and most secure method.

What is a Self-Signed Certificate?

A self-signed SSL/TLS certificate is an X.509 digital security certificate signed with its own private key rather than through a chain of trust back to a recognised root authority. While web browsers will present an initial security warning indicating that the certificate is untrusted, the underlying cryptographic transport layer remains identical to commercial certificates: all data transmitted between client and server is fully encrypted using robust AES-GCM or ChaCha20 cipher suites.

Prerequisites and Verifying OpenSSL Installation

OpenSSL is pre-installed across virtually every Linux distribution. To verify that OpenSSL is present on your system, run:

openssl version

If for any reason OpenSSL is missing from a minimal container or server installation, install it via your package manager:

Ubuntu, Debian, and Linux Mint:

sudo apt update && sudo apt install openssl

Fedora and RHEL:

sudo dnf install openssl

Arch Linux:

sudo pacman -S openssl

How to Generate a Self-Signed Certificate in a Single Command

You can create both a 2048-bit or 4096-bit RSA private key and a matching self-signed certificate in one streamlined OpenSSL execution:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/nginx-selfsigned.key \
  -out /etc/ssl/certs/nginx-selfsigned.crt

Understanding the Command Breakdown

Each parameter in the command serves a critical cryptographic purpose:

  • req : Invokes OpenSSL’s certificate signing request (CSR) and certificate generation utility.
  • -x509 : Instructs OpenSSL to generate a self-signed X.509 certificate rather than outputting a certificate signing request.
  • -nodes : Short for “No DES”. This ensures the private key is not encrypted with a passphrase. Omitting a passphrase is essential for automated web servers (like Nginx or Apache) so they can start automatically on system reboot without waiting for manual human password entry.
  • -days 365 : Specifies the certificate validity lifespan (in days).
  • -newkey rsa:2048 : Simultaneously creates a new 2048-bit RSA private key. (You can substitute rsa:4096 if your security policy requires 4096-bit keys).
  • -keyout : Defines the destination file path for the generated private key.
  • -out : Defines the destination file path for the generated public certificate.

Automating Certificate Prompts Non-Interactively

By default, OpenSSL prompts you interactively for country, state, organisation, and Common Name (domain name). To generate the certificate non-interactively in CI/CD build scripts or automated Docker builds, supply the subject metadata using the -subj flag:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/myserver.key \
  -out /etc/ssl/certs/myserver.crt \
  -subj "/C=GB/ST=London/L=London/O=DevLab/OU=IT/CN=localhost"

Securing Your Private Key Permissions

Private keys must be protected against unauthorised access from unprivileged local system users. Always adjust ownership and permissions immediately following creation:

sudo chmod 600 /etc/ssl/private/nginx-selfsigned.key
sudo chmod 644 /etc/ssl/certs/nginx-selfsigned.crt

Inspecting Your Generated Certificate

To inspect your certificate’s expiration date, issuer details, subject name, and cryptographic fingerprint, run:

openssl x509 -in /etc/ssl/certs/nginx-selfsigned.crt -text -noout

Troubleshooting Common Self-Signed Certificate Warnings

  • Browser Displays “NET::ERR_CERT_AUTHORITY_INVALID”: Because the certificate is self-generated, browsers like Chrome and Edge flag it as untrusted. For local development on Google Chrome, type thisisunsafe directly on the warning screen or click Advanced > Proceed to localhost (unsafe).
  • Subject Alternative Name (SAN) Warnings in Modern Browsers: Modern versions of Chrome and Firefox deprecate relying on the Common Name (CN) alone and mandate Subject Alternative Names. For extensive testing, supply an OpenSSL configuration file that includes a [san] section defining subjectAltName=DNS:localhost,IP:127.0.0.1.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.