SSL certificates have become a de facto part of every website. If you don’t yet have an SSL on your site to encrypt data, you should. Rather than showing an extra layer of security on sites protected by SSL, modern browsers instead now display a warning when a website does not have an SSL, essentially requiring sites to maintain their positive image.
When moving from one server to another, what needs to happen to your SSL to maintain your secure status? We’ll cover the basics for transferring traditional and Let’s Encrypt SSLs to Ubuntu 16.04 and CentOS 7.
Can SSLs be transferred between servers?
Absolutely! An SSL consists just of a handful of text files and a bit of configuration for the secure service. Additionally, there is a misconception that certificates are tied permanently to their IP address or physical server, but this is not true. In reality, they are linked only to the domain name(s) listed the certificate and are very migratable. Technically, an SSL can be used on multiple servers or services to protect the same domain name. We will leverage this concept to help us move our SSLs.
You will need to have a copy of your SSL Certificate and SSL Private Key, as well as any ‘Chain Certificates.’ Often these will be two separate files, called domain.com.crt for the certificate, and domain.com.key for the private key, as well as an additional signing_authority.crt file for the chain certificate. Another popular naming convention for these files is cert.pem and key.pem, but sometimes they have no file suffix at all (.pem or .crt).
How can you tell where to get these files? We’ll get into how to determine the locations for these configurations first.
Step 1: Collecting SSL Files
Debian SSL File Location
In distributions of Linux, including Ubuntu, you can check the loaded virtual hosts on Apache using:
CentOS SSL File Location
For RHEL based distributions, including CentOS, you can use:
Both of these commands will list the running configuration settings, including all loaded virtual hosts and their configuration file locations. We’re looking for the domain name of the SSL we want to copy, and the HTTPS port 443. On my Ubuntu test machine, for example, this line is the output for the domain in question:
port 443 namevhost domain.com (/etc/apache2/sites-enabled/domain.com.conf:1)
Since we are copying the SSL for the domain.com domain, we’ll check this configuration file, and look for the virtual host block that references port 443.
Searching through the file, we find:
This block of text describes all three files that we need to bring to the new server: the certificate file (cert.pem), the private key (privkey.pem) and the intermediate certificates (chain.pem).
Step 2: Copying SSL Files
From the file paths we discovered in the last step, we know that all of the SSL files for this site exist in the /etc/ssl/domain.com directory. So, we can copy this whole folder to the new server using the rsync tool. Assuming that the old server has an IP of 188.8.131.52, hop over to your new server, and run the command below. Trailing slashes (/) are very important for this command!
mkdir -p /etc/ssl
rsync -avz email@example.com:/etc/ssl/domain.com /etc/ssl/
This method preserves the ownership and permissions of these files, so we should not have to do anything else in that regard. Our next section, step 3, is split into two sections. Pick step 3A if you’re new server is Ubuntu 16.04 or step 3B if you new server is CentOS 7.
Step 3A: Setting up Apache on the new server (Ubuntu 16.04)
A non-SSL virtual host set up is necessary for your domain on the new server. If you have not yet done so, you will need to install and activate mod_ssl to allow Apache to parse SSL communication on the target machine:
apt-get install mod_ssl
If you get a message that mod_ssl is not available for installation, its possibly installed through a different package. Check to see if that is the case:
dpkg -S mod_ssl.so
If this returns a positive result, you ‘ll run:
a2enmod ssl to complete the activation. After enabling mod_ssl, restart Apache:
systemctl restart apache2
Lastly, there is one configuration file to change, which will allow serving named virtual hosts. The activation of the SSL module lets Apache listen on port 443, but we need to be able to host multiple sites per IP. Open up the /etc/apache2/ports.conf file:
Ensure that the contents mimic this output:
Specifically, we are ensuring that the NameVirtualHost lines are present. Once this is true, we can test and reload the configuration to bring it into effect:
systemctl reload apache2
Next, we must add a configuration for the website to call the SSL files we just copied over. If you are using the same document root on the new server as on the old, you can copy and paste the original virtual host block into a new configuration file in /etc/apache2/sites-available/. Be sure to update referenced IPs to match the new server.
If there are differences in the running modules or other customizations performed on the new machine, make a copy of the existing non-SSL virtual host block on the target server into a separate file. Also, under /etc/apache2/sites-available/, update the port number, and add the three lines for the SSL files. For our example, I copied and pasted the exact contents of the old file into /etc/apache2/sites-available/domain.com_ssl.conf.
After having done so, we run:
This links the configuration into the /etc/apache2/sites-enabled/ folder. This site name will change depending on what you named the configuration file (just cut off the .conf). Next, we test this new configuration:
If everything comes back OK, we can reload the configuration files for the apache2 service:
systemctl reload apache2
Each command line operation for CentOS is very different, but the overall procedure is the same, and the configuration files will have similar content. First, confirm that Apache is configured to support SSL traffic:
yum install mod_ssl
This installation procedure should automatically set up a ssl.conf file for you in /etc/httpd/conf.d/ for listening on port 443 and restart Apache, but it may not enable named virtual hosts. Make sure you add the following line to your httpd.conf file as well if it is not already present. Adding these lines allows you to serve multiple sites per IP address using virtual host blocks.
Next, we must add a configuration for the website to call the SSL files we just copied over. If you are using the same document root on the new server as on the old, copy and paste the original virtual host block into a new configuration file in /etc/httpd/conf.d/, making sure that the IP addresses are updated to match those on the target server.
If there are differences in the running modules or other customizations performed on the new machine, you can make a copy of the existing non-SSL virtual host block on the target server into a separate file. Also, in /etc/httpd/conf.d/, update the port number, and add the three lines for the SSL files.
Once created, test the configuration syntax of the file:
httpd -tThe output will either say ‘Syntax OK’ or tell you what file and line is problematic. If everything is okay, you can reload the configuration for Apache:
systemctl reload httpd
What if I use Let’s Encrypt?
Let’s Encrypt SSLs are just as transferable as any other SSL, but manually creating an SSL virtual host config file sometimes causes conflict with future installations of Let’s Encrypt. So, there is a particular procedure to be followed.
Transferring Let’s Encrypt Installations
First, Let’s Encrypt should be installed on the new server. For Ubuntu 16.04, that looks like this:
apt-get install python-certbot-apache
For CentOS 7, use these commands:
yum install epel-release
yum install python-certbot-apache
Once installed on either distro, set a cron to renew the certificates automatically. You can set these up by running
crontab -e as the root user. The cron on my Ubuntu machine looks like this:
45 2 * * 6 /usr/bin/certbot renew && systemctl reload apache2
On my CentOS server, it looks like this:
45 2 * * 6 /usr/local/letsencrypt/certbot-auto renew && systemctl reload httpd
Next, we can bring over the entire /etc/letsencrypt directory, which houses the configuration files. This directory holds the certificates and the keys themselves. On the new server, we run:
rsync -avz 184.108.40.206:/etc/letsencrypt /etc/
Now that the files are in place, we can have Let’s Encrypt reinstall all of the certificates we synced over:
/usr/local/letsencrypt/certbot-auto install --apache
Running the command presents a numbered list of the certificates in the /etc/letsencrypt folder. Select the number for the site you’d like to set up a configuration for, and it will create your configuration file; Once done, you only need to reload Apache:
systemctl reload apache2 #ubuntu
systemctl reload httpd #centos
Step 4: Confirming operation
The new server can now be tested using hosts file modification, detailed in this article. It’s truly is the best way to test the functionality of a migration target, as both browser and server believe that this is real traffic on the real domain name.
Once you set up your hosts file and flush your DNS cache, you should simply be able to load up the website in your browser using https, and see your website secured with the original certificate on the target machine! No worries though; live traffic is still routed to the original server with the same SSL, so your site visitors will not notice your testing.
If you are using Let’s Encrypt, it is important to keep your certificate expiration dates in mind. For instance, if your certificates are slated to expire in 7 days, you will want to update DNS promptly after the transfer, so that the new server can take over certificate renewals. If you miss this window and the certificate renews on the source server, you can simply re-run the rsync command where we collected /etc/letsencrypt:
rsync -avz 220.127.116.11:/etc/letsencrypt /etc/