SSL certificates and HTTPS explained
SSL certificates and HTTPS explained
This article explains what SSL/TLS certificates are and how to correctly implement HTTPS on your Pixzo server.
Requirements
- Access to your web server (Apache 2.4.41+ or Nginx 1.18+) - Domain name with DNS management - Root or sudo access via SSH - OpenSSL version 1.1.1 or higher installed
Steps
1. Generate a private key and CSR
Create a 2048-bit RSA private key and a Certificate Signing Request (CSR) for your domain:
openssl req -new -newkey rsa:2048 -nodes -keyout jouwdomein.key -out jouwdomein.csr
During the process, enter your domain name (Common Name) and organization details.
2. Request a certificate from a CA
Use Let's Encrypt for a free DV certificate via Certbot:
sudo certbot certonly --standalone -d jouwdomein.nl -d www.jouwdomein.nl
Certbot places the certificate in `/etc/letsencrypt/live/jouwdomein.nl/`.
3. Download the intermediate certificate
Fetch the correct intermediate certificate chain for your CA. For Let's Encrypt, this is included automatically. Verify the chain:
openssl crl2pkcs7 -nocrl -certfile /etc/letsencrypt/live/jouwdomein.nl/fullchain.pem | openssl pkcs7 -print_certs -text | grep "Subject:"4. Configure your web server for TLS 1.2 or higher
Add the following configuration to your Apache virtual host or Nginx server block:
Apache
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/jouwdomein.nl/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/jouwdomein.nl/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder onNginx
ssl_certificate /etc/letsencrypt/live/jouwdomein.nl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jouwdomein.nl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;5. Remove weak cipher suites
Exclude RC4, SHA-1, and 3DES from your cipher configuration:
OpenSSL test: RC4 must not appear
openssl ciphers -v 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' | grep -i rc46. Enable HTTP-to-HTTPS redirect
Add a redirect to HTTPS for all HTTP traffic:
<VirtualHost *:80>
ServerName jouwdomein.nl
Redirect permanent / https://jouwdomein.nl/
</VirtualHost>7. Reload the server configuration
Apply the changes without downtime:
sudo systemctl reload apache2 for Apache
sudo systemctl reload nginx for Nginx8. Set up automatic renewal (Let's Encrypt)
Certbot can renew certificates automatically. Test the renewal:
sudo certbot renew --dry-run
Add a cronjob for daily checks (`0 3 * /usr/bin/certbot renew --quiet`).
Verification
Check whether your HTTPS works correctly:
curl -vI https://jouwdomein.nl 2>&1 | grep -E "(SSL connection|TLS|HTTP/2)"
Use the SSL Labs test (ssllabs.com/ssltest) or the OpenSSL s_client:
openssl s_client -connect jouwdomein.nl:443 -servername jouwdomein.nl 2>/dev/null | openssl x509 -noout -dates -subject -issuerFrequently asked problems
Certificate is not trusted by the browser
The intermediate certificate is missing from the chain. The entire chain must be included — check with:
openssl s_client -connect jouwdomein.nl:443 -showcerts | grep "s:" | uniq
You do not see the root certificate; only the end certificate and intermediate should be visible. Add `SSLCertificateChainFile` in Apache or the full chain file in Nginx.
Error message "certificate has expired" after installation
Check whether the system time is correctly synchronized:
timedatectl status
Force NTP sync: `sudo timedatectl set-ntp true`.
TLS 1.0 or 1.1 still active despite configuration
Some load balancers or reverse proxies rewrite the SSL configuration. Check whether global SSL settings in `/etc/ssl/` or an `ssl.conf` file override the local settings with `grep -r "SSLProtocol\|ssl_protocols" /etc/`.