Security

Install a GoGetSSL certificate on NGINX

You validated your domain, paid for a GoGetSSL certificate, and now the files sit in your inbox. The remaining step is making NGINX actually use them. This guide walks through the exact process on an Ubuntu 24.04 VPS: generating a CSR, installing the GoGetSSL certificate files, configuring the server block, and verifying the chain is served correctly. The same steps apply to Debian 12 or AlmaLinux 9 if you adjust the package manager.

安装 GoGetSSL 证书只需修改 NGINX 配置文件中的两个路径。

Installing a GoGetSSL certificate is only a matter of pointing two paths in the NGINX configuration.

Prerequisites

  • An Ubuntu 24.04 VPS with NGINX installed and running (sudo apt install nginx).
  • A domain name pointed at your server's IP. The IPv4 must resolve before certificate validation.
  • Root access or a user with sudo privileges.
  • Your GoGetSSL certificate files already issued: the certificate bundle, the private key you generated during the CSR step, and the CA bundle if they sent one separately.
  • Port 443 open in your firewall if you run one.

Why GoGetSSL instead of Let's Encrypt

Let's Encrypt is free and automates renewal, and I use it on personal projects. But a paid GoGetSSL DV certificate starts around $10 per year, and you get a longer validity period, which means fewer renewal cycles on servers you want to touch rarely. Wildcard certificates from GoGetSSL cover all subdomains, which a single Let's Encrypt cert does not. If you run production APIs or client-facing services, paying a small fee to avoid unexpected renewal failures is a defensible trade-off.

GoGetSSL also supports email validation in addition to DNS and HTTP validation, which helps when you cannot edit DNS quickly. The certificate files arrive as a ZIP containing your certificate and a CA bundle. What GoGetSSL calls the CA bundle is the intermediate certificate, and NGINX needs both files to serve a complete chain.

Step 1 - Generate a CSR on the VPS

The CSR is generated on the server that will host the certificate, not on your laptop. This keeps the private key on the machine from the start. If you ordered the certificate with a CSR from somewhere else, skip this step and place that key file at /etc/nginx/ssl/.

sudo mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl
sudo openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

The -nodes flag keeps the key unencrypted so NGINX can read it without a passphrase at startup. If you encrypt the key, every reload of NGINX prompts for the passphrase, which breaks automated restarts. For a single domain, RSA 2048 is standard and compatible with every client. ECDSA keys are faster but require the certificate to match the key type, so unless you ordered an ECDSA certificate, stick with RSA.

When prompted, enter the common name as your full domain name, for example www.yourdomain.com. Leave the challenge password empty. The output is two files: yourdomain.key, which stays on the server, and yourdomain.csr, which you paste into the GoGetSSL order form if you have not already provided it.

Verify the CSR was created correctly:

openssl req -in yourdomain.csr -noout -subject

The output shows the subject line with CN=yourdomain.com. If the common name is wrong, delete both files and start over before submitting the CSR to anyone.

Step 2 - Upload the certificate files

Once GoGetSSL issues the certificate, download the ZIP and extract it. The contents vary by product, but a DV certificate typically includes yourdomain_com.crt and a CA bundle file. Upload both to the server with SCP from your local machine:

scp yourdomain_com.crt yourdomain_com.ca-bundle user@your-server-ip:/tmp/

Then move them into the SSL directory and set permissions:

sudo mv /tmp/yourdomain_com.crt /etc/nginx/ssl/yourdomain.crt
sudo mv /tmp/yourdomain_com.ca-bundle /etc/nginx/ssl/yourdomain.ca-bundle
sudo chown root:root /etc/nginx/ssl/yourdomain.key /etc/nginx/ssl/yourdomain.crt /etc/nginx/ssl/yourdomain.ca-bundle
sudo chmod 600 /etc/nginx/ssl/yourdomain.key
sudo chmod 644 /etc/nginx/ssl/yourdomain.crt /etc/nginx/ssl/yourdomain.ca-bundle

The private key gets 600 so only root can read it. The certificate and CA bundle are public data, so 644 is fine. If NGINX runs as a different user, it still needs read access to the key, which is why the key stays owned by root with 600 permissions.

Verify the certificate matches the key before touching the configuration:

sudo openssl x509 -noout -modulus -in /etc/nginx/ssl/yourdomain.crt | openssl md5
sudo openssl rsa -noout -modulus -in /etc/nginx/ssl/yourdomain.key | openssl md5

Both commands print the same MD5 hash. If they differ, the certificate does not belong to that key, and NGINX will refuse to start with a mismatch error.

Step 3 - Configure the NGINX server block

NGINX reads the certificate from the ssl_certificate and ssl_certificate_key directives. The order matters: the certificate file must contain the full chain, with your leaf certificate first and the intermediate after it. Some GoGetSSL bundles already concatenate this; if yours is a single file, use it directly. If you have separate files, combine them:

sudo cat yourdomain.crt yourdomain.ca-bundle > yourdomain.fullchain.crt

Now edit the server block for your domain. On Ubuntu, the default site is /etc/nginx/sites-available/default, but I recommend a separate file per site:

sudo nano /etc/nginx/sites-available/yourdomain

Add a server block on port 443 with the certificate paths:

server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/nginx/ssl/yourdomain.fullchain.crt;
    ssl_certificate_key /etc/nginx/ssl/yourdomain.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    root /var/www/yourdomain;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

Disable TLS 1.0 and 1.1. They are obsolete and every modern client supports TLS 1.2 at minimum. The cipher list above restricts to AES-GCM, which is fast on modern CPUs with AES-NI instructions.

If you want HTTP to redirect to HTTPS, add a second server block on port 80:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

Enable the site and test the configuration:

sudo ln -s /etc/nginx/sites-available/yourdomain /etc/nginx/sites-enabled/
sudo nginx -t

Look for the line syntax is ok and test is successful. If NGINX reports cannot load certificate, the file permissions are wrong or the path is typoed. If it reports a key mismatch, go back to Step 2 and check the hashes again.

Step 4 - Enable the firewall and reload

Before reloading NGINX, make sure port 443 is reachable. On Ubuntu with ufw:

sudo ufw allow 443/tcp
sudo ufw status

The status output should show 443/tcp ALLOW. If you use firewalld on AlmaLinux or Rocky Linux:

sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Now reload NGINX to apply the certificate:

sudo systemctl reload nginx

Unlike restart, reload does not drop active connections. It gracefully finishes existing requests and applies the new configuration. Verify the service is still healthy:

systemctl status nginx

You should see active (running) with no errors in the log. Check the error log explicitly if anything looks off:

sudo tail -f /var/log/nginx/error.log

Step 5 - Verify the certificate is served correctly

A browser showing a padlock is the first signal, but it is not enough. Confirm the full chain, the domain match, and the expiry date from the command line:

curl -vI https://yourdomain.com 2>&1 | grep -E "SSL connection|subject:|issuer:|expire date"

You want the subject to match your domain and the issuer to be the GoGetSSL intermediate or CA, not a self-signed name. If you see self-signed in the issuer line, NGINX is serving the wrong file.

For a deeper check, verify the chain order. A common mistake is listing the leaf certificate as the CA bundle, which breaks the chain for some clients:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | grep -E "subject=|issuer="

The output shows multiple subject and issuer pairs. The chain must start with your certificate and end with a root CA. If any link is missing, clients on older Android or iOS versions will reject the connection even though modern browsers accept it.

Finally, test from the outside world. SSL Labs (www.ssllabs.com/ssltest) gives a grade from A to F and reports chain errors, protocol support, and cipher strength. A clean A grade is a realistic target for this configuration. External testing is important because a local curl test can pass while external clients fail due to a broken chain or a local DNS resolver serving cached records.

Troubleshooting

NGINX fails to start with "cannot load certificate"

This means the certificate file is unreadable or the path is wrong. Run sudo nginx -t to see the exact path it tries to read. Check the file exists and that its permissions allow NGINX to read it. The key must be 600 and owned by root.

Certificate works in Firefox but not in Chrome

This is almost always a chain issue. Chrome downloads the intermediate from the certificate's AIA field, while Firefox ships its own trust store and may handle missing intermediates differently. Rebuild the full chain file with cat yourdomain.crt yourdomain.ca-bundle and reload NGINX.

GoGetSSL certificate is valid but the site shows a warning

Check the domain match. A certificate for www.yourdomain.com does not cover yourdomain.com unless it is a wildcard or SAN entry. If you ordered a single-domain certificate, redirect www to the apex domain or order a certificate that covers both names.

FAQ

Where does NGINX expect the certificate files?

There is no fixed location. The ssl_certificate and ssl_certificate_key directives accept any absolute path. The standard convention is /etc/nginx/ssl/ for the key and fullchain, but you can place them anywhere NGINX can read.

Can a GoGetSSL certificate cover multiple domains?

Yes. A wildcard certificate covers all subdomains of one domain, for example *.yourdomain.com. A multi-domain (SAN) certificate covers a specific list of domains. Install either the same way, as long as the certificate file contains all the SAN entries you need.

How do I renew a GoGetSSL certificate on NGINX?

Order a new certificate or reissue the existing one, upload the new files, then run sudo systemctl reload nginx. There is no automated renewal like Let's Encrypt. Track the expiry date and renew at least a week before it lapses.

Does the private key expire?

No. The key remains valid indefinitely. When you reissue the certificate, you can reuse the same key if you still have it. This is safe and often convenient, because you do not need to regenerate the CSR or update the server configuration.

Why does the certificate chain matter in NGINX?

A browser must be able to trace the chain from your certificate to a root it trusts. If the intermediate is missing, the chain is broken and clients reject the connection. The fullchain file must contain the leaf plus all intermediates in the correct order.

Related articles

安装GoGetSSL证书到NGINX步骤

在NGINX上安装GoGetSSL证书只需要几步:在服务器上生成CSR、上传证书文件、修改站点配置指向证书路径、放行443端口并重载NGINX,最后用curl和SSL Labs验证证书链是否完整。私钥需设为600权限且与证书匹配,证书文件需按叶子证书加中间证书的顺序拼接。TLS 1.2以上版本是安全底线,建议把HTTP请求永久重定向到HTTPS。证书到期前一周应手动更新并重载NGINX。

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.