Create a self-signed SSL certificate
Content |
Tested on |
Debian (Lenny, Squeeze) |
Ubuntu (Lucid, Precise, Trusty) |
Objective
To create a self-signed SSL certificate
Background
In order to establish an SSL connection it is usually necessary for the server (and perhaps also the client) to authenticate itself to the other party. This is normally done using an X.509 certificate, which links the owner’s identity to a public key that can be used with a digital signature algorithm such as RSA or DSA. In order to use the public key it is necessary to know the corresponding private key, which can either be stored separately or in the same file as the certificate.
Certificates can be signed by a certificate authority or they can be self-signed. Reputable certificate authorities usually charge a fee, so for some purposes you may prefer to use a self-signed certificate instead. See below for a discussion of the security implications.
There are a number of different file formats that can be used to hold SSL certificates and keys. The method described below will create a PEM-encoded X.509 certificate and a PEM-encoded OpenSSL key, both of which are suitable for use with Apache.
Scenario
Suppose that you wish to serve a web site using SSL from the domain www.example.com
. You have chosen to use a self-signed certificate, which should be written to the file /etc/ssl/certs/example.pem
. The private key should be written to the file /etc/ssl/private/example.key
.
Method
The certificate can be created using OpenSSL, which is provided by the openssl
package on both Debian:
apt-get install openssl
and Red Hat-based systems:
yum install openssl
A suitable command to create the certificate and key file would be:
openssl req -new -x509 -nodes -out /etc/ssl/certs/example.pem -keyout /etc/ssl/private/example.key -days 3650 -subj '/CN=www.example.com'
By default the req
subcommand takes a PKCS#10 certificate signing request as its input and produces one as its output. That is not the required behaviour in this instance, so its input and output methods have been overridden by the -new
and -x509
options respectively. -new
indicates that req
should construct an entirely new certificate request instead of processing an existing one. -x509
indicates that it should output an X.509 certificate as opposed to a certificate request.
The -nodes
option indicates that the private key should not be encrypted using a passphrase. This results in some loss of security but if often necessary for practical reasons. See below for a discussion of the implications.
The -out
and -keyout
options specify the names of the respective files to which the certificate and private key should be written.
The -days
option specifies the number of days before the certificate should expire. The default is 30 days, but it often makes sense to use a much longer period for self-signed certificates because much of the risk lies in the distribution process.
The -subj
option lists the fields to be included in the certificate. In this case only one field has been specified, of type CN
and with a value of www.example.com
. CN
is short for ‘Common Name’, and in this context it specifies the domain name to which the certificate refers. There are many other types of field that can be added, but you must include either a CN
or a subjectAltName
if you want to use the certificate for SSL. For self-signed certificates this minimal level of identification is usually adequate.
Testing
You can view the content of a certificate using the command:
openssl x509 -in /etc/ssl/certs/example.pem -text
The most important fields in the output are the subject, in which the CN
or subjectAltName
should specify the domain name to which the certificate refers:
Subject: CN=www.example.com
and the issuer, which should match the subject for a self-signed certificate:
Issuer: CN=www.example.com
and the period of validity, outside of which the certificate can be expected to not work:
Validity Not Before: Feb 25 19:10:41 2012 GMT Not After : Mar 26 19:10:41 2012 GMT
Next steps
You can configure Apache to make use of the certificate created above using the SSLEngine
,
SSLCertificateFile
and SSLCertificateKeyFile
directives:
SSLEngine on SSLCertificateFile /etc/ssl/certs/example.pem SSLCertificateKeyFile /etc/ssl/private/example.key
Alternatives
Using the ssl-cert package on Debian-based systems
If you are using a Debian-based system then a quick and easy way to generate a self-signed certificate is to install the ssl-cert
package:
apt-get install ssl-cert
By default the certificate is placed in the file /etc/ssl/certs/ssl-cert-snakeoil.pem
and the key in the file
/etc/ssl/private/ssl-cert-snakeoil.key
. It can be used by Apache using the directives:
SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
The common name of the certificate will be equal to the fully-qualified domain name of the host on which it was created.
Security considerations
Self-signing
It is sometimes claimed that self-signed certificates are of no security value whatsoever, however this is based on two questionable assumptions:
- that an attacker with the ability to eavesdrop on your network traffic will also have the ongoing ability to modify it at will;
- that countermeasures against the use of fraudulent certificates either cannot or will not be taken.
In practice there are circumstances where the use of a self-signed certificate is appropriate and circumstances where it is not. Self-signing is more likely to be defensible if:
- you have administrative control over the client(s) and can use this to securely install the certificate;
- you are using a domain name that has not been delegated to you from the IANA root zone;
- you wish to remain anonymous;
- you have no funding; and/or
- the users of the system have the ability to judge whether a given certificate should be trusted.
If you find yourself using multiple self-signed certificates on a network then it may be preferable (both on security grounds and for convenience) to set up a local certificate authority instead. Although this would have a self-signed root, it is better to have one root than many.
Passphrases
The private key can be encrypted using a passphrase. This is a useful protection, except that it is often impracticable to present the passphrase when it is needed.
To use a passphrase-protected certificate on a server the usual mode of operation is to prompt for the passphrase when the server process starts, then keep a copy of the key in memory while the process is running. There are at least three issues with this approach:
- The server process cannot be restarted unless there is someone in attendance who is able to enter the passphrase.
- Restarting the server process will take longer than would otherwise be the case due to the time taken entering the passphrase.
- Even if the key exists only in memory, that does not make it completely inaccessible to an attacker.
For these reasons it is not unusual for SSL certificates to be used without a passphrase, as in the example above. If you are concerned about the risk of loss then you may find that the following measures provide a better balance between security and availability:
- Use a separate machine to perform the SSL encapsulation. This can then be hardened to a significantly greater extent than would be possible if it were also serving the content.
- Make the validity period of the certificate as short as possible. You should not normally do this when using self-signed certificates, because you would increase the risk during distribution, but a short validity period is feasible if you are running a local certificate authority.