Skip to content
Search AlmaLinux

    Browse this documentation

    AlmaLinux 9: configuring and verifying nginx TLS

    In an AlmaLinux 9.8 privileged container (nginx 1.20.1 + OpenSSL): openssl req -x509, a conf.d/lab.conf, nginx -t, starting nginx, curl -sk and openssl s_client. Log: plans/content-expansion/evidence/logs/alma-nginx-tls.log.

    The certbot/Let’s Encrypt part was not executed here (it needs a public domain and ports 80/443) and follows the official flow.

    1. Path: the file behind ssl_certificate does not exist → nginx -t fails immediately;
    2. Key mismatch: certificate and key are not a pair → nginx -t reports key values mismatch;
    3. Incomplete chain: shipping only the leaf certificate breaks some clients → concatenate the intermediates into the same file.

    All three are caught by nginx -t, so the first command after editing is always nginx -t.

    Terminal window
    sudo dnf install -y nginx openssl
    sudo openssl req -x509 -nodes -newkey rsa:2048 -days 7 \
    -subj "/CN=lab.local" \
    -keyout /etc/pki/tls/private/lab.key \
    -out /etc/pki/tls/certs/lab.crt
    -rw-r--r-- 1 root root 1115 ... /etc/pki/tls/certs/lab.crt

    Self-signed is only for proving the configuration starts; browsers will flag it and production needs an ACME certificate.

    server {
    listen 8443 ssl;
    server_name lab.local;
    ssl_certificate /etc/pki/tls/certs/lab.crt;
    ssl_certificate_key /etc/pki/tls/private/lab.key;
    location / { return 200 "ok\n"; }
    }
    Terminal window
    sudo nginx -t && sudo nginx
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    Terminal window
    curl -sk https://127.0.0.1:8443/
    echo | openssl s_client -connect 127.0.0.1:8443 -servername lab.local 2>/dev/null | grep -E "Protocol|Cipher"
    ok
    New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
    Protocol : TLSv1.3

    The s_client output confirms TLSv1.3 and the cipher; seeing TLSv1.2 means the configuration restricts protocols.

    certbot: EPEL first, sign, then test renewal

    Section titled “certbot: EPEL first, sign, then test renewal”
    Terminal window
    sudo dnf install -y epel-release
    sudo dnf install -y certbot python3-certbot-nginx
    sudo certbot --nginx -d example.com
    sudo certbot renew --dry-run

    certbot comes from EPEL; --nginx edits the configuration and reloads, provided nginx runs, DNS points here and port 80 is reachable. The renew --dry-run validates the renewal path that keeps you out of trouble long term.

    • Editing the certificate without reloading: nginx keeps the old certificate;
    • Private key at 644: should be 600 so other users cannot read it;
    • Testing only 443: curl -k succeeding does not prove the chain is right; inspect it with openssl s_client -showcerts.

    Practice: self-signed 8443 plus a failure case

    Section titled “Practice: self-signed 8443 plus a failure case”
    Terminal window
    sudo dnf install -y nginx openssl
    sudo openssl req -x509 -nodes -newkey rsa:2048 -days 7 -subj "/CN=lab.local" \
    -keyout /etc/pki/tls/private/lab.key -out /etc/pki/tls/certs/lab.crt
    sudo tee /etc/nginx/conf.d/lab.conf >/dev/null <<'EOF'
    server {
    listen 8443 ssl;
    server_name lab.local;
    ssl_certificate /etc/pki/tls/certs/lab.crt;
    ssl_certificate_key /etc/pki/tls/private/lab.key;
    location / { return 200 "ok\n"; }
    }
    EOF
    sudo nginx -t && sudo nginx
    curl -sk https://127.0.0.1:8443/
    sudo sed -i 's#lab.crt#nope.crt#' /etc/nginx/conf.d/lab.conf
    sudo nginx -t # expected to fail

    Checks:

    1. The first nginx -t succeeds and curl -sk returns ok
    2. s_client shows TLSv1.3
    3. Breaking the path makes nginx -t fail clearly
    4. Restoring the path makes nginx -t pass again

    常见问题

    What causes nginx -t to report key values mismatch?

    The certificate and private key are not a pair (for example a new certificate with the old key). Compare `openssl x509 -noout -modulus` with `openssl rsa -noout -modulus`.

    What does an incomplete chain look like?

    Browsers and curl may work while some clients or Android devices report certificate errors. Check with `openssl s_client -showcerts` whether the intermediate is included.

    Does nginx need a manual reload after certbot renews?

    certbot deploy hooks usually reload automatically; with webroot setups lacking a hook, add `systemctl reload nginx` or a cron entry yourself.