Bring-your-own SSL Certs with VNS3

by | 12 Sep 2017

One of the (few) issues some customers have with VNS3 is the use of self-signed certificates. There are arguments to be made that self-signed certs can be as secure than those provided by third-party trusted signing certificate authorities (CAs), when implemented properly. But these arguments are often more hassle than many IT departments want, especially as most browsers have increased their scary warnings, and when an end user sees those the last thing they want is a debate on the relative security of CAs versus their own local infrastructure.

As of version 4.0 of VNS3 it is possible to upload your own SSL certs. These can be self-signed certs or those provided by a CA.

In this post we’re going to show how to create and upload a signed certificate to VNS3 by using EFF’s Certbot and certificates generated by Let’s Encrypt. Certbot is a part of EFF’s efforts to encrypt the entire Internet. It acts as a client to the Let’s Encrypt open CA, which is a service provided by the Internet Security Research Group (ISRG).

Our approach will be to create the certificates separate from the instance, then upload them using VNS3’s UI.

Creating and Installing Your Let’s Encrypt Certificates

The rest of this tutorial assumes the following:

  • You have ownership of a specific domain,
  • You are naming your VNS3 instance
  • You have access to the DNS records for

Given the above requirements, you can run the Certbot process on a separate server and have the certs generated, ready to be uploaded to VNS3.

The approach is:

  • Add as an A or CNAME record to your DNS records for
  • If it’s not already installed, install Certbot on your separate server ( ). It’s even possible to use Docker ( ).
  • Run the Certbot client (if this is the first time you’ve run the client you will be asked for an email address for renewal/security notices and you will be asked to agree to the Terms of Service.) :

Running Certbot looks similar to the following:

$ sudo certbot certonly –manual –preferred-challenges dns

Please enter in your domain name(s) (comma and/or space separated) (Enter ‘c’ to cancel):

Yuo’ll step through the certbot prompts to create your certificates. At this point you will have to wait for your DNS records to push the TXT record out. This should be fairly quick. To see if your TXT record has appeared you can use the “dig” command (in a separate tab/window), which should return the contents of the TXT record. For example:

$ dig txt

For VNS3 we need the following files:



To update via the UI, connect to your instance and navigate to the “HTTPS Certs” option in the Admin section of the menu.

The file, cert.pem , is your SSL certificate, and privkey.pem is your SSL key file. Upon clicking the “Upload and Install” button you will receive the message, “HTTPS certs validated and installed”. (If you receive “Error validating key/cert files” it’s possible the order of the files was reversed, with the private key as the cert and vice versa). Once installed the system will restart the web server and your new certificates should be protecting your VNS3 instance.

Automating Certificate Renewal

An SSL certificate from Let’s Encrypt CA expires in 3 months. This is actually a very good thing as it means that in the event of another Heartbleed-type bug, the maximum amount of time that the weakened certs will remain active is 90 days. The problem is that it means that someone will need to rerun Certbot and update the certs on the VNS3 instances every 90 days. A better way is to automate the process.

A detailed analysis of the certificate renewal process is beyond this post. Instead we’ll just touch on some details. Certbot supports a way of running non-interactively but a plugin is required when combining with manual use. It is also possible to run semi-interactively, like so:

$ sudo bash -c “yes | certbot certonly –manual –cert-name ”

To automate the uploading of the new certs to the VNS3 instance requires use of the API. Here is an example of some basic, hastily written Ruby code that can be used to upload and install the certs:

require ‘rest_client’
require ‘json’

@user = ‘api’
@password = ‘vnscubed’

base_path = ‘ ’
cert =‘cert.pem’)
key =‘cert.key’)
def put(url, payload = {})
rc =, user: @user, password: @password, verify_ssl: OpenSSL::SSL::VERIFY_NONE)
JSON.parse(rc.put(payload.to_json, content_type: ‘application/json’))
def get(url)
rc =, user: @user, password: @password, verify_ssl: OpenSSL::SSL::VERIFY_NONE)
JSON.parse(rc.get(content_type: ‘application/json’))
response = put(“#{base_path}/keypair”, { cert: cert, key: key })
response = put(“#{base_path}/install”)
uuid = response[‘response’][‘uuid’]response = get(“#{base_path}/install/#{uuid}”)
while response[‘response’][‘state’] == ‘pending’
puts “Job #{uuid} : status #{response[‘response’][‘status’]}”
sleep 3
response = get(“#{base_path}/install/#{uuid}”)
puts “Job #{uuid} : status #{response[‘response’][‘status’]}”
rescue => e
puts “Error: #{e.message}”

The above Ruby code should not be used in production. It doesn’t test well for errors, it has global variables, it loops in an unchecked way and it’s not verifying the existing SSL certs. But on the positive side, it does demonstrate how easy it can be to upload newly generated certs to a VNS3 instance.

Taking the two separate steps and wrapping them in a script is trivial and having either a Jenkins task or a cron job run the process every month or two should be easy to ensure that the certificates on your VNS3 instances are up-to-date.


In this post we’ve shown you how to create and upload an SSL certificate for your VNS3 instance using Let’s Encrypt and Certbot. We’ve also given a quick overview on how to begin to automate the certificate update process. Hopefully another item on the ever-lengthening IT security to-do list can now be checked off.