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: