This short How-To has been compiled based on the work I’ve done so far while building my personal home server. To achieve reasonable level of privacy without spending a fortune on it, I’ve become my own Certification Authority (CA).
Overview
These are the basic steps covered later in detail:
- Create a CA key and certificate.
- Create a server key and a Certificate signing request (CSR).
- Sign the CSR using the CA key.
- Use the new server certificate in Apache.
- Import the CA certificate into your browsers.
- … Profit!
What this results in is a single certificate file for your CA that you distribute and import into your browsers (PC, phone, …). Every individual signed server / service certificate you create and use is then automatically recognized as valid and trusted. If you are using a personal set of services (various web applications, XMPP server, etc.), this saves you a lot of “exception adding”, just import one (your) CA certificate and everything is working, no need for the browser to nag about self-signed certificates.
Detailed how-to
Creating a CA key pair
First, prepare your “playground”, a data storage somewhere on your (preferably Linux) computer. It should look like this:
root-ca
|-- conf ... for configuration files.
|-- private ... for private CA key (protect this directory!)
|-- public ... for public CA key
|-- requests ... for incoming CSR
+-- certs ... for resulting certificates
Now cd to the root-ca directory. Create a configuration file conf/openssl.conf with the following content:
[ req ]
default_bits = 2048
default_keyfile = ./private/root.pem
default_md = sha1
prompt = no
distinguished_name = root_ca_distinguished_name
x509_extensions = v3_ca
[ root_ca_distinguished_name ]
countryName = UK
stateOrProvinceName = Sussex
localityName = Brighton
0.organizationName = Example Inc
commonName = Example Inc Root CA
emailAddress = david@example.com
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = .
new_certs_dir = ./certs/
database = ./conf/index
certificate = ./public/root.pem
serial = ./conf/serial
private_key = ./private/root.pem
x509_extensions = usr_cert
name_opt = ca_default
cert_opt = ca_default
default_crl_days = 30
default_days = 365
default_md = sha1
preserve = no
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ usr_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
nsCaRevocationUrl = https://www.example.com/example-ca-crl.pem
It might look long and complicated, but most of it is pretty self explanatory. What you should edit is the root_ca_distinguished_name section and the nsCaRevocationUrl.
Then initialize the “certificate counters”, like so:
echo "01" > conf/serial
touch conf/index
Finally, generate a CA key pair (public and private root.pem files):
openssl req -nodes -config conf/openssl.conf -days 1825 -x509 -newkey rsa:2048 -out public/root.pem -outform PEM
Creating a server key pair
On the server for which you want to obtain a signed certificate, do this:
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
Then you can transfer the server.csr file to the CA’s requests directory.
Signing the CSR
Simply call this command and you get a signed certificate server.cert from a request server.csr:
openssl ca -batch -config conf/openssl.conf -in requests/server.csr -out certs/server.cert
Setting up SSL in Apache
Somewhere in the httpd.conf or inside a virtual host configuration add these lines:
Listen 443
SSLEngine on
SSLCertificateFile /path/to/keys/server.cert
SSLCertificateKeyFile /path/to/keys/server.key
SSLCertificateChainFile /path/to/keys/root.pem
These lines activate SSL and the port for SSL, specify server certificate, private certificate key and (optionally) root CA certificate. After restarting the server, HTTPS should be ready to use.
Importing and using
Different applications have different ways of importing trusted CA certificates.
On Windows, you just “execute” the certificate and install it into the appropriate category. This should take care of most of your applications. Web browser (e.g. Firefox) might need to have this certificate installed explicitly, ignoring certificates in the OS.
On Linux, look for /etc/ca-certificates.conf, add the certificate filename there and copy the file to /usr/share/ca-certificates/. Then run update-ca-certificates –fresh to recreate the list of known certificates.
Based on these articles: