---
myst:
html_meta:
"description lang=en": "Configure VPN sidecar containers for Kasm Workspaces, a single network container to route traffic from many Workspaces through a VPN tunnel. "
"keywords": "Kasm, How to, How-to, VPN, Container, OpenVPN, TailScale, NordVPN"
"property=og:locale": "en_US"
---
```{title} VPN Sidecar Containers
```
# VPN Sidecar Containers
## Intro
For security reasons or to gain access to a remote network it might be required to give specific Kasm Workspaces access to a VPN. One way to do that would be to customize an existing Kasm core image with VPN tools, but then it requires many network level permissions and becomes a configuration nightmare.
The Kasm team's recommended configuration would be to use an off the shelf or custom VPN docker container running alongside Kasm Workspaces while leveraging the existing desktop and application containers.
Their traffic can then be forced through the external VPN container using a custom Docker exec config. This document will be covering three different ways to achieve this.
Deployment time ~10 minutes.
* [Option 1 Create a standalone openvpn setup](#option-1-create-a-standalone-openvpn-setup)
+ [The OpenVPN server](#the-openvpn-server)
+ [The OpenVPN sidecar container](#the-openvpn-sidecar-container)
+ [Finding the public IP OpenVPN](#finding-the-public-ip-openvpn)
* [Option 2 using a popular VPN Vendor container](#option-2-using-a-popular-vpn-vendor-container)
+ [Setting up a VPN container (NordVPN)](#setting-up-a-vpn-container)
+ [Nord VPN Testing](#nord-vpn-testing)
* [Option 3 Tailscale](#option-3-tailscale)
+ [Getting the Tailscale auth key](#getting-the-tailscale-auth-key)
+ [Setting up a Tailscale Docker container](#setting-up-a-tailscale-docker-container)
+ [Tailscale testing](#tailscale-testing)
## Option 1 Create a standalone openvpn setup
This configuration is going to be using an off the shelf OpenVPN container for the server as the assumption is most users will already have an OpenVPN endpoint available. Then the example will show building a custom client container to act as the sidecar.
### The OpenVPN server
Here [kylemanna/openvpn](https://hub.docker.com/r/kylemanna/openvpn/) is being used to be able to quickly spin up an endpoint on a remote server. Use the following commands to deploy and dump a usable client config file:
```
sudo docker volume create --name Kasm_vpn
sudo docker run -v Kasm_vpn:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://IP_OR_HOSTNAME
sudo docker run -v Kasm_vpn:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
sudo docker run -v Kasm_vpn:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
sudo docker run -v Kasm_vpn:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full Kasm nopass
sudo docker run -v Kasm_vpn:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient Kasm > Kasm.ovpn
```
Please substitute the `IP_OR_HOSTNAME` for the actual server IP or hostname for the server. After filling out the prompted information for password protecting the certificates the `Kasm.ovpn` configuration file needed to connect the VPN sidecar client will be written to disk.
### The OpenVPN sidecar container
Build a custom docker container to act as the VPN sidecar container on the Kasm Workspaces host.
```
mkdir openvpn-client
cd openvpn-client
mkdir root
```
Here is the `Dockerfile`:
```
FROM debian:latest
RUN apt update && \
apt install -y \
iptables \
openvpn && \
apt clean
# add local files
COPY /root /
VOLUME [ "/vpn/config" ]
ENTRYPOINT [ "/entrypoint.sh" ]
```
And custom `root/entrypoint.sh`:
```
#! /bin/sh
# create tun device
if [ ! -c /dev/net/tun ]; then
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
fi
# Enable devices MASQUERADE mode
iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE
# start vpn client
openvpn --config /vpn/config/${VPN_CONFIG}
```
Make sure the entrypoint is executable:
```
chmod +x root/entrypoint.sh
```
The directory structure should look like this:
```
openvpn-client/
├─ root/
│ ├─ entrypoint.sh
├─ Dockerfile
```
Now build the container:
```
sudo docker build -t openvpn-client .
```
On the Docker host running Kasm Workspaces (or Agent Server if using a Mult-Server Deploy) create a custom docker network:
```
sudo docker network create \
--driver=bridge \
--opt icc=true \
--subnet=172.20.0.0/16 \
vpn-1
```
And finally navigate to the folder containing the `Kasm.ovpn` config file and run the container:
```
sudo docker run -d \
--cap-add NET_ADMIN \
--name open-vpn \
--net vpn-1 \
--ip 172.20.0.2 \
-e VPN_CONFIG=Kasm.ovpn \
-v $(pwd):/vpn/config \
--restart unless-stopped \
openvpn-client
```
### Customizing Workspaces
```{include} /how_to/vpn_sidecar/customizing_workspaces.md
```
### Testing
Testing the VPN configuration in the container will vary depending on the provider or use case, but here are some tips.
These examples will be using the `AlmaLinux 8 - VPN` Workspace configured earlier.
#### Finding the public IP OpenVPN
Click on Applications -> Terminal Emulator and enter:
```
curl icanhazip.com
```
Make sure the IP returned is not the current public IP of the Kasm Workspaces Agent the container is running on.
## Option 2 using a popular VPN Vendor container
This example will be using an off the shelf VPN container here specifically geared for [NordVPN](https://nordvpn.com/), but the steps should be similar depending on the desired provider or configuration.
### Setting up a VPN container
On the Docker host running Kasm Workspaces (or Agent Server if using a Mult-Server Deploy) first create a custom docker network:
```
docker network create \
--driver=bridge \
--opt icc=true \
--subnet=172.20.0.0/16 \
vpn-1
```
Now spinup a NordVPN Docker container:
A NordVPN token is required and can be obtained following these [instructions](https://support.nordvpn.com/1905092252)
```
docker run -d \
--cap-add NET_ADMIN \
--cap-add NET_RAW \
--name nord-vpn \
--net vpn-1 \
--ip 172.20.0.2 \
-e TOKEN=NORDVPNTOKEN \
-e TECHNOLOGY=NordLynx \
--restart unless-stopped \
ghcr.io/bubuntux/nordvpn
```
### Customizing Workspaces
```{include} /how_to/vpn_sidecar/customizing_workspaces.md
```
### Testing
Testing the VPN configuration in the container will vary depending on the provider or use case, but here are some tips.
These examples will be using the `AlmaLinux 8 - VPN` Workspace configured earlier.
#### Nord VPN Testing
Most VPN providers' webpages will give some kind of indication that the browsing session is "protected" from their home page. This example uses a NordVPN, so open up Firefox from the desktop and navigate to [https://nordvpn.com](https://nordvpn.com), The page should display a `Protected` status:
```{image} /images/vpn_sidecar/protected.png
:width: 100%
:align: center
```
## Option 3 Tailscale
[Tailscale](https://tailscale.com/) is a zero configuration VPN solution that allows users to quickly connect to a network of remote computers by their Tailscale IP addresses. This example will be configuring a sidecar container to route traffic to the machines on the Tailscale network. It is important to note here this example does not configure an exit node here simply allowing configured VPN containers to route traffic out to the Tailscale network.
### Getting the Tailscale auth key
Most users can skip this step when trying to connect Workspaces containers to existing Tailscale infrastructure. For those who are new to Tailscale sign up for an account with them [here](https://login.tailscale.com/start).
After signed up a login screen will be presented:
```{image} /images/vpn_sidecar/welcome.png
```
Ignore the setup wizard and click the avatar on the top right of the screen and select "Billing":
```{image} /images/vpn_sidecar/billing.png
```
From here click on "Keys" under "Personal Settings":
```{image} /images/vpn_sidecar/keys.png
```
Click on "Generate auth key...":
```{image} /images/vpn_sidecar/generate.png
```
The Kasm team recommends setting "Reusable" and "Ephemeral" but ultimately review the settings and decide the best settings:
```{image} /images/vpn_sidecar/keysettings.png
```
Copy the key created and move on to the next step.
### Setting up a Tailscale Docker container
On the Kasm Workspaces host build a custom docker container to act as the VPN sidecar container.
```
mkdir tailscale
cd tailscale
mkdir root
```
Here is the `Dockerfile`:
```
FROM alpine:3.15
RUN \
apk add --no-cache \
bind-tools \
tailscale
# add local files
COPY /root /
ENTRYPOINT [ "/entrypoint.sh" ]
```
And custom `root/entrypoint.sh`:
```
#! /bin/sh
# create tun device
if [ ! -c /dev/net/tun ]; then
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
fi
# Enable devices MASQUERADE mode
iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
iptables -t nat -A POSTROUTING -o tailscale+ -j MASQUERADE
# start vpn client
tailscaled
```
Make sure the entrypoint is executable:
```
chmod +x root/entrypoint.sh
```
The directory structure should look like this:
```
tailscale/
├─ root/
│ ├─ entrypoint.sh
├─ Dockerfile
```
Now build the container:
```
sudo docker build -t tailscaled .
```
On the Docker host running Kasm Workspaces (or Agent Server if using a Mult-Server Deploy) create a custom docker network:
```
sudo docker network create \
--driver=bridge \
--opt icc=true \
--subnet=172.20.0.0/16 \
vpn-1
```
Now spinup a Tailscale Docker container:
```
sudo docker run -d \
--cap-add NET_ADMIN \
--name tailscaled \
--net vpn-1 \
--ip 172.20.0.2 \
--restart unless-stopped \
tailscaled
```
Now login using the auth key:
```
sudo docker exec tailscaled tailscale up --authkey=
```
Now navigate [here](https://login.tailscale.com/admin/machines) and ensure the machine is listed:
```{image} /images/vpn_sidecar/machine.png
```
### Customizing Workspaces
```{include} /how_to/vpn_sidecar/customizing_workspaces.md
```
### Testing
Testing the VPN in the container will vary depending on the provider or use case, but here are some tips.
These examples will be using the `AlmaLinux 8 - VPN` Workspace configured earlier.
#### Tailscale testing
An easy way to test is to simply run a ping to another device on the Tailscale network from the workspace. In order to test this at least one other device connected to the Tailscale network will be needed. From the Tailscale dashboard [here](https://login.tailscale.com/admin/machines) the IPs of other connected devices can be seen. This example will be using `100.86.224.182`.
Assuming the Workspace is a modified desktop Workspace and in particular that this container is using the AlmaLinux 8 example from above.
Once launched into the session go ahead and open a terminal from Applications -> Terminal Emulator:
```{image} /images/vpn_sidecar/openterminal.png
```
Now run a ping command:
```
ping 100.86.224.182
```
There should be acks printed to the screen:
```{image} /images/vpn_sidecar/pings.png
```
Any container with this configuration will have access to other machines on the connected Tailscale network.