Download! Download back issues COMPLETELY FREE!

Masterclass: Secure your website with SSL encryption

Essential Linux tools explained – this month, SSL, the tech that enables secure connections over the web.

SSL is the Secure Sockets Layer. It’s the technology that secures the web, and just about everyone who has used a web browser will have heard of it and (especially after the recent Heartbleed incident) its widely-used open source implementation: OpenSSL.

SSL provides a secure communications channel over an insecure network. Its best-known use is to secure the connection between a web server and browser but it also has other uses, such as securing the transmission of email.

OpenSSL is both a toolkit and library that implements SSL. The library is also used by other tools that use cryptography such as SSH. Most distros will install OpenSSL by default or as a dependency of another application like your web browser. Check that you have it:

$ openssl version
OpenSSL 1.0.1h 5 Jun 2014

You should expect to see at least version 1.0.1g, because this is the one that fixed the Heartbleed bug. If you need to install or update, you should find it in your distro’s repository.

SSL is a cryptographic protocol that enables two parties such as a web server and a browser to exchange information securely by encrypting it before sending and decrypting it upon receipt.

Encrypting and decrypting requires a secret, like a password, which is known as a key. A symmetric key can both encrypt and decrypt, whereas an asymmetric key can only do one or the other and therefore requires a key-pair; one for encryption, which can be given to anyone (a public key), and another for decryption that must be kept secret (a private key).

Asymmetric ciphers are more complex than symmetric ones, and therefore have a higher computational overhead. This makes a symmetric cipher preferable for data transmission, but presents the challenge of sharing a symmetric key between two parties previously unknown to each other.

SSL solves this key exchange problem by using an asymmetric cypher to encrypt the symmetric key. Here’s what happens when you access a website secured with SSL.

  • The client (web browser) connects to the server (website) using a URL that begins with https:
  • The Server sends its SSL Certificate to the client.
  • The client validates the certificate.
  • The client generates a random symmetric key and encrypts it using the public key contained in the certificate.
  • The client sends the encrypted symmetric key to the server.
  • The server uses its private key to decrypt the symmetric key.
  • The server and client encrypt all further communication sent in either direction using the symmetric key.
  • At the end of the session, the symmetric key is discarded.
  • The process is repeated for further sessions.

Image

The beginnings of a typical SSL conversation.

An SSL certificate is like an envelope with the public key inside. It is signed so that the recipient can be confident that the contents have not been altered and can be trusted. This is done by a certificate authority (CA) using its own certificate that is also signed, either by another CA or self-signed.

A CA’s certificate that is self-signed is a root certificate and those that are pre-installed in web browsers are trusted implicitly. Web browsers include the root certificates for the major certificate authorities that provide the certificates used by most websites.

A certificate is trusted if its signings can be traced back to a trusted root certificate. This Public Key Infrastructure underpins SSL and is defined by a standard called X.509.

Get the key

OpenSSL supports the X.509 standard, and you can use it to prepare a certificate signing request that you need to send to a CA to get a new certificate. If you have a certificate, you can use it to sign other certificates. You can even create your own self-signed certificate and be your own certificate authority. But, before you begin, you need your own private key:

$ openssl genpkey -algorithm rsa -out private.key
$ chmod 400 private.key

You can choose the key generation algorithm, but the usual choice for SSL is “RSA”, because it can generate larger keys (up to 4,096) bits. Remember to change the access permissions of the key file to keep it secret. You can then extract the corresponding public key:

$ openssl pkey -in private.key -pubout -out public.pem

pem means Privacy Enhanced Mail, and is a file format that uses base64 encoding. You can specify other formats, such as der, which is a binary equivalent of pem.

You can further secure a private key by encrypting it with a triple-DES symmetric key. Add -des3 when generating the private key or encrypt an existing private key with

$ openssl pkey -in private.key -des3 -out private-enc.key

You will need to enter the passphrase for an encrypted key whenever it is used, making them less useful on servers. A passphrase can be removed:

$ openssl pkey -in private-env.key -out private.key

You can use PEM format keys with X.509, and you can use OpenSSL to create the certificate signing request (CSR):

$ openssl req -new -key private.key -out request.csr

This will request some data from you, but the most important field is the Common Name. This must match the domain that the certificate is for. The remaining fields can be completed as desired, or as mandated by the CA. Enter a period . for a blank field. Once you have the certificate signing request, you’ll need to submit it to a certificate authority using their own procedures.

Image

Firefox and the other major web browsers enable you to look inside a server’s certificate.

Be your own certificate authority

For testing or internal use, a self-signed certificate may be all you need, and creating one is similar:

$ openssl req -new -key private.key -x509 -out mycert.crt

The -x509 option is what causes a certificate to be written instead of a CSR. The information required for a CSR applies here too, and you will be prompted to enter it. You can add further parameters such as -days, which changes the certificate’s validity from the 30 day default.

Self-signed certificates are useful for development and testing and other internal purposes but have otherwise limited use because they lack trust. To get a trusted certificate, you will need to send a certificate signing request to a trusted certificate authority.

You can use your own certificate (whether signed by a trusted CA or self-signed) to sign new certificates.

$ openssl x509 -req -in request.csr -CA mycert.crt -CAkey private.key -out cert.crt

You’ll need to add -CAcreateserial the first time you do this so that OpenSSL creates a serial number file (it’s then used automatically for subsequent certificates). Alternatively, you can use -set_serial to supply a specific serial number.

We’ve explained how SSL works and how you can use OpenSSL to create certificates. Next, we’ll use a real certificate authority to get a certificate and use it to set up a secure SSL website. SSL gives visitors to a website confidence that it is genuine and that the information supplied to it is safe. If you run a website, you can increase your users’ confidence by supporting SSL and you can do this without costing the earth. In fact, you can do it for free.

StartSSL is a certificate authority with trusted root certificates in most major web browsers that offers free one-year domain-verified SSL certificates.

All you need is a domain that you can receive administrative email for – they send a verification email to either the ‘postmaster’, ‘hostmaster’ or ‘webmaster’ address for the domain. There are no additional checks (such as verifying domain ownership) made for these free certificates, but you can pay a fee for extended validation.

We’ll use StartSSL to create a basic, fee-free domain-validated certificate. These are good for one domain (eg example.com) and one subdomain (eg shop.example.com) which means that one certificate could theoretically be used for two sites. However, given that you can create as many certificates as you wish, there isn’t really any limitation on what you can do (you can also get wild-card multiple domain certificates, but they are not free).

The first thing to do is to sign up for an account at www.startssl.com. You have to enter your personal details including address and phone number, and these may be used depending on the level of validation that you require.

You will be sent a verification email containing a code that you need to enter into the website. It then sends a second email containing a link and another verification code. Clicking that link and entering the code takes you to a Generate Private Key page.

The private key is for a new client certificate that will be installed in your browser and will be used to authenticate you with StartSSL instead of a username and password (using an SSL certificate to authenticate onesself is a little-used capability of web browsers that few people are aware of).

Leave the drop-down with ‘High Grade’ selected and click on Continue to generate the key. Next, press Install to install it into in your browser, which should respond with a pop-up confirming the certificate installation. The web page then displays links explaining how to back up the key that was just installed. Do that, then click the Finish button.

With your client certificate installed, you can click on the Control Panel button. The Authenticate button there uses your client certificate to authenticate you, and is how you log in to the StartSSL website on return visits.

Once authenticated, you can use the control panel’s tool box, certificates wizard or validations wizard.

Protocol variations

There are several versions of the SSL protocol, the latest being 3.0, after which it was renamed Transport Layer Security (TLS) and has since seen several revisions. The current TLS version is 1.2. The terms SSL and TLS are often used interchangeably despite their differences (for example, TLS 1.0 is also known as SSL 3.1) and SSL has now become a generic term for describing secure websites.

When a connection is established between a client and server, the protocol negotiates and uses the latest version that they both support.

TLS added the ability for a client to connect to a server’s standard port and then negotiate a secure connection. Prior to this, SSL required a dedicated secure port. To be used this way, TLS uses a protocol-specific method to negotiate the switch, and not all protocols include one. StartTLS is the protocol-specific method supported by email protocols. There is an HTTP Upgrade header that allows an HTTP connection to negotiate TLS as specified by RFC2817 but

it isn’t widely implemented. HTTP continues to use separate ports: 80 for unsecured HTTP and 443 for HTTP over SSL/TLS.

Domain Validation

Before you can create a certificate, you must perform the domain validation, and you can validate as many domains as you want using the Validations wizard.

You enter a domain and it sends an email to an administrative address for the domain (your choice of either ‘postmaster’, ‘hostmaster’ or ‘webmaster’) containing a validation code that needs to be entered on the website to complete the validation.

The validation lasts for 30 days, but you can re-validate whenever you need to.

You use the Certificates wizard to create certificates for validated domains. You can supply a Certificate Signing Request (CSR) or have StartSSL generate one, including a private key for you. While this convenience might sound nice, and StartSSL states that no copies of generated private keys are kept at any stage, it’s a really bad idea for anyone but you to have access to your private key. For this reason we recommend that you use a CSR! It’s easy to create a CSR using OpenSSL on your own machine:

$ openssl req -new -key private.key -out request.csr

The -key option specifies the private key to use. If it’s omitted, a new private key will be generated and you will be prompted to supply the required information.

StartSSL only uses the public key embedded in the CSR and ignores any applicant data so, when creating the CSR, you can just accept the defaults or enter meaningful detail; it doesn’t matter.

In the StartSSL Certificates wizard, choose ‘Web Server SSL/TLS Certificate’ and, to use a CSR, press the skip button to bypass the private key generation.

Gather the text of the CSR (eg ‘cat request.csr’) and paste it into the box in the Wizard. The response indicates success and reminds you that all content of the certificate signing request is ignored except its public key. Press ‘Continue’.

You are then presented with your validated domains; select the relevant one. You are then presented with a box to enter one subdomain (you’ll need to pay if you need a certificate for multiple domains or sub-domains). Enter a subdomain (like ‘www’) and press Continue.

After a final confirmation of the domain and sub-domain, press Continue once more. The certificate is displayed on the screen. Copy and paste it into a local file. It’s customary to use a .crt file extension, like server.crt. Once the certificate has been obtained, the CSR can be discarded. You now need to install the certificate and associated private key on your web server.

Is that really you?

As well as transporting the public key, the certificate also permits identity validation, which enables a web browser to confirm that the web server that it is communicating with is the one that it thinks it should be communicating with.

This works because a signed certificate cannot be modified, and the certificate authority (CA) is trusted to perform identity validation before issuing a certificate.

It is, however, up to the CA to decide how it verifies an entity’s identity, and this can vary from basic domain validation using whois data to extended validation that mandates specific checks that require submission of physical documents like passports or company accounts. EV certificates can only be issued by CAs who pass an independent audit as required by the CA/Browser Forum (see www.cabforum.org), making them expensive and difficult to obtain. Domain validated certification may suffice for some applications – low-cost and fee-free certificates are offered by cacert.org, startssl.com and comodo.com.

There is no technical difference between a normal and an EV certificate – both offer the same level of encryption. The EV certificate carries a Certificate Policy Object Identifier and browsers are hard-coded to recognise them (the latest browsers add a green highlight to the address bar).

Webserver configuration

Assuming that you have an Apache webserver already installed and working without SSL, we’ll now configure a new SSL virtual host, and afterwards another one for the subdomain.

Now we need the private key and the new site certificate file from StartSSL. The exact location for the Apache configuration depends on your Linux distribution. On Arch Linux it’s at /etc/httpd/conf. Copy the private.key and server.crt, for example:

$ scp private.key server.crt [email protected]:/etc/httpd/conf

Then edit the default Apache SSL configuration, which may be found in the extra subdirectory and called httpd-ssl.conf. Make the following changes, all within the <VirtualHost _default_:443> block:

  • Set DocumentRoot to the directory where this virtual host’s files will reside (eg /srv/https)
  • Set ServerName to the domain covered by the server certificate and the https port (443) (eg mydomain.com:443).
  • Set SSLCertificateFile to the path of the server certificate (eg /etc/httpd/conf/server.crt)
  • Set SSLCertificateKeyFile to the path of the private key (eg /etc/httpd/conf/private.key).

If your certificate has intermediate certificate authoritity certificates, concatenate them into a single file and set SSLCertificateChainFile to its path (you don’t need to do this for StartSSL but may need to if you get your certificate elsewhere). If you have set DocumentRoot to a new directory path, a <Directory> entry may be required to make it accessible:

<Directory “/srv/https”>
Order allow,deny
Allow from all
</Directory>

Now, edit the main Apache configuration file, httpd.conf, to uncomment the line that includes the SSL configuration:

# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf

And, finally, restart Apache, in the appropriate manner for your system. Systemd users can use

$ systemctl restart httpd

Assuming there is content at the document root, pointing a browser to the new site should work with no security warnings and the browser should display its padlock icon to show that the connection is secure.

Apache’s Name-based virtual hosts support enables you to configure further SSL virtual hosts in a similar way. Find the Listen 443 stanza in httpd.conf and add another to enable it on port 443:

NameVirtualHost *:443

This relies on Server Name Indication (SNI) to resolve hosts by name, as described in the boxout, left. With name-based virtual hosts configured, you can add further blocks for additional virtual hosts:

<VirtualHost *:443>
DocumentRoot “/srv/https/subdomain.mydomain.com”
ServerName servername.mydomain.com:443
SSLCertificateFile /etc/httpd/conf/private.key
SSLCertificateKeyFile /etc/httpd/conf/server.crt
</VirtualHost>

A server re-start is required for the configuration changes to take effect. Restart the server and point your browser to the virtual host’s URL.

SSL, virtual hosts and SNI

Historically, it wasn’t possible to host multiple SSL hosts on a single IP address and port because the web server needs to know the host name to choose the correct certificate, but this information is wrapped up in the encrypted content and, therefore, can’t be accessed until the encryption is established. This has been solved by Server Name Indication (SNI), an extension to the https protocol that presents the host name during the pre-encryption handshake.

Support isn’t universal, however, and it’s likely that a browser that doesn’t support it will be offered the incorrect certificate, because the SNI is missing. If a web server receives a request without SNI, it will fall back to a default certificate. Apache uses the first virtual SSL host’s certificate when this happens. This may result in an unexpected certificate being returned to the browser, which may trigger a security warning. You can change this behaviour by enabling SSLStrictSNIVHostCheck so it returns a 403 error page instead.

This won’t be an issue if all the virtual hosts share the same certificate (perhaps they are subdomains or you have a certificate that covers multiple domains).