Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Create a Self-Signed SSL Certificate for Nginx (with SANs and Secure Configuration)

A complete OpenSSL and Nginx walkthrough for creating a self-signed HTTPS certificate with Subject Alternative Names, secure key permissions, client trust, troubleshooting, renewal, and production alternatives.
Length13 min Posted Quest giverVGSources Team

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A self-signed certificate can encrypt HTTPS traffic to Nginx, but browsers and operating systems do not trust it automatically. The reliable process is to generate a certificate with every DNS name and IP address clients will use, protect the private key, configure an HTTPS listener, test the configuration, and explicitly install the certificate as trusted on controlled test clients.

This guide shows a complete OpenSSL and Nginx setup for an internal hostname such as example.test. It also explains the browser warning, name-mismatch errors, key-permission failures, certificate renewal, and when a self-signed certificate should be replaced with an internal or public certificate authority.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What a self-signed certificate does—and does not do

A self-signed certificate is a TLS certificate signed by its own private key rather than by a certificate authority (CA). When Nginx presents it, the connection is encrypted after the TLS handshake. Someone observing the network cannot read the HTTP contents in transit merely because the certificate is self-signed.

Encryption is only one part of HTTPS authentication. A client also checks whether the certificate chains to a trusted CA and whether the requested hostname appears in the certificate’s Subject Alternative Name (SAN). A self-signed certificate normally fails the trust-chain check, so an unconfigured browser displays a warning such as “unknown issuer,” “self-signed certificate,” or “connection is not private.” That warning is expected until the certificate, or the CA that issued it, is explicitly trusted on the client.

Self-signed certificates are appropriate for local development, a temporary test server, an isolated lab, or a private service whose clients are managed individually. They are not a practical trust model for a public website. Internet users cannot be expected to install your certificate, and a self-signed leaf certificate does not provide a central way to issue, rotate, or revoke certificates for many services.

Before you begin

  • Administrative access to the Linux host running Nginx.
  • OpenSSL installed on that host.
  • A DNS name, hosts-file name, or IP address that clients will actually use.
  • Permission to edit the active Nginx configuration and reload the service.
  • A plan for how test clients will trust the certificate.

Install OpenSSL with your operating system’s package manager if it is missing. For example, on a Debian- or Ubuntu-based system you would use the distribution package for OpenSSL; on an RPM-based system, install the corresponding OpenSSL package. Package names and commands vary by distribution, so use the package manager documented for your operating system.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Plan the names in the certificate

Modern hostname verification uses SAN entries. The certificate’s Common Name (CN) is not a substitute for SAN, even when the CN appears correct. Put every DNS name and IP address that a client may use in the SAN extension.

Examples of SAN entries

  • DNS:example.test for the primary hostname.
  • DNS:www.example.test if clients also request the www name.
  • IP:127.0.0.1 if a client connects by that loopback address.
  • IP:192.0.2.10 if clients connect directly to that address.

An IP address must be written as an IP: SAN, not as a DNS: entry. Do not add a public hostname merely to make a warning disappear; include a name only when the certificate is intended for that service and you control the use of that name. If the server will later be reached through another alias, regenerate the certificate or issue a new one containing that alias.

Generate the key and one-year certificate

Create a directory that administrators can write to and that the Nginx master process can read. The following commands create a 2048-bit RSA private key and a self-signed certificate valid for 365 days:

sudo install -d -m 700 /etc/nginx/ssl
sudo openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes 
  -keyout /etc/nginx/ssl/example.key 
  -out /etc/nginx/ssl/example.crt 
  -subj "/CN=example.test" 
  -addext "subjectAltName=DNS:example.test,DNS:www.example.test,IP:127.0.0.1"
sudo chmod 600 /etc/nginx/ssl/example.key
sudo chmod 644 /etc/nginx/ssl/example.crt

Replace the names and addresses with those used in your environment. The -x509 option produces a certificate directly instead of a certificate-signing request. -newkey rsa:2048 creates a new 2048-bit RSA key, -sha256 selects the SHA-256 signature digest, and -days 365 makes the certificate valid for one year from creation. The -nodes option leaves the private key unencrypted on disk so Nginx can start without an interactive passphrase prompt; strict file permissions are therefore essential.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The command writes PEM-formatted files. The certificate is public material and may be read by Nginx workers or a diagnostic tool. The key is secret material. Mode 600 allows only the file owner to read and write it, while directory mode 700 prevents other users from listing or entering the directory. The Nginx master process must still be able to read the key. If your distribution starts Nginx under a different administrative account or applies additional filesystem controls, verify access without making the key world-readable.

Use a configuration file when SANs are complex

The -addext option is convenient for a short SAN list. For many names, create an OpenSSL configuration file so the extension is easy to review and reproduce:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = example.test

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.test
DNS.2 = www.example.test
IP.1 = 127.0.0.1

Save the file outside the web root, then generate the certificate with the configuration:

sudo openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes 
  -keyout /etc/nginx/ssl/example.key 
  -out /etc/nginx/ssl/example.crt 
  -config /etc/nginx/ssl/openssl-san.cnf

Keep the resulting key protected just as you would with the one-line command. The configuration file is not secret, but it can reveal internal hostnames, so store it with the same administrative discipline as other server configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verify the certificate before configuring Nginx

Inspect the subject, issuer, validity dates, and SAN extension:

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

For a self-signed certificate, the subject and issuer normally identify the same certificate identity. Confirm that the “Not Before” and “Not After” dates cover the current time and that every required DNS name and IP address appears under Subject Alternative Name. An omitted SAN is a common cause of a name-mismatch error even when the CN looks right.

Check that the certificate and private key belong together. One simple method is to compare their public-key fingerprints:

openssl x509 -in /etc/nginx/ssl/example.crt -pubkey -noout | 
  openssl pkey -pubin -outform der | sha256sum
openssl pkey -in /etc/nginx/ssl/example.key -pubout | 
  openssl pkey -pubin -outform der | sha256sum

The two hashes must match. If they do not, point Nginx at the matching key and certificate pair or generate a new pair. Do not try to repair a mismatch by changing file names.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configure an HTTPS server block in Nginx

Add an HTTPS server block to the site configuration loaded by Nginx. The essential directives are an HTTPS listener, the certificate path, and the private-key path:

server {
    listen 443 ssl;
    server_name example.test www.example.test;

    ssl_certificate     /etc/nginx/ssl/example.crt;
    ssl_certificate_key /etc/nginx/ssl/example.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/example;
    index index.html;
}

listen 443 ssl; makes this server block accept TLS on the standard HTTPS port. server_name determines which virtual host Nginx selects from the request’s Host header and TLS SNI name. The two ssl_ directives must point to the exact PEM files you generated. The protocol setting enables TLS 1.2 and TLS 1.3, the versions shown in current Nginx guidance; avoid enabling obsolete protocols for a new deployment.

If your distribution separates site definitions from the main configuration, place the block in the appropriate sites-enabled or conf.d location and ensure it is included by the main Nginx configuration. A request to an IP address may select a different default server than a request to example.test; make the server names and the client’s URL agree.

Certificate chains and the file order

A single self-signed certificate has no intermediate chain. If you later use a certificate issued by a CA, ssl_certificate should contain the server certificate first, followed by any intermediate certificates in the order required by the issuer. Do not put the private key in that file. Keep ssl_certificate_key pointed only at the corresponding private key.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test and reload Nginx safely

  1. Run the configuration test:
    sudo nginx -t

    A successful result reports that the syntax is okay and the test is successful.

  2. If the test reports a missing file, verify the path, spelling, and directory permissions. If it reports a PEM error, inspect the file for accidental truncation or extra text and confirm that it contains the expected PEM headers.
  3. Reload rather than stopping the service:
    sudo systemctl reload nginx

    A reload applies the new configuration while existing connections are allowed to finish. If your system does not use systemd, use its service manager’s documented reload operation.

  4. Check the service status and logs if the reload fails. A failed reload leaves the previous working configuration in place on many systems, but do not assume that behavior without checking the service status.

Test from a client that does not yet trust the certificate

First test the TLS endpoint while explicitly supplying the certificate as a trust anchor:

curl --cacert /etc/nginx/ssl/example.crt https://example.test/

This command asks curl to trust the self-signed certificate for this request only. It should return the page from /var/www/example if DNS or the hosts file resolves example.test to the Nginx server and the server block is selected correctly. It does not install the certificate into the operating system’s global trust store.

Inspect the certificate presented by the endpoint:

openssl s_client -connect example.test:443 -servername example.test 
  -showcerts </dev/null

The -servername option sends the SNI name, which matters when several HTTPS virtual hosts share an address. Compare the certificate shown by the live endpoint with the file on disk. If the endpoint presents another certificate, a different server block, another Nginx instance, or a proxy in front of Nginx is handling the connection.

Make a controlled client trust the certificate

Without an explicit trust change, a browser or command-line client should report an unknown or self-signed issuer. That is a trust decision, not evidence that encryption failed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a temporary command-line test, use the certificate with curl’s --cacert option as shown above. For a development browser, import the certificate into that browser’s managed authority store or the operating system trust store according to the platform’s documented procedure. On a managed internal fleet, distribute a CA root through the organization’s device-management policy instead of asking each user to bypass warnings.

Trusting a self-signed leaf certificate on one machine does not make it trusted elsewhere. Every client that needs a clean verification result must receive the certificate or the CA that issued the service certificate. Remove the trust entry when the test environment is retired.

Why browsers show warnings

Unknown or self-signed issuer

The client cannot build a chain from the certificate to a trusted root. Install the certificate as a deliberate trust anchor on the test client, or replace it with a certificate issued by a CA already trusted by that client.

Hostname mismatch

The requested hostname or IP address is absent from SAN. Regenerate the certificate with the exact value the client uses, then reload Nginx. Also confirm that DNS, the hosts file, the URL, and the Nginx server_name all use the same spelling. A certificate for example.test does not automatically cover www.example.test, an IP address, or a different subdomain.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Expired or not-yet-valid certificate

Check the dates with the openssl x509 command. Verify the server and client clocks as well. A certificate can appear expired because a system clock is wrong, but extending the validity period does not fix a clock problem.

Wrong certificate from a shared address

When multiple sites share an address, the client’s SNI name selects a server block. Use the same hostname in the URL, server_name, and SAN. Test with openssl s_client -servername to confirm which certificate is returned.

Fix Nginx startup and reload failures

Permission denied reading the key

The key should be restricted, but the Nginx master process must be able to read it. Check ownership, directory traversal permissions, and any mandatory-access-control policy applied by the operating system. Do not solve the error with mode 644 or by placing the key in a publicly served directory.

Certificate or key file not found

Use absolute paths, check capitalization, and confirm that the files exist on the same filesystem namespace as the running Nginx process. Containers and chroot-like layouts can make a host path unavailable inside the Nginx environment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Invalid PEM formatting

A certificate file normally contains a block beginning with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE-----. A private key contains a corresponding private-key header. Copying a file through a system that changes line endings or adding explanatory text can make OpenSSL reject it. Regenerate the file if its content is uncertain.

Certificate and key do not match

Compare the public-key hashes described earlier. Make sure a deployment script did not replace one file while leaving the other from an older certificate. Replace both files as a pair, then run nginx -t before reloading.

Requests still reach HTTP

Confirm that clients use an https:// URL and that port 443 is open in the host firewall and any network security group. An HTTP listener on port 80 does not automatically provide TLS. You may add a separate HTTP-to-HTTPS redirect later, but the HTTPS server block must work first.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Protect and operate the private key

NGINX describes the private key as a secure entity that should be stored in a file with restricted access. Keep the key out of web roots, source-control repositories, container logs, issue trackers, and backups readable by untrusted users. Treat a copied key as compromised even if the certificate itself is public.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Use a dedicated certificate directory such as /etc/nginx/ssl with restrictive directory permissions.
  • Keep the private key at mode 600 or an equivalent policy that permits only the required administrative and Nginx identities.
  • Do not print the key in deployment output or diagnostic logs.
  • Restrict access to backups and snapshots containing the key.
  • Document who may rotate the key and how the old key will be removed.

The certificate can be distributed to clients for trust testing; the private key cannot. If the key may have been exposed, generate a new key and certificate, install the new pair, and remove the old trust material from clients.

Renewal and rotation

The example certificate expires after 365 days. Self-signed certificates do not renew automatically. Before expiry, generate a new key and certificate with the current SAN list, verify the pair, update the Nginx paths if necessary, run sudo nginx -t, and reload Nginx. If clients trusted the old self-signed certificate directly, they must also trust the replacement certificate; this is one reason a directly trusted self-signed leaf becomes cumbersome as a service grows.

Choose a rotation schedule that leaves time for distribution and testing rather than waiting for the expiration date. Record the certificate’s “Not After” date and monitor it. Do not silently extend an expired certificate without checking whether names, keys, or trust policy should also change.

Self-signed certificate, internal CA, or public CA?

The right choice depends on who connects, how many services exist, and whether the service is public.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Approach Client trust distribution Hostname coverage Renewal and rotation Revocation handling Best fit
Self-signed leaf Install each certificate explicitly on every client, or accept a warning. Only the DNS names and IP addresses listed in that certificate’s SAN. Simple for one certificate, but every replacement requires new client trust distribution when clients trust the leaf directly. No scalable central revocation model. One-off tests, local development, and isolated systems.
Internal CA Distribute one managed root CA to approved clients, then issue service certificates beneath it. Each leaf certificate can list its service’s SANs while the same root covers many services. More setup initially; routine leaf rotation is easier once issuance is automated. Can support an organization’s chosen revocation and replacement procedures. Managed private fleets and multiple internal services.
Public CA Most browsers and operating systems already trust the public CA chain. Subject to the CA’s validation and issuance rules for the names you control. Requires planned renewal and full-chain installation. Uses the CA’s revocation and status mechanisms. Internet-facing production services.

An internal CA is usually a better long-term answer than distributing a different self-signed leaf certificate for every internal service. Nginx can use certificates issued by that CA in the same way: point ssl_certificate at the leaf plus required intermediates, and keep ssl_certificate_key private.

For a public site, obtain a certificate from a trusted CA, install its full chain with the primary certificate first and intermediates afterward, retain strict key permissions, and keep client verification enabled. Nginx identifies purchasing a trusted server certificate or creating an internal CA as the production alternatives to a self-signed leaf.

Do not disable verification globally

Flags that turn off certificate verification can make a test appear to work, but they remove the protection that detects an impersonated server. Do not disable verification globally in browsers, operating systems, application runtimes, or service-to-service clients. Use a narrowly scoped trust anchor such as curl’s --cacert for a controlled test, or install the appropriate internal CA on managed clients.

A repeatable deployment checklist

  • List every DNS name and IP address clients will use.
  • Generate the key and certificate with those values in SAN.
  • Store them outside the web root in a restricted directory.
  • Set private-key permissions so only the required identities can read the key.
  • Inspect subject, issuer, dates, and SAN with OpenSSL.
  • Verify that the certificate and key have the same public key.
  • Add listen 443 ssl, ssl_certificate, and ssl_certificate_key to the intended server block.
  • Run sudo nginx -t before every reload.
  • Reload Nginx and test with an explicit trust anchor.
  • Distribute trust only to the clients that should access the test or internal service.
  • Record the expiration date and rotate before expiry.
  • Replace the self-signed leaf with an internal or public CA when the number or type of clients makes individual trust distribution impractical.

The Bottom Line

Use a self-signed Nginx certificate for controlled testing, not as a public trust solution: include all client names and IPs in SAN, protect the key, configure and test the HTTPS listener, and establish explicit client trust.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.