Getting Pritunl working with Let’s Encrypt CA

Recently I was working on a fresh install of Pritunl’s VPN server on a VM. Pritunl’s software is free for simple configurations and is a really easy way to setup a VPN server in a few minutes – it’s also compliant with OpenVPN standards so you can use either the ubiquitous OpenVPN client or Pritunl’s own branded client. The Pritunl client has some advantages like easy one-step configuration with a similarly configured Pritunl server (vs importing a settings files) but otherwise they are largely functionally the same.

One of the new features that was recently (within the last year?) added to Pritunl was the ability to use Let’s Encrypt certificates in the server. Previously, you had to either get a third-party plugin or run Pritunl behind a reverse proxy to get Let’s Encrypt or any other certificate working (without upgrading to a more expensive paid license).

However, the Let’s Encrypt function wasn’t working. Normally, you would set the domain name for the certificate in the settings dialog box, then hit “Save” and the backend would run and verify the domain, fetch the certificate, and apply it all automatically.

Now, I’m just getting “Error getting LetsEncrypt certificate check the logs for more information.”

Okay, lets take a look at the logs:

[patient-plateau-8521][2017-11-16 16:08:58,851][INFO] Parsing acme account key...
[patient-plateau-8521][2017-11-16 16:08:58,981][INFO] Parsing acme CSR...
[patient-plateau-8521][2017-11-16 16:08:59,075][INFO] Registering acme account...
[patient-plateau-8521][2017-11-16 16:08:59,850][ERROR] Failed to get LetsEncrypt cert
Traceback (most recent call last):
File "/usr/lib/pritunl/local/lib/python2.7/site-packages/pritunl/handlers/", line 711, in settings_put
File "/usr/lib/pritunl/local/lib/python2.7/site-packages/pritunl/", line 49, in update_acme_cert
cert = get_acme_cert(, csr)
File "/usr/lib/pritunl/local/lib/python2.7/site-packages/pritunl/", line 24, in get_acme_cert
File "/usr/lib/pritunl/local/lib/python2.7/site-packages/pritunl/", line 111, in get_crt
raise ValueError("Error registering: {0} {1}".format(code, result))
ValueError: Error registering: 400 {
"type": "urn:acme:error:malformed",
"detail": "Provided agreement URL [] does not match current agreement URL []",
"status": 400
acme_domain = u''

Oh…great. Um, it looks like there’s a problem with the agreement URL which are basically the Terms of Service for using Let’s Encrypt. The solution was actually very easy.

SSH into the sever and edit the main configuration file:


In my config, it was on line 124. Edit the line to the newest agreement and save and close.

 'acme_agreement_url': '',

Re-compile the Python binary and restart the Pritunl server, then try setting your domain name again.

sudo python -m compileall .
sudo service pritunl restart

This time it worked like a charm for me. Done!




Continue Reading

Fix Common SSL/TLS Problems in Apache2

Qualys SSL Labs has some great tools to check your server’s SSL/TLS installation to make sure they don’t fall victim to common vulnerabilities or exploits that seem to be discovered every month. If you’re running an Apache2 installation, securing your server against most SSL/TLS vulnerabilities is as easy as enabling the headers Apache module, and then a few lines to your SSL configuration.

First, enable the headers module so Apache2 can modify headers sent to the client:

pengc99@alpha:~$ sudo a2enmod headers
Enabling module headers.
To activate the new configuration, you need to run:
 service apache2 restart

Then add the following lines to your SSL configuration:

# Make the server secure
 SSLProtocol all -SSLv2 -SSLv3
 SSLHonorCipherOrder on

Restart your server:

pengc99@alpha:~$ sudo /etc/init.d/apache2 restart
Restarting web server: apache2 ... waiting .

That’s it! Now go run the test at and marvel at your server’s newfound security!


Continue Reading