The Curious Dev

Various coding insights from a curious dev

TLS Certificate Basics

Over the last few years we’ve seen a series of high profile SSL fails with names like Heartbleed, BEAST and POODLE which are based on various flaws in SSL and its various algorithm/cipher implementations. SSL (otherwise formerly known as SSLv3) is dead and has now all but been abandoned as essentially “not fixable”.

TLS is now the only show in town with three active versions TLSv1, TLSv1.1 and TLSv1.2 (and TLSv1.3 is on its way in hopefully 2016). Given the age of TLSv1, it probably doesn’t hurt to disable it too, unless you’ve got some semi-ancient clients (Java 6 can only do up to TLSv1).

With an increased focus on security, I thought I’d document some simple steps to getting a new TLS certificate setup.

One can purchase a certificate from a Certificate Authority (CA) such as StartSSL, Comodo or Gandi. Alternatively, one could generate a certificate but that wouldn’t be signed by a trusted CA, a self-signed certificate, which thus wouldn’t be trusted by browsers. Self-signed certificates result in some at times scary looking browser security warnings but it depends on the target audience and your degree of annoyance.

Generate a private key

To get things started you’ll need to generate a private key file:

openssl genrsa -out dash.thecuriousdev.com.key 2048

This will produce a file dash.thecuriousdev.com.key which will contain something like this (truncated):

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAw1Fo5Ay3U/AeO0AVNieFpjcEe63S8bAN8+YPqpIwQzauXzTA
ukOOXSYXR+RrN33KFQT+AzusQ1Ska5+VNM0tV+cjgYMB2I0JsUQ6tQ==
-----END RSA PRIVATE KEY-----

Generate a CSR

As an input of the certificate creation process you’ll need a Certificate Signing Request (CSR) which you generate from your private key:

openssl req -new -key dash.thecuriousdev.com.key -out thecuriousdev.com.csr -config "C:\Program Files (x86)\Git\ssl\openssl.cnf"

That last bit with the openssl.cnf file is required otherwise OpenSSL has a whinge about not finding the configuration, the OpenSSL on my machine is the one that came with the very helpful Git Bash tools package, so I just tell it where the config is.

The output file dash.thecuriousdev.com.csr will look something like this (truncated):

-----BEGIN CERTIFICATE REQUEST-----
MIICsjCCAZoCAQAwbTELMAkGA1UEBhMCQVUxGjAYBgNVBAgMEVdlc3Rlcm4gQXVz
CWHCQjHlWoTnuKeRpXuEVhF3Dt5RHiD9G4c3TQ4207V4azsvEt/7HWH1An6F6RRv
-----END CERTIFICATE REQUEST-----

When buying a certificate there will typically be a text area to input the contents of this file.

Purchasing the Certificate

Upon purchasing the certificate from your CA, you’ll typically be provided with a certificate file to download or a block of text to select, it’ll have the form similar to this (truncated):

-----BEGIN CERTIFICATE-----
MIIGMjCCBRqgAwIBAgIHBjI4n6fkszANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE
9YVDp+AnN/0tLTS0MxVVtJJZHwDCF3lRrcnuNm6tzufSwQlFLnsoqQWEufFLls8a
-----END CERTIFICATE-----

In addition to your certificate you’ll likely be provided an “intermediate” CA certificate which links your certificate up to the global certificate used by the CA (which is typically included in the various browsers etc). Depending on the CA, there may be multiple intermediate certificates.

Save the contents of all of these certificates to the same file, i.e. concatenated one after another and name it accordingly, such as dash.thecuriousdev.com.pem.

Note: I’m not sure whether the order of the certificate blocks makes a difference.

This looks something like this truncated example:

 -----BEGIN CERTIFICATE-----
 MIIGMjCCBRqgAwIBAgIHBjI4n6fkszANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE
 9YVDp+AnN/0tLTS0MxVVtJJZHwDCF3lRrcnuNm6tzufSwQlFLnsoqQWEufFLls8a
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIIF2TCCA8GgAwIBAgIHFxU9nqs/vzANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
 EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
 -----END CERTIFICATE-----
 

Create a PKCS12 keystore

Next up we’ll generate a PKCS12 keystore from the certificates (pem file) and private key.

Input files needed:

  • pem file - dash.thecuriousdev.com.pem (containing the new certificate and any intermediate certificates)
  • private key - dash.thecuriousdev.com.key (from your original steps to generate the CSR)

Using OpenSSL with the required certificates and key it can generate a PKCS12 keystore (typically with a .p12 extension). You’ll be prompted for a password, for this example I’ll stick with the default changeit that the Java keytool uses.

openssl pkcs12 -export -in dash.thecuriousdev.com.pem -inkey dash.thecuriousdev.com.key -out dash.thecuriousdev.com.p12 -name dash.thecuriousdev.com

Create a JKS keystore

Now that we’ve got a PKCS12 keystore, we can easily produce our JKS keystore from it.

keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore dash.thecuriousdev.com.jks -srckeystore dash.thecuriousdev.com.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias dash.thecuriousdev.com

Note: I believe there can be problems if a srcstorepass is not provided.

Summary

You should now have a JKS keystore dash.thecuriousdev.com.jks that will contain one entry, keytool -list -keystore dash.thecuriousdev.com.jks, will produce something like this:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

dash.thecuriousdev.com, 08/07/2015, PrivateKeyEntry,
Certificate fingerprint (SHA1): 76:E4:54:8B:71:72:F6:1F:CB:80:47:D5:A9:C6:1C:46:0E:91:96:2E

You can now use this keystore in your web/application server or even for AWS CloudFront, more on this in another post perhaps.

SSH Tunnels With PuTTY

In a previous post I covered how I’ve been using PuTTY to get through the day, I decided to expand on it a little further and document a couple steps to bring a particular server’s ports closer to you … even if they’re firewalled away.

An ssh tunnel can be explained quite simply as:

an encrypted connection that is used to transport another protocol

Single Server

sshing into a server is one thing, but what if port 22 is the only practical accessible port due to firewall restrictions? To connect to a database on the server one can use a tunnel to “sneak” through.

To expand on this example further, let’s say there’s a postgres server running on port 5432 but the firewall is blocking access to it (as it probably should be). It is trivial to setup an ssh tunnel to effectively bring the port to the local machine.

Using PuTTY, configure the connection as per normal, for example:

SSH Session

Then in the SSH settings, add a port value for the Source port field, this is the port you’ll need to use in your database tool of choice, pgAdminIII perhaps. This can be any port really, except for anything already in use locally, i.e. if you’ve got postgres running locally, don’t choose 5432.

In the Destination field, this is the important bit, set the host:port combination as though you were directly sitting at the remote server, i.e. localhost:5432 for the server’s local database.

SSH > Tunnels configuration

Once you open the session, the tunnel is live too. One can now go into pgAdminIII and setup a connection to a local database:

Create a new connection

Note the port in use and that the host is localhost as it is connecting to the local end of the SSH Tunnel on the configured port 15432.

pgAdminIII has an option to configure an SSH Tunnel in the connection creation dialog but I haven’t worked out how that fits in to the picture just yet.

So there’s a connection, does it work?

Sure does!

As a side note: if you close your PuTTY session, your tunnel will go with it.

SSH and PuTTY

Lately I’ve been working with quite a few AWS EC2 Instances which have required me to SSH into them at various points for troubleshooting, so I thought I might as well document a few basics of SSH with key pairs.

Using PuTTY

PuTTY is the most prominant Secure Shell (SSH) client out there as demonstrated by its inclusion by serveral other applications, such as WinSCP. PuTTY can make the process of connecting remotely to a server via SSH (mostly) painless.

Get PuTTY, Pageant and PuTTYgen from here: www.chiark.greenend.org.uk/~sgtatham/putty/download.html and put them somewhere useful – such as a directory in your Dropbox that is on your system PATH.

If you have a linux / unix style machine you can generally connect to it via SSH, often with just your account username and password. This is mostly fine but typing your password every single time you login can get tedious, especially if you’re jumping onto many different servers throughout the course of your day.

However, if you have suitably configured the machines you’re using with an SSH key pair you can SSH into any machine at will with the key exchange taking place behind the scenes. If your private key does not have a passphrase on it, you wont have to enter your password. If there is a passphrase, then you will be prompted for that each time you connect, unless you also configure Pageant to handle that (it’s pretty simple).

Generating a Key Pair with PuTTYgen

To use keys with SSH/PuTTY you will need to generate a pair, PuTTYGen is a tool that sits within the PuTTY ecosystem and serves exactly this purpose.

Here’s the initial screen of PuTTYgen, the large blank area is what will be filled in when we generate a key:

Initial screen of PuTTYgen

Simply click the Generate button to start the key generation process then, as directed on screen, move the mouse around to provide random input to the generation process:

Generating a key

Here’s a generated key, with a key fingerprint and comment, ideally one should put a decent comment in the key that describes the key’s use e.g. WebServer-UAT-key:

A generated key without a passphrase

Adding a passphrase will secure you key from use, but when you use it you’ll have to provide the passphrase (unless you use Pageant):

A generated key with a passphrase

Now you can simply save both the Public and Private keys into separate files, I like <Purpose>-<environment>.ppk or perhaps <Machine>-<environment>.pub for the key names e.g. WebServers_TEST.ppk or AppServers_UAT.pub:

Saving public/private key components

Keep your keys safe

If you’re not using a passphrase on your private key, then anyone with the key can use it, so it makes sense to store it in a safe place.

This location may be something as simple as your home directory on your PC (which is typically not accessible to other users) or in a “secure drive” along the lines of something like Truecrypt (project discontinued, but seems to have been forked as CipherShed) which you can secure with a password and even put in your Dropbox for sharing amongst your computers.

Setup public key on your server

To use a key pair over SSH you need to put your public key on the server in a specific location. This location is a file to which your public key is appended to: /home/scott/.ssh/authorized_keys.

So this is a simple as SCPing your public key to your server, converting the putty generated key to something suitable for consumption by the SSH daemon and then appending the modified key to the authorized_keys file.

Let’s assume you have SCP’d your public key into user home i.e. /home/scott. In one command you can convert the key and append the contents of the key file into the authorized_keys file, like so:

scott@Jules:~$ ssh-keygen -i -f WebServers_UAT.pub >> ~/.ssh/authorized_keys

So this is how our authorized_keys file would then look:

authorized_keys file

The SSH config needs to be reloaded to take effect:

scott@Jules:~$ sudo /etc/init.d/ssh reload

You now should probably remove the public key as their is no point in having it hanging around cluttering up your user home, obviously that is assuming it’s backed up elsewhere.

That is it for the server.

Using keys with PuTTY

For your server’s session, simply add the private key file in the Connection > SSH > Auth section of the PuTTy configuration screen:

ssh key config screen

Without any passphrase, you’ll log straight into your server:

logged into server

If you had a passphrase on your key, this is what it’d look like:

prompt for passphrase

Using Pageant to make it even easier

If you’ve not put a passphrase on your key, then this step will be somewhat redundant, but if you have, then configuring pageant will save you time.

Pageant is another tool that comes alongside PuTTY and it can easily be made to startup when you start you computer, or perhaps just when you begin some new task that you know you’ll be logging into serveral servers with the same key or the same server multiple times.

When you use a key with PuTTY that has a passphrase set, then it will ask you every single time what that passphrase is. Pageant takes care of the authentication so long as you’ve provided the key’s passphrase once upon startup, and it keeps that information in memory rather than on disk so it is considerably more secure too (supposedly).

Initially, the Pageant application will be rather minimalist:

Initial Pageant application screen

Click the ”Add Key” button and choose a private key with a passphrase:

Adding a key to Pageant

Now you can just launch a PuTTY instance to your server with the relevant private key and you’ll be logged straight in!

Automatically logged in to server

AWS Instances

I’ve been developing AWS Cloud Formation templates over the last while and that has entailed an iterative process of SSHing into numerous EC2 instances skimming through logs to work out why something isn’t working as expected. If the instances were stable and were up for a reasonable period it might make sense to save a session in PuTTY to load up for a particular IP, but when one is terminating tens of instances in a day it’s not viable or logical to do so.

So the workflow is as basic as navigating to the instance in the AWS Console, copying its IP and pasting into a generic “AWS-Instance” session which has the relevant key and username (often it’s “ec2-user” or “ubuntu”) and then loading that, no passwords required.

In the AWS Console and in the properties of an EC2 instance, select the IP:

AWS EC2 Instance IP

Now, go to PuTTY and load a saved session with the predefined key pair, paste the IP over the placeholder:

AWS EC2 Instance IP

Launch the session and you’re done.

One slight annoyance I have with PuTTY and AWS is the new fingerprint warning ones receives basically every single time, it’s another click I need to do, if anyone knows how to disable that, I’d be interested!

AWS EC2 Instance IP

Happy SSHing.

Included file 'facebook_like.html' not found in _includes directory