SSL Certificates Made Easy (and Cheap!)

Running an SSL-enabled website is a best practice but often made difficult by the fact that one needs a Private Key Infrastructure (PKI) to obtain the SSL certificates needed for SSL operation.

There are two options for using a PKI: 1. Deploy your own PKI, and 2. Use a public PKI. The former is cheap (free) but has a steeper learning curve because one needs to know how to set up the Certification Authority (CA) server software and how to manage the PKI (generate Certificate Signing Requests [CSRs], sign certificates, revoke certificates, deploy the root CA certificate to endusers’ devices, etc.). The latter can be non-free but is easier as the PKI is already established and one only needs to request a certificate, sometimes for a price.

The Let’s Encrypt project is “[…] a free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG).” See for additional details about the Let’s Encrypt project. Two important details about certificates issued by the Let’s Encrypt project is that: 1. They are free, and 2. Browsers trust the CA that issues them, so there is no need to distribute CA root certificates to endusers’ devices.

We run an Apache web server that serves a few domains via virtual hosts and it was easy to set them up to use certificates issued by the Let’s Encrypt project. Here are the details:

We run Apache on Ubuntu so the first thing we had to do was to install an ACME client (ACME is a protocol used to fetch certificates). The ACME client recommended by the Let’s Encrypt project is called Certbot. According to the Certbot’s website, “Certbot is an easy-to-use automatic client that fetches and deploys SSL/TLS certificates for your webserver. Certbot was developed by EFF and others as a client for Let’s Encrypt and was previously known as “the official Let’s Encrypt client” or “the Let’s Encrypt Python client.” Certbot will also work with any other CAs that support the ACME protocol”.

The Certbot website has clear instructions on how to do this. For us, it was just:

shell$ sudo add-apt-repository ppa:certbot/certbot
shell$ sudo apt-get update
shell$ sudo apt-get install certbot

The next step was to request the certificates. There are Certbot “plugins” that automate the process but we chose a very manual process that gives us a little bit more control over the entire process:

shell$ sudo certbot certonly --webroot -w /srv/www/ -d -d -w /usr/share/wordpress -d -d
 Saving debug log to /var/log/letsencrypt/letsencrypt.log
 Starting new HTTPS connection (1):

 You have an existing certificate that contains a portion of the domains you
 requested (ref: /etc/letsencrypt/renewal/

It contains these names:,

You requested these names for the new certificate:,,,

Do you want to expand and replace this existing certificate with the new
 (E)xpand/(C)ancel: e
 Renewing an existing certificate
 Performing the following challenges:
 http-01 challenge for
 http-01 challenge for
 http-01 challenge for
 http-01 challenge for
 Using the webroot path /usr/share/wordpress for all unmatched domains.
 Waiting for verification...
 Cleaning up challenges
 Unable to clean up challenge directory /srv/www/
 Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
 Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem

 - Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/ Your cert will
 expire on 2017-06-26. To obtain a new or tweaked version of this
 certificate in the future, simply run certbot again. To
 non-interactively renew *all* of your certificates, run "certbot
 - If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:
 Donating to EFF:

Note that I had previously requested a certificate for, and when I ran Certbot I requested a new domain to be listed in the certificate ( Certbot noticed that I had previously requested a certificate for and asked me if I wanted to expand the certificate to include the new domain.

As mentioned in the output from the certbot, the certificates (identity certificate for the website as well as the CA certificate) are left in the /etc/letsencrypt/live/ directory. At this point one just has to configure Apache to use these certificates.

Printing From Windows 7 to Remote CUPS Printer

It took me a little while to figure out how to get a machine running Windows 7 to print to a remote CUPS printer so I thought I’d document what I did in case it helps others (as well as myself as I am sure I will forget this if I don’t document it)…

The first step is to go to the “Devices and Printers” control panel. There one has to click on the “Add Printer” link at the top (also available in the right-click menu).

In the dialog window that follows, select “Add a network, wireless, or Bluetooth printer”. Windows will then try to automatically find an available network printer. At that point I stop the search by clicking on the “Stop” button, and the click on “The printer that I want isn’t listed”.

In the next dialog, “Find a printer by name or TCP/IP address”, select the option “Select a shared printer by name”, and enter an URL like the following:

http://<IP address or hostname of the CUPS server>:631/printers/<Name of the CUPS printer queue>

Then click “Next”.

The next step is important — it’s where a printer driver must be selected. Normally, the CUPS server knows what printer it has connected. In that case on needs to send print jobs in a format that the CUPS server can understand, like Postscript or PDF — the CUPS server will convert to the appropriate language understood by the printer. However, it might be the case that the CUPS server has a raw queue, in which case the CUPS client must sent the print job in the format that the printer can understand.

So, when selecting a driver in the Windows “Add Printer Wizard”, one can do the folowing:

  1. If not using a raw queue on the CUPS server, select the “Generic” manufacturer, and then the “MS Publisher Color Printer”. This will cause the print job to be of type “application/postscript”, which CUPS can then convert to the right printer language.
  2. If using a raw queue on the CUPS server then select the appropriate printer driver so the Windows client sends the job in the format that the printer can understand.


“[…] install the native printer drivers for your printer on the Windows computer. If the CUPS server is set up to use its own printer drivers, then you can just select a generic postscript printer for the Windows client(e.g. ‘HP Color LaserJet 8500 PS’ or ‘Xerox DocuTech 135 PS2’).”

Note that I didn’t have luck using the “HP Color LaserJet 8500 PS” printer driver — it would generate a printer job in the “PJL encapsulated PostScript document text” format, which CUPS would have problems handling. But the “MS Publisher Color Printer” worked fine.

  • This page contains good information on how to create a CUPS raw printer queue: