Running HashiCorp Vault on WSL2 secured with LetsEncrypt
Tags: hashicorpvault, wsl2, letsencrypt, certbot
Published: 2020-04-12 08:56:12

---
title: Running HashiCorp Vault on WSL2 secured with LetsEncrypt
published: true
date: 2020-04-12 00:00:00 UTC
tags: HashiCorp Vault, WSL2, LetsEncrypt, CertBot
canonical_url: https://robearlam.com/blog/running-hashicorp-vault-on-wsl2-secured-with-letsencrypt
---

I've recently being getting my head around [HashiCorp Vault](https://www.vaultproject.io/). A great product for securing your secrets, certificates, passwords and much more besides. Vault can be enabled in "dev" mode to allow you to test out its features, but I wanted to use this on an actual project so I needed to setup a properly secured instance.

I’ve been loving the developer experience involved with [WSL2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-install) since it’s release, so I wanted to setup my Vault instance in there. I also wanted to have HTTPS enabled, so went to my go to nowadays for certificate generation - [Lets Encrypt](https://letsencrypt.org/).

## Generating the Certificate

First of all, I’m going to generate the certificate that I want to use to secure my vault instance. We’re going to do this using [Certbot](https://certbot.eff.org/), a free tool provided by the [EFF](https://www.eff.org/). This is used to generate certificates for LetsEncrypt and is only available for Linux – another reason I’m loving WSL2 is that all of these tools are now available to us Windows developers! So first up, we run the following commands to install CertBot into my WSL2 instance:

{% gist https://gist.github.com/robearlam/aec15c65aaffbd5ec00a826c5cbe57ad %}

Now if we were running a native instance of Ubuntu, we would be able to go ahead and generate the certificate now, but as we’re running WSL2 we need to do some extra configuration first. As part of the certificate process CertBot needs to able to receive a call back from the server. To do this we need to make sure that traffic on port 80 is being forwarded from my Windows instance into WSL2.

We can do this with a PowerShell script:

{% gist https://gist.github.com/robearlam/4290a98dd2870e4b16dd50fbdc690d7b %}

This will ensure that all traffic on the ports entered will be forwarded the IP assigned to my WSL2 instance. This is a slightly modified version of the fix listed on this [GitHub Issue](https://github.com/microsoft/WSL/issues/4150).

You’ll notice that we’re not just forwarding ports 80 & 443 to handle HTTP & HTTPS traffic, but also 8200. This is the port that Vault operates under and we’ll want Windows applications to be able to communicate with my Vault instance, so we’ll set this up now as well.

One annoying thing with WSL2 currently is that every time the instance starts up it is assigned a new IP address, meaning that we’ll need to run this PowerShell script again each time to forward the traffic on to the new IP. One simple way around this is to scheduled the script to be executed on startup and we can do this with a scheduled task:

{% gist https://gist.github.com/robearlam/b07c9f1ab8bd5d488bb3c7cde92aea5d %}

So now we have everything setup, we can finally generate our certificate!

{% gist https://gist.github.com/robearlam/e9988977f9542ba0a3b0d5efed1b8670 %}

## Setting up Vault
We have our certificate ready, so now we need to install Vault. This is really simple to do with just a few commands in Linux. We’re going to download the archive, extract it, then move Vault to _/usr/local/bin_ so we can access it easily:

{% gist https://gist.github.com/robearlam/43370d5355f704737896c1d35f3ea965 %}

Now we have Vault installed we’re ready to generate our config file to control how this instance of Vault will run. I’m going to be using Azure Storage as the back-end and link to the certificates that we just created:

{% gist https://gist.github.com/robearlam/6983891d2553867c4dfaca28326b190f %}

I’m going to save that config file to _/etc/vault/config.json_. Now we have everything we need; we can start up our new instance of Vault! We can stand up a new instance of a Vault server and initialize it with the following two commands:

{% gist https://gist.github.com/robearlam/27d32be1af5b679863d7221fd722eba8 %}

After completing the _init_ command, you will be presented with Unseal keys & Root token so don't forget to make a note of them. Once you have these you're ready to start storing your secrets, as easy as that!

## Drawbacks

At this point if I was running on a native Ubuntu instance, I would configure Vault as a service using _systemd_ so that it would always run on startup. However, unfortunately _systemd_ isn’t supported on WSL2 at this stage, you can read more about it on this [GitHub Issue](https://github.com/microsoft/WSL/issues/994). So for now I’m left having to manually run Vault when first boot up my machine. Not ideal, but hopefully the issue is fixed soon so that I can automate this last piece!