Use OpenSSL to create a PEM-encoded private key and certificate, add every DNS name and IP address that clients will use as Subject Alternative Names (SANs), then reference the two files from an Nginx HTTPS server block. The resulting connection is encrypted, but browsers and operating systems will not trust the certificate until you explicitly install it as a trust anchor.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
This guide covers certificate creation, Nginx configuration, permissions, validation, client trust, renewal, and the point at which a self-signed certificate should be replaced by an internal or public certificate authority.
As an Amazon Associate I earn from qualifying purchases.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsWhat a self-signed certificate does—and does not do
A self-signed certificate is signed by its own private key rather than by a certificate authority (CA). When Nginx presents it during a TLS handshake, the traffic is encrypted and the client can verify that the certificate has not been altered. However, the client has no independent reason to trust the issuer. A normal browser therefore displays an unknown-issuer or self-signed-certificate warning until the certificate is deliberately trusted.
That distinction matters when deciding where to use one:
#1 Best Overall
- Good fit: local development, a lab, a temporary test endpoint, or a private service whose clients you administer.
- Poor fit: an Internet-facing production site, a public API, or a service used by people and devices you cannot configure. Those clients expect a chain to a CA already in their trust stores.
Modern hostname verification uses the certificate’s SAN extension. The old Common Name (CN) field is not a substitute. If a client connects with example.test, that exact DNS name must appear as a SAN; if it connects to 127.0.0.1, that IP address must appear as an IP SAN. A certificate containing only a CN can still produce a name-mismatch error.
Plan the names, addresses, and file locations first
List every client endpoint
Write down the names clients actually use, not just the name you intend them to use later. Include each internal DNS alias, development hostname, and literal IP address that will be used in a URL. DNS SANs and IP SANs are different entries: use DNS:name.example for a hostname and IP:192.0.2.10 for an address.
Do not add a public hostname merely because it is convenient. Put a public name in SAN only when the certificate is intended for that name and you control the corresponding service. If the name set changes, issue a new certificate rather than relying on the CN.
Choose a protected directory
Keep the key outside the web root and outside application repositories. The example below uses /etc/nginx/ssl. The directory is restricted to administrators, while Nginx’s master process must still be able to read the key when it starts or reloads. Nginx documentation describes the certificate as public and the private key as a secure entity that requires restricted access.
Understand the two files
example.keyis the private key. Anyone who obtains it can impersonate the service for the lifetime of the certificate, so protect it as a secret.example.crtis the certificate. It contains the public key, identity information, validity dates, and SANs. It may be readable by Nginx and clients.
The OpenSSL command in this guide writes both files in PEM format, which Nginx accepts directly. The -nodes option leaves the private key unencrypted so Nginx can start unattended; compensate with strict file ownership and mode.
Prerequisites
- A Linux host with administrative access (for example, the ability to run commands with
sudo). - Nginx installed and running, with its configuration directory known.
- OpenSSL installed through your operating system’s package manager.
- At least one planned DNS name or IP address for the service.
Package names and installation commands vary by distribution. Install the distribution’s OpenSSL package before continuing, then confirm that the openssl command is available.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallRank #2
Step 1: Create the certificate directory
Create a directory that administrators can write to but ordinary users cannot:
sudo install -d -m 700 /etc/nginx/ssl
Mode 700 restricts directory access to its owner. On a typical system the owner is root. If your Nginx master process runs under a different account, ensure that account can traverse the directory and read the key without making the key broadly accessible. Do not solve a permission problem by making the private key world-readable.
Step 2: Generate a key and self-signed certificate with SANs
Replace the example names and address with the endpoints your clients use:
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
What each option controls
| Option | Purpose |
|---|---|
-x509 |
Outputs a self-signed certificate instead of a certificate-signing request. |
-newkey rsa:2048 |
Creates a new 2048-bit RSA private key. |
-sha256 |
Uses SHA-256 for the certificate signature. |
-days 365 |
Sets a one-year validity period from the time of issuance. |
-nodes |
Does not encrypt the private key with a passphrase, allowing unattended Nginx starts. |
-keyout and -out |
Choose the private-key and certificate paths. |
-subj |
Sets the subject; the CN is retained for identification but does not replace SANs. |
-addext subjectAltName |
Adds the DNS and IP identities used for hostname verification. |
The command creates a new key each time it runs. Re-running it replaces the named files, so make a backup only in a location protected like the original and coordinate the replacement with a reload. The one-year period is an example; choose a shorter or longer period according to your rotation policy and test environment.
Build the SAN list correctly
Separate SAN entries with commas and use the proper type prefix:
DNS:example.testfor a DNS name.DNS:www.example.testfor a second DNS alias.IP:127.0.0.1for a literal IPv4 address.
If clients use an IPv6 address, include it as an IP: entry as well. A wildcard DNS name, where appropriate for your private naming scheme, does not cover an IP address and does not automatically cover a different parent domain. Include the exact names that appear in requests.
Step 3: Configure Nginx to listen for HTTPS
Add an HTTPS server block to the appropriate Nginx configuration file:
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;
}
How the directives fit together
listen 443 ssl;opens the conventional HTTPS port and enables TLS for this listener.server_namedeclares the names this virtual server should answer. It also helps Nginx select the correct server block when SNI is supplied.ssl_certificatepoints to the public certificate file.ssl_certificate_keypoints to the matching private key.ssl_protocols TLSv1.2 TLSv1.3;limits negotiation to the protocol versions shown in current Nginx guidance.rootandindexare ordinary content settings; change them to match your application.
If you have several HTTPS virtual servers, each block needs an appropriate certificate and key. Ensure the requested hostname appears in the SANs of the certificate selected for that block. A correct certificate in the wrong block still produces a name mismatch.
Step 4: Check the configuration and reload safely
- Run Nginx’s configuration test:
sudo nginx -tContinue only when it reports that the syntax test is successful and the configuration test is successful.
- Reload without stopping existing connections:
sudo systemctl reload nginx - If the reload fails, keep the old configuration in place while you correct the reported file path, syntax, ownership, or certificate problem. Do not delete the working certificate until the replacement has passed validation.
Nginx’s master process reads the key during startup or reload. A key with mode 600 is appropriate when it is owned by the account that starts Nginx (normally root); verify your service’s ownership model rather than loosening permissions pre-emptively.
Step 5: Verify the certificate and the live endpoint
Inspect the certificate itself
openssl x509 -in /etc/nginx/ssl/example.crt -noout
-subject -issuer -dates -ext subjectAltName
Check that the subject is the certificate you intended, the issuer is the same certificate for a self-signed leaf, the validity dates include the current time, and every required SAN is present. If a name or address is missing, issue a new certificate with a corrected -addext value.
Test with an explicit trust anchor
curl --cacert /etc/nginx/ssl/example.crt https://example.test/
The --cacert option tells this curl invocation to trust the certificate explicitly. It does not change the operating system’s trust store and does not make unrelated browsers trust it. Use a URL whose hostname appears in SAN; otherwise curl should correctly reject the connection for a name mismatch.
Interpret an ordinary browser warning
A browser that has not been configured to trust the certificate should report an unknown or self-signed issuer. That warning is expected for this design. It is different from a SAN mismatch, an expired certificate, or a failed TLS handshake. Record the exact error before changing files so you address the right problem.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Rank #4
Make test and internal clients trust the certificate
Encryption and trust are separate controls. To remove the issuer warning, import the certificate into the trust store used by the particular client, browser, operating system, container, or language runtime. The certificate must be distributed through a controlled channel, and clients must be able to distinguish this test certificate from an untrusted certificate downloaded by an attacker.
Trusting a leaf certificate directly is manageable for a single test service. Every replacement certificate must then be distributed again. For a private fleet with several services, use an internal CA instead: install the CA root once on managed clients and issue separate leaf certificates for each service. Keep the CA private key offline or otherwise more strongly protected than a web-server key.
Do not disable TLS verification globally to hide the warning. Nginx guidance cautions that disabling verification reduces security and is not suitable for production. If a test tool needs an exception, scope it to that command or isolated environment and document the exception.
Troubleshoot the failures that occur most often
“Certificate is not trusted” or “self-signed issuer”
The client does not have the certificate (or its issuing CA) in a trust store. For a one-off test, use an explicit trust option such as curl’s --cacert. For managed users, deploy the certificate or, preferably, an internal CA root through the organization’s normal device-management process. Do not replace the trust check with a global verification bypass.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
“Hostname does not match”
Compare the exact hostname or IP in the URL with the SAN output from the inspection command. Add every missing DNS or IP entry and regenerate the certificate. Also confirm that the request’s Host header and TLS SNI value select the intended Nginx server block; a different block may be presenting a valid certificate for another service.
Nginx reports that it cannot read the certificate or key
Check the paths in ssl_certificate and ssl_certificate_key, then check that the files are present, PEM formatted, and readable by the Nginx master process. Keep the directory restricted and the key at mode 600; correct ownership or the service’s access path instead of granting broad read permission.
Best Value
The certificate and key do not work as a pair
Nginx requires the private key to correspond to the public key in the certificate. This error commonly appears after copying a key from one issuance and a certificate from another. Restore the matching pair generated together, or issue a new pair and update both directives atomically.
The certificate is expired or not yet valid
Use the -dates output to check the notBefore and notAfter values and verify the host clock. Reissue before expiry, install the replacement alongside the old files, run nginx -t, and reload. Clients that pin the old self-signed leaf will need the new certificate distributed to them.
Free tools Windows power users keep installed
One-click scans. No signup required.
A chain is configured in the wrong order
When you use a certificate chain, place the primary server certificate first and intermediate certificates after it in the configured certificate file. A self-signed leaf normally has no intermediate chain. Incorrect ordering can cause clients to reject an otherwise valid chain.
Nginx will not reload after a change
Run sudo nginx -t and read the first reported error. Typical causes are a typo in a path, an unmatched brace, a certificate in the wrong format, or permissions that prevent the master process from opening the key. Fix the named problem, test again, and only then reload.
Self-signed certificate, internal CA, or public CA?
| Choice | Client trust distribution | Hostname coverage and operations | Best use |
|---|---|---|---|
| Self-signed leaf | Every client must trust that individual certificate explicitly. | Simple SAN list for one service; replacement requires redistributing the new leaf. Revocation is mainly handled by removing it from trust stores. | One-off tests, local development, and tightly controlled single-service environments. |
| Internal CA | Install one CA root on managed clients, then trust issued leaf certificates. | Scales across multiple internal names and services; requires CA key protection, issuance, renewal, and a plan for revocation and root rotation. | Private fleets, corporate networks, and environments with centralized device management. |
| Public CA certificate | Major operating systems and browsers already trust the public CA chain. | Suitable for public DNS names; renewals and full-chain installation still require automation and strict key handling. | Internet-facing production websites and APIs. |
Nginx documents both purchasing a server certificate from a trusted CA and creating an internal CA with OpenSSL. The practical decision is driven by who your clients are: if you cannot reliably install trust material on them, a self-signed certificate is the wrong production model.
Renewal, rotation, and safe handling
Track the one-year expiration
The example certificate is valid for 365 days. Record its expiration date and schedule replacement before that date, allowing time to distribute trust changes and reload every Nginx instance. A self-signed certificate that is trusted directly by clients creates a coordination problem: issuing a replacement changes the trust anchor those clients recognize.
Recommended Free Tools
Protect backups and automation
- Keep private keys out of web roots, source-control repositories, container logs, and backups readable by untrusted users.
- Restrict backup access at least as tightly as the live key and destroy obsolete copies according to your security policy.
- When automating rotation, write the new files with restrictive modes, validate them with
nginx -t, and reload only after validation succeeds. - Never print the key or embed it in diagnostic output. The certificate itself is public; the key is not.
Plan for compromise
If a private key may have been exposed, treat the certificate as compromised even if its expiration date is far away. Remove trust in the affected certificate, issue a new key and certificate, update Nginx, and distribute the replacement through a controlled channel. An internal CA gives you a cleaner way to replace one service certificate without changing the root trusted by every client.
Production alternative for public services
For a public website or API, obtain a certificate from a trusted CA for the exact public names, install the complete chain with the server certificate first and intermediates afterward, and retain strict private-key permissions. Keep certificate verification enabled for clients. A public CA certificate avoids asking every visitor to import a private trust anchor, which is why it is the practical choice for Internet-facing production.
Quick Recap
Deployment checklist
- OpenSSL is installed and the planned DNS names and IP addresses are known.
- The certificate directory is restricted, and the Nginx master process can read the key.
- The certificate was generated with SAN entries for every endpoint clients actually use.
- The key is mode
600; the certificate is mode644only where that access is appropriate. - The HTTPS server block includes
listen 443 ssl, the correctserver_name, and matching certificate/key paths. sudo nginx -tsucceeds before every reload.- The certificate inspection command shows the expected subject, dates, issuer, and SANs.
- A curl test succeeds when the certificate is supplied explicitly with
--cacert. - Required test or internal clients have a documented trust installation method.
- A renewal date, key-protection plan, and compromise-recovery procedure are recorded.
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.




