Today, I wanted to quickly update my expired SSL certificate. This did not went as quickly as I thought and I nearly destroyed my whole server setup. However, one good thing: I also have my PHP upgraded now because it somehow stopped working during my efforts. Let’s dive right into how to update an SSL certificate without destroying everything.
This guide is kind of a reminder for myself on how to do the update because I will most probably forget by next year where the files are located. So keep in mind: For your setup it might look different. FYI: I have Debian running on some virtual server by Netcup.de and I use namecheap.com as my certificate provider.
First, check your apache config to know where all the certificate and key files are located. The following command will show you some path below “Virtual Host Configuration”.apachectl -S
For me, this shows: *:443 mic.st (/etc/apache2/sites-enabled/000-default-ssl.conf:1
If you have setup an SSL certificate before and open this config file with nano
using:nano /etc/apache2/sites-enabled/000-default-ssl.conf
there should be some lines looking like this:
<VirtualHost *:443>
# lots of comments
# ...
ServerName mic.st <-- here you can put your domain, not sure if that HAS to match the one in the CSR.
DocumentRoot /var/www <--- this is apaches default folder to deliver web stuff
SSLEngine on
SSLCertificateFile /etc/ssl/xyz.crt <-- you will get this from your SSL provider
SSLCertificateKeyFile /etc/ssl/xyz.key <-- you will create this when creating a CSR request
SSLCertificateChainFile /etc/ssl/xyz.ca-bundle <-- you will get this from your SSL provider
# a lot more comments
</VirtualHost>
Code language: Bash (bash)
- Your SSL certificate provider will ask you for some CSR request. You have to create that on your server. You could reuse the same for every certificate. However, it’s better practice to recreate it for every renewal period.
- I prefer to run the following command for creating this CSR in my
/etc/ssl/
directory so that you don’t have to point to various directories from your apache config file.openssl req -new -newkey rsa:2048 -nodes -keyout xyz.key -out xyz.csr
This command will ask you for some details. Depending on your certificate provider, some information is mandatory and some is optional. Your certificate provider will most definitely have some information about what to put where.
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:NRW
Locality Name (eg, city) []:MyCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NA
Organizational Unit Name (eg, section) []:NA
Common Name (e.g. server FQDN or YOUR name) []:yourdomain.com
Email Address []:admin@yourdomain.com
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
Code language: Bash (bash)
- Copy the CSR file’s content using
cat xyz.csr
and just copy/paste everything into your certificate provider’s form - Depending on “how strong” your certificat is you have some validation step to prove that you own that domain you are issuing a certifcate for. For me it was uploading some validation .TXT file to
/var/www/.well-known/pki-validation
- As soon as the certification is done (this might take some minutes) you should be able to download the
.crt
and the.ca-bundle
files at your certificate provider’s website. - Upload these files to the location you found out about with:
apachectl -S
(If there are any old certicates located in that folder do yourself a favor and just delete them. Old certificates and/or key files are just confusing. Also doublecheck if all the filenames and paths are correct) - You can check your config file’s syntax with:
apachectl -t
However, if you have typos in your filename or path, this will not help you. - Restart apache to see if everything works with:
service apache2 restart
orsystemctl restart apache2
(should also work) - If you navigate to your website (after cleaning your browser’s cache) you should see the your website using
https://
working again without any issues.
Troubleshoot
- If you try to restart Apache and there are just errors shown that do not really help you, consider having a look at your apache logs. Unfortunately, when Apache starts with an error, this error is not shown. That is why you have to dive into the logs. For me I accidentally had an old .key file that did not belong to the renewed certificates.
- You might have to enable the SSL module for your Apache server first with:
sudo a2enmod ssl
(However, if you ever used a SSL certificate before you should not have to do that) - If you find a stackoverflow thread recommending to reinstall apache by using
sudo apt-get purge apache2
andsudo apt-get install apache2
because of some config issues:
DON’T DO THAT unless absolutely necessary. This might f*ck up some of your server configurations.
FYI: I did that because I was dumb and did not look into the log files first. After reinstalling Apache, I also had to reinstall PHP (for whatever reason, it just did not work anymore) and I had to reinstall MySQL as well to make WordPress work again. Aaand because that newer PHP version did not include that mysqli driver WordPress uses, this had to be manually reenabled as well. All of these steps did not solve the actual problems which weren’t more than just incompatible .key and certificate files. The only benefit of this unneeded debugging and fixing was that my PHP version is now updated. - If you want to redirect your HTTP requests (with and without www) to HTTPS plus redirecting to some subfolder (e.g. where your blog is located) you can use the following
.htaccess
file and just place it into your/var/www/
folder. I also added some rules to exclude folders from redirecting to HTTPS:
<IfModule mod_rewrite.c>
RewriteEngine on
# do not redirect BEGIN
RewriteRule ^.well-known/ - [L,NC]
RewriteRule ^someOtherFolder/ - [L,NC]
# do not redirect END
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^$ blog/ [L]
RewriteRule (.*) blog/$1 [L]
</IfModule>
Code language: Bash (bash)
(If .htacces is not working for your setup, you might have to enable it with: a2enmod rewrite
, also you might have to update your Apache config file, see: https://stackoverflow.com/questions/22797931/htaccess-is-not-working-in-linuxdebian-apache2