How to Migrate SSL Certificates to a New Server
When migrating services to a new Breeze instance, your SSL/TLS certificates need to move along with them. Whether you use Let's Encrypt, a commercial certificate authority, or self-signed certificates, this guide covers transferring them correctly and keeping your sites secure during the transition.
Understanding SSL Certificate Files
An SSL certificate typically consists of several files:
- Certificate file (
.crtorfullchain.pem) — your domain's public certificate - Private key (
.keyorprivkey.pem) — the secret key paired with the certificate - CA bundle / chain (
chain.pemorca-bundle.crt) — intermediate certificates linking yours to a trusted root
Option 1: Migrate Let's Encrypt Certificates
Transfer the Entire Let's Encrypt Directory
Let's Encrypt stores everything under /etc/letsencrypt/. Copy the entire directory to preserve renewal configurations:
rsync -avz user@source-ip:/etc/letsencrypt/ /etc/letsencrypt/
Install Certbot on the new Breeze:
sudo apt install -y certbot python3-certbot-nginx
Verify the certificates transferred correctly:
sudo certbot certificates
Test automatic renewal:
sudo certbot renew --dry-run
Or Issue Fresh Certificates
Alternatively, after pointing DNS to your new Breeze, simply issue fresh certificates. This is often the cleaner approach:
sudo certbot --nginx -d example.com -d www.example.com
Option 2: Migrate Commercial SSL Certificates
For certificates from a commercial CA, you need to transfer three files:
# On the source server, locate your certificate files
ls -la /etc/ssl/certs/example.com.*
ls -la /etc/ssl/private/example.com.key
# Transfer to the new Breeze
scp /etc/ssl/certs/example.com.crt user@breeze-ip:/etc/ssl/certs/
scp /etc/ssl/certs/example.com.ca-bundle user@breeze-ip:/etc/ssl/certs/
scp /etc/ssl/private/example.com.key user@breeze-ip:/etc/ssl/private/
Set correct permissions on the private key:
sudo chmod 600 /etc/ssl/private/example.com.key
sudo chown root:root /etc/ssl/private/example.com.key
Step 3: Update Web Server Configuration
Update Nginx to reference the certificate paths on the new Breeze:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_trusted_certificate /etc/ssl/certs/example.com.ca-bundle;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
}
Test the configuration and reload:
sudo nginx -t
sudo systemctl reload nginx
Step 4: Verify SSL Is Working
Test the certificate from the command line:
openssl s_client -connect example.com:443 -servername example.com /dev/null | openssl x509 -noout -dates -subject
Check for the correct domain name, valid date range, and complete certificate chain. You can also use online SSL test tools to verify your configuration and check for common issues.
Handling Certificate Expiry During Migration
If your certificate expires soon, plan accordingly:
- Renew before migrating — get a fresh certificate on the source server, then transfer it
- Issue a new certificate after migration — once DNS points to the Breeze, get a new cert directly
- Use a temporary self-signed certificate — for testing only, never in production
Security Best Practices
- Never transfer private keys over unencrypted channels — always use SCP or SFTP
- Restrict private key file permissions to
600and ownership toroot - Delete certificate files from the old server after confirming the migration is complete
- Set up automated renewal with Certbot to avoid future expiry surprises