3rd party SSL/TLS certs on TurnKey: convert CER/P7B to PEM

Stuart recently asked via support how to use third party .cer or .p7b SSL/TLS certificates with TurnKey v14.x.

As I don't run any permanent websites, I'm not super familiar with different certificate formats. My only experience really has been through my years with TurnKey and I've only ever encountered the text file .pem certs. So I did a quick bit of research to help Stuart out. I figured that seeing as it's been a little while since I wrote a blog post and this info may be useful for others, I wrote it up. :)


One might suspect that seeing as security is such an important thing on the internet, that most software that supports SSL/TLS (technically everyone should be using TLS these days), should also support all the available options.

My research suggests that you'd be wrong! Seeing as TurnKey can definitely use PEM files, I thought I'd show you how you can convert these other certificates to a PEM file cert.

It appears that there are 4 types of certificate file commonly in use. Hopefully the file extension will give you a clue. However, you may need to try reading the file (I suggest cat) to be sure. If you get nothing but a bunch of weird characters and colors, you've likely got a binary file. If it has only Latin characters (the certificate itself will still be a jumble of Latin characters, but they should be nicely formatted) that means it's one of the text formats.

So to start off, let's look at the different formats. Then after that, I'll cover converting them to PEM. :)

Four types of certificate file

PEM Format

As noted above, these are the most common form of cert, particular on Linux servers. The self signed certs which TurnKey ships with are PEMs. They're also the sort of certificate you'll get if you use our built-in Let's Encrypt integration.

These are an ASCII encoded text file. They contain "----BEGIN CERTIFICATE----" and "----END CERTIFICATE----" (and similar) statements, plus the certificate, etc expressed as text characters.

Several .pem certificates and even the private key can be chained together and included in one file, one below the other. Some apps expect the key to be in a separate file, so TurnKey also includes separate files for the key (cert.key) file and the Diffie-Hellman parameters (dhparams.pem) files. (FWIW the DH param key is what supports so called perfect forward secrecy). Both of these are also included in our the default self signed cert file. You can see that by grepping the file:

# grep -- '----' /etc/ssl/private/cert.pem 
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
-----BEGIN DH PARAMETERS-----
-----END DH PARAMETERS-----

I'll discuss that a little more later on, so please keep that in mind...

Obviously .pem is the most common file extension for these type of certs. But they can have a range of file extensions, including .pem, .key, .crt & .cer.

Chances are, these certs won't need any modification and you can simply drop them into the relevant place and they should "just work"! If you do need to modify them, you'll need to use some sort of text editor. I highly recommend that you not use Windows Notepad or MS Word or anything like that! If on Windows, I suggest Notepad++, but I'd suggest using nano on your server.

If it refuses to work, I suggest that you check your file against the format of the default TurnKey .pem file first. Then try to put the contents of your new .pem file in a similar order/format.

DER Format

These are a binary format of the ASCII PEM files discussed above.

They usually have the extension .der or .cer. Apparently they're most commonly used with Java applications.

P7B/PKCS#7

These files are Base64 encoded ASCII text files. They include the text "----BEGIN PKCS----" & "----END PKCS7----" statements.

They can contain a certificate chain, but not the private certificate key.

Generally these have a file extension of .p7b or .p7c. Most often found on Windows computers, Java Tomcat can also apparently support these certs.

PFX/PKCS#12

These files are another binary format and often include the certificate, certificate chain and the private key, all in the one binary file.

My research suggest that these are essentially limited to Windows OS. They have an extension of .pfx or .p12.

How to convert alternate types to PEM

As promised, here is how to convert the different types to a PEM format:

DER to PEM

To convert DER (.der, .cer) files to PEM:
openssl x509 -inform der -in certificate.der -out certificate.pem

P7B to PEM

To convert P7B (.p7b, .p7c) files to PEM:
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.pem

PFX to PEM

To convert PFX (.pfx, .p12) files to PEM:
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes

Please note, that the resulting PEM file will include the certificate and key (and possibly certificate chain).

You may wish/need to open the file in a text editor and copy each certificate, key etc (including the BEGIN/END statements) to its own individual text file and save with an appropriate name.

Building the Certs so they "just work™"

By default, TurnKey is configured to use a single cert for all services. So if you are hosting from a single domain, and wish to use the same cert for all services (e.g. Webmin, Webshell & Adminer), you can recreate the the certs in the format that TurnKey uses by default and drop them into the default location, everything should "just work™"

Please note, that Stuart mentioned that if you are using an AWS Marketplace TurnKey instance, you'll need to enable root. It wasn't working for him with sudo, but everything was fine after enabling, and relogging in as root. If you wish to disable the root account again after we're done, then just rerun the command but swap the off for on.

So first up, let's move the default cert & key:

mv /etc/ssl/private/cert.pem /etc/ssl/private/orig.cert.pem
mv /etc/ssl/private/cert.key /etc/ssl/private/orig.cert.key

Then move in the new cert, plus the private key:

mv path/to/converted/certificate.pem /etc/ssl/private/cert.pem
mv path/to/converted/certificate.key /etc/ssl/private/cert.key

Now we need to make the new cert have the same format as the original one. I posted the default certificate earlier on, but if you want to double check it again, run this:

grep -- '----' /etc/ssl/private/orig.cert.pem

The contents of the default certificate are posted above (certificate, private key & dh-parameters). Please note that the default TurnKey DH parameters can be found here: /etc/ssl/private/dhparams.pem.

As an additional note, all TurnKey servers (re)generate a unique 2048 bit DH parameter key on first boot. With the current state of technology, 2048 bit keys are considered "unbreakable". But if you're a security junkie, then you could "crank up" the security of your HTTPS connections (to make them "unbreakable" plus!) by generating a larger dhparams key. Please note, generating these keys is a CPU intensive task, and bigger keys take exponentially longer to generate than smaller keys.

Moving along, double check what the contents of your new cert is (grep -- '----' /etc/ssl/private/cert.pem). It will most likely have just a certificate, i.e. this output:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

If it has a number of certificates (i.e. multiple "BEGIN CERTIFICATE" and "END CERTIFICATE" lines), that's fine (my reading suggests that is generally referred to as "full chain certificate"). Assuming it has nothing other than a certificate (or 2), let's make it match the original cert.pem, by adding the private key and the DH_params:

cat /etc/ssl/private/cert.key >> /etc/ssl/private/cert.pem
cat /etc/ssl/private/dhparams.pem >> /etc/ssl/private/cert.pem

Now double check the contents of your cert.pem file (grep -- '----' /etc/ssl/private/cert.pem). As per the original TurnKey certificate, it should look something like this:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
-----BEGIN DH PARAMETERS-----
-----END DH PARAMETERS-----

Final Steps

The next step is to lock down the permissions so that only root can access them. Ideally you should keep your keys in the default location (/etc/ssl/private). As the name suggests, we want that directory to be readable by root only. So let's lock it down!:

chown -R root:root /etc/ssl/private
chmod 400 /etc/ssl/private/*

Now restart services (this is for a LAMP or LAMP based appliance, other appliances may require different services to be restarted):

service apache2 restart
service stunnel4 restart

Once you have got your cert in the format you need, moved it to the relevant location and ensured that it's a similar format to above, locked down permissions, then it's time to test that everything works as it should!

Browse to your server using HTTPS and double check it's all working. Please don't forget to clean up any unneeded files. Also please remember that many of these files contain your certificate private key. If that leaks, then anyone can decrypt any traffic with your website. That's really bad! So guard them closely and don't post the contents of these files anywhere (using the grep commands I posted above it ok as it doesn't include any of the private/secret stuff).

You should now be good to go! :)

As noted above, I don't have extensive experience with SSL/TLS certs. So if I've got anything wrong, please post a correction (in the comments below).

Comments

Stuart Dyer's picture

Hi Jeremy, Just though of this I have been using webmin to generate a CSR, with the above and doing it via command line where does the CSR come from ? Thanks Stuart
Jeremy Davis's picture

TBH, I'm not particularly familiar with it (you must be getting sick of me saying that...) but it should "just work"!

To adjust the defaults, I suggest that you just edit the default template (/etc/ssl/turnkey.cnf) to your requirements. Alternatively, you could copy the existing template (then adjust). To use a new template, you'll need to explicitly use it via the '-t' or '--template' switch, e.g. '-t /etc/ssl/new-template.cnf'.

Then run it like this (add the '-t /path/to/template' before your FQDN):

turnkey-make-ssl-cert --csr <YOUR_FQDN>
Replacing <YOUR_FQDN> with your full domain (e.g. www.example.com).

You'll then find the new .crt file in /usr/local/share/ca-certificates/<YOUR_FQDN>.crt

Stuart Dyer's picture

ran that, found the cert, but it begins with   -----BEGIN CERTIFICATE----- -----END CERTIFICATE-----   Normally starts with begin Certificate Singing Request Tried this csr in our CA and it rejected it
Jeremy Davis's picture

I wonder what is going on there?!?

I've opened an issue on the tracker and hopefully John (@Dude4Linux) will have some input (he wrote the script).

In the meantime, it should be easily possible directly from the commandline. You'll need to use the OpenSSL commandline tool (opensll). Again I have no clue how to do what your after, but hopefully google can help. Also theirs always the man(ual) page:

man openssl
John Carver's picture

As I recall, I used the instructions from StartCom for preparing the certificate request. At the time, they were the only source of free ssl certs and I was too cheap to spend money testing other cert providers.  I never noticed that the header was incorrect, but given what happened to StartCom, I'm not surprised they weren't following proper procedures.  I thought that this functionality was replaced by Let's Encrypt.

Information is free, knowledge is acquired, but wisdom is earned.

John Carver's picture

Stuart, the turnkey-make-ssl-cert with the --csr option produces three files, a certificate request, a temporary cert you can use while you wait for the real cert, and a .key file to be used with both the .csr and .crt.  Jeremy's instructions told you to look for the .crt file which is the temporary cert.  Look for the .csr file in the same directory, or run it again with the --out option.

# turnkey-make-ssl-cert -o example.com -r www.example.com
# ls
example.com.crt  example.com.csr  example.com.key

# head -1 example.com.*
==> example.com.crt <==
-----BEGIN CERTIFICATE-----

==> example.com.csr <==
-----BEGIN CERTIFICATE REQUEST-----

==> example.com.key <==
-----BEGIN PRIVATE KEY-----

Please try submitting the .csr file and let us know it that works.  Sorry for the confusion.

Information is free, knowledge is acquired, but wisdom is earned.

Jeremy Davis's picture

It looks like you need to use the `--out` switch with the `--csr` switch, otherwise it doesn't seem to work. However, even then, it only seems to work if you are already in the directory where you want the cert to go.

With a bit of fiddling, I'm pretty sure I've got it working:

root@lamp ~# mkdir cert
root@lamp ~# cd cert
root@lamp ~/cert# turnkey-make-ssl-cert --csr --out www.tester.com
root@lamp ~/cert# ls
www.tester.com.crt  www.tester.com.csr  www.tester.com.key
root@lamp ~/cert# grep -- '-'  www.tester.com.csr 
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
And John you are right, that now we have Let's Encrypt, there's not as much need for this sort of thing anymore. However, there are still valid reasons why a person may still wish to get a cert from an alternate third party (or perhaps even an onsite CA).
nam viet luat's picture

any onw please help me to resol my errr when i add SSl/TLS Certs. My web is cant run after added  :(

Jeremy Davis's picture

Hi there,

Please note that this is the TurnKey Linux forums. If you server is TurnKey Linux, then I suggest that you start a new thread in the forums and explain in as much detail as possible what steps you've taken and what errors are occurring.

My guess is that the error you are seeing is perhaps related to this blog post (i.e the wrong type of certificate for the service) but I could be wrong.

Landis Arnold's picture

There was an older instruction set here that has always worked well.

Generate a CSR

Submit the CSR to a SSL CERT generator (ie namecheap.com)

Then in WebMin point your Apache instances to the CSR and CERT.

Has always worked for me.  I can be more explicit.

 

Pages

Add new comment