Skip to content

whyvra/tunnel

Repository files navigation

tunnel

Tunnel Build Docker Pulls LICENSE PRs Welcome

The secure manager for your WireGuard clients

Table of contents

Purpose

Tunnel is a secure manager for your WireGuard clients' configuration. It is not meant to manage your server's and your clients' private keys. Your server's private key should be stored securely on your server and your clients' private keys should be stored on their devices only. Tunnel does not automatically update your WireGuard configuration on the file system nor does it manage the WireGuard services.

Tunnel offers an easy way to add new clients. Their keys are generated in the browser (using C# running on WebAssembly) and only the public key is sent to the server. Your private key is never sent. The relevant peer section can then be copied from the server configuration and added to your WireGuard config file on your server.

The QR Code and WireGuard config file are only available when you first add the client. They are gone after you close the dialog and can never be generated by Tunnel again (again the private key is not stored). You can always revoke an exisiting client and generate a new key pair by creating a new client.

Usage

The simplest way to get started is to use the docker image.

docker run -it --rm -p "5800:5800" whyvra/tunnel

You should now be able to access tunnel via http://localhost:5800/

By default, the docker image exposes port 5800 where it serves its content using HTTP. The data is stored in a SQLite database saved in /data. A 7-day rotating log is also kept under /data/logs.

Configuration

The docker image configuration can be tweaked in a number of different ways using appsettings.json files and/or environment variables.

The appsettings.json files hold all the base settings for the Tunnel app. There's one for the API and one for Blazor frontend located in /srv/dotnet and /srv/www respectively.

API settings

The default API settings can be overwritten by mounting a custom appsettings.json file and pointing the DOTNET_CUSTOM_APPSETTINGS environment variable to it. Please note if a setting is not overwritten in the custom appsettings.json file, the base setting will still be read.

docker run -it --rm -p "5800:5800" \
-e "DOTNET_CUSTOM_APPSETTINGS=/run/secrets/appsettings.json" \
--mount type=bind,source="$(pwd)",target=/run/secrets \
whyvra/tunnel

The API settings can also be overwritten using environment variables. Each element in the hierarchy is separated by a double underscore.

For example, if you wanted to override the TunnelContext connection string, the environment variable would be called ConnectionStrings__TunnelContext.

docker run -it --rm -p "5800:5800" \
-e "ConnectionStrings__TunnelContext=Data Source=/data/tunnel_db.sqlite3;" \
whyvra/tunnel

Blazor settings

The Blazor frontend settings can only be modified by overwriting the appsetting.json file in /srv/www as shown below.

docker run -it --rm -p "5800:5800" \
-v "$(pwd)/appsettings.json":/srv/www/appsettings.json \
whyvra/tunnel

The default Blazor frontend settings are shown below. These are the minimal required settings for the frontend. If you overwrite the Blazor appsettings.json file, you should at least include those.

{
  "api": {
    "url": "/api"
  },
  "auth": {
    "enabled": false
  }
}

See the Authentication section below for more info on the auth parameters.

SSL

To use HTTPS instead of HTTP, use the SSL_CERT and SSL_KEY environment variables to point to the location of the mounted certificate and key files.

docker run -it --rm -p "5800:5800" \
-e "SSL_CERT=/run/secrets/cert.pem" \
-e "SSL_KEY=/run/secrets/key.pem" \
--mount type=bind,source="$(pwd)"/ssl,target=/run/secrets \
whyvra/tunnel

Please note that SSL_CERT should point to the chained version of your SSL certificate.

Database

Tunnel supports SQLite and PostgreSQL. The relevant settings in the API appsettings.json are as follows:

{
  ...
  "database": {
    "type": "sqlite",
    "automaticMigrations": true
  },
  "ConnectionStrings": {
    "TunnelContext": "Data Source=/data/tunnel.sqlite3;"
  }
}

For PostgreSQL, set database.type to postgres and update the TunnelContext connection string.

You can also use the following environment variables:

  • database__type
  • database__automaticMigrations
  • ConnectionStrings__TunnelContext

Authentication

Authentication can be added by using an OpenID Connect server like Keycloak. In order to configure authentication, you'll need to update both the API and Blazor settings. The API settings can be tweaked using environment variables but you will need to update the /srv/www/appsettings.json file for the Blazor settings.

Add the following auth parameters to appsettings.json

{
  ...
  "auth": {
    "authority": "https://example.keycloak.com/auth/realms/apps",
    "clientId": "wg.tunnel",
    "enabled": true,
    "requiredRole": "wg_admin",
    "responseType": "code"
  }
}

The requiredRole parameter is optional. If provided, it will require the logged-in user to have the provided role under the roles claim in the JWT issued by the Open ID Connect server.

The responseType parameter is only required for the Blazor settings. It will default to code if omitted. Should it be provided to the API settings, it will just be ignored.

Please note that if you have an SSL certificate issued by a custom or internal CA on your Open ID connect server, you will need to add or mount the root CA certificate under /etc/ssl/certs.

docker-compose

Detailed below is a docker-compose example making use of PostgreSQL as the backend database and Keycloak (Open ID Connect server) for authentication. This example has been tested using docker stack.

Folder structure:

.
├── appsettings.json
├── data (data folder for tunnel)
├── docker-compose.yml
├── init_script.sql
├── pgdata (folder for postgres data)
└── ssl
    ├── tls.crt
    └── tls.key

The tls.crt and tls.key can be generated with the following commands. Please note that the certificate should answer to keycloak.lan or whatever hostname you choose to replace it with.

$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out tls.key
$ openssl req -key tls.key -x509 -new -days 720 -out tls.crt
# docker-compose.yml
version: '3.5'

services:

  postgres:
    image: postgres:13-alpine
    hostname: postgres
    environment:
    - POSTGRES_PASSWORD=postgres
    - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
    - ./pgdata:/var/lib/postgresql/data/pgdata
    - ./init_script.sql:/docker-entrypoint-initdb.d/init_script.sql

  keycloak:
    image: jboss/keycloak:latest
    hostname: keycloak
    depends_on:
    - postgres
    environment:
    - DB_VENDOR=postgres
    - DB_ADDR=postgres
    - DB_PORT=5432
    - DB_USER=postgres
    - DB_PASSWORD=postgres
    - KEYCLOAK_USER=admin
    - KEYCLOAK_PASSWORD=admin
    - KEYCLOAK_LOGLEVEL=WARN
    - ROOT_LOGLEVEL=WARN
    volumes:
    - ./ssl:/etc/x509/https
    ports:
    - "8443:8443"

  tunnel:
    image: whyvra/tunnel:0.1
    hostname: wg-tunnel
    depends_on:
    - postgres
    - keycloak
    environment:
    - database__type=postgres
    - ConnectionStrings__TunnelContext=Host=postgres;Database=tunnel;Username=postgres;Password=postgres;
    - auth__enabled=true
    - auth__authority=https://keycloak.lan:8443/auth/realms/apps
    - auth__clientId=wg_tunnel
    - auth__requiredRole=wg_admin
    volumes:
    - ./data:/data:rw
    - ./appsettings.json:/srv/www/appsettings.json
    - ./ssl/tls.crt:/etc/ssl/certs/tls.crt
    ports:
    - "5800:5800"
// appsettings.json
{
  "api": {
    "url": "/api"
  },
  "auth": {
    "authority": "https://keycloak.lan:8443/auth/realms/apps",
    "clientId": "wg_tunnel",
    "enabled": true,
    "requiredRole": "wg_admin"
  }
}
# init_script.sql
CREATE DATABASE keycloak;
CREATE DATABASE tunnel;

License

Released under the MIT License.

Releases

No releases published

Packages

No packages published