{"id":13547453,"url":"https://github.com/whyvra/tunnel","last_synced_at":"2025-04-23T06:30:50.721Z","repository":{"id":37843811,"uuid":"327144503","full_name":"whyvra/tunnel","owner":"whyvra","description":"The secure manager for your WireGuard clients","archived":false,"fork":false,"pushed_at":"2023-12-26T19:22:25.000Z","size":1140,"stargazers_count":27,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T09:22:32.749Z","etag":null,"topics":["blazor","clients","docker","dotnet","manager","ui","vpn","web","web-ui","wireguard"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/whyvra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-01-05T23:21:16.000Z","updated_at":"2025-03-02T18:09:09.000Z","dependencies_parsed_at":"2023-12-26T20:59:51.453Z","dependency_job_id":"9539de98-e6ab-43a5-913c-65b01713138e","html_url":"https://github.com/whyvra/tunnel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whyvra%2Ftunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whyvra%2Ftunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whyvra%2Ftunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whyvra%2Ftunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/whyvra","download_url":"https://codeload.github.com/whyvra/tunnel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250384726,"owners_count":21421784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","clients","docker","dotnet","manager","ui","vpn","web","web-ui","wireguard"],"created_at":"2024-08-01T12:00:55.992Z","updated_at":"2025-04-23T06:30:49.361Z","avatar_url":"https://github.com/whyvra.png","language":"C#","funding_links":[],"categories":["C# #"],"sub_categories":[],"readme":"# tunnel\n\n[![Tunnel Build](https://img.shields.io/github/workflow/status/whyvra/tunnel/Tunnel?style=flat-square)](https://github.com/whyvra/tunnel/actions)\n[![Docker Pulls](https://img.shields.io/docker/pulls/whyvra/tunnel?style=flat-square)](https://hub.docker.com/r/whyvra/tunnel)\n[![LICENSE](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/whyvra/tunnel/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\n\nThe secure manager for your WireGuard clients\n\n\u003cimg src=\"https://raw.githubusercontent.com/whyvra/tunnel/master/docs/sample.gif\" width=\"900\"\u003e\n\n## Table of contents\n\n* [Purpose](#purpose)\n* [Usage](#usage)\n* [Configuration](#configuration)\n* [API settings](#api-settings)\n* [Blazor settings](#blazor-settings)\n* [SSL](#ssl)\n* [Database](#database)\n* [Authentication](#authentication)\n* [docker-compose](#docker-compose)\n* [License](#license)\n\n## Purpose\n\nTunnel 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.\n\nTunnel 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.\n\nThe 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. \n\n## Usage\n\nThe simplest way to get started is to use the docker image.\n\n```bash\ndocker run -it --rm -p \"5800:5800\" whyvra/tunnel\n```\n\nYou should now be able to access tunnel via `http://localhost:5800/`\n\nBy 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`.\n\n## Configuration\n\nThe docker image configuration can be tweaked in a number of different ways using `appsettings.json` files and/or environment variables.\n\nThe `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.\n\n## API settings\n\nThe 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.\n\n```bash\ndocker run -it --rm -p \"5800:5800\" \\\n-e \"DOTNET_CUSTOM_APPSETTINGS=/run/secrets/appsettings.json\" \\\n--mount type=bind,source=\"$(pwd)\",target=/run/secrets \\\nwhyvra/tunnel\n```\n\nThe API settings can also be overwritten using environment variables. Each element in the hierarchy is separated by a double underscore.\n\nFor example, if you wanted to override the `TunnelContext` connection string, the environment variable would be called `ConnectionStrings__TunnelContext`.\n\n```bash\ndocker run -it --rm -p \"5800:5800\" \\\n-e \"ConnectionStrings__TunnelContext=Data Source=/data/tunnel_db.sqlite3;\" \\\nwhyvra/tunnel\n```\n\n## Blazor settings\n\nThe Blazor frontend settings can only be modified by overwriting the `appsetting.json` file in `/srv/www` as shown below.\n\n```bash\ndocker run -it --rm -p \"5800:5800\" \\\n-v \"$(pwd)/appsettings.json\":/srv/www/appsettings.json \\\nwhyvra/tunnel\n```\n\nThe 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.\n\n```json\n{\n  \"api\": {\n    \"url\": \"/api\"\n  },\n  \"auth\": {\n    \"enabled\": false\n  }\n}\n```\n\nSee the Authentication section below for more info on the `auth` parameters.\n\n## SSL\n\nTo 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. \n\n```bash\ndocker run -it --rm -p \"5800:5800\" \\\n-e \"SSL_CERT=/run/secrets/cert.pem\" \\\n-e \"SSL_KEY=/run/secrets/key.pem\" \\\n--mount type=bind,source=\"$(pwd)\"/ssl,target=/run/secrets \\\nwhyvra/tunnel\n```\n\nPlease note that `SSL_CERT` should point to the chained version of your SSL certificate.\n\n## Database\n\nTunnel supports SQLite and PostgreSQL. The relevant settings in the API `appsettings.json` are as follows:\n\n```json\n{\n  ...\n  \"database\": {\n    \"type\": \"sqlite\",\n    \"automaticMigrations\": true\n  },\n  \"ConnectionStrings\": {\n    \"TunnelContext\": \"Data Source=/data/tunnel.sqlite3;\"\n  }\n}\n```\nFor PostgreSQL, set `database.type` to `postgres` and update the `TunnelContext` connection string.\n\nYou can also use the following environment variables:\n* `database__type`\n* `database__automaticMigrations`\n* `ConnectionStrings__TunnelContext`\n\n## Authentication\n\nAuthentication 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.\n\nAdd the following `auth` parameters to `appsettings.json`\n```json\n{\n  ...\n  \"auth\": {\n    \"authority\": \"https://example.keycloak.com/auth/realms/apps\",\n    \"clientId\": \"wg.tunnel\",\n    \"enabled\": true,\n    \"requiredRole\": \"wg_admin\",\n    \"responseType\": \"code\"\n  }\n}\n```\n\nThe `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.\n\nThe `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.\n\nPlease 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`.\n\n## docker-compose\n\nDetailed 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`.\n\n### Folder structure:\n```\n.\n├── appsettings.json\n├── data (data folder for tunnel)\n├── docker-compose.yml\n├── init_script.sql\n├── pgdata (folder for postgres data)\n└── ssl\n    ├── tls.crt\n    └── tls.key\n```\n\nThe `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.\n\n```bash\n$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out tls.key\n$ openssl req -key tls.key -x509 -new -days 720 -out tls.crt\n```\n\n```yaml\n# docker-compose.yml\nversion: '3.5'\n\nservices:\n\n  postgres:\n    image: postgres:13-alpine\n    hostname: postgres\n    environment:\n    - POSTGRES_PASSWORD=postgres\n    - PGDATA=/var/lib/postgresql/data/pgdata\n    volumes:\n    - ./pgdata:/var/lib/postgresql/data/pgdata\n    - ./init_script.sql:/docker-entrypoint-initdb.d/init_script.sql\n\n  keycloak:\n    image: jboss/keycloak:latest\n    hostname: keycloak\n    depends_on:\n    - postgres\n    environment:\n    - DB_VENDOR=postgres\n    - DB_ADDR=postgres\n    - DB_PORT=5432\n    - DB_USER=postgres\n    - DB_PASSWORD=postgres\n    - KEYCLOAK_USER=admin\n    - KEYCLOAK_PASSWORD=admin\n    - KEYCLOAK_LOGLEVEL=WARN\n    - ROOT_LOGLEVEL=WARN\n    volumes:\n    - ./ssl:/etc/x509/https\n    ports:\n    - \"8443:8443\"\n\n  tunnel:\n    image: whyvra/tunnel:0.1\n    hostname: wg-tunnel\n    depends_on:\n    - postgres\n    - keycloak\n    environment:\n    - database__type=postgres\n    - ConnectionStrings__TunnelContext=Host=postgres;Database=tunnel;Username=postgres;Password=postgres;\n    - auth__enabled=true\n    - auth__authority=https://keycloak.lan:8443/auth/realms/apps\n    - auth__clientId=wg_tunnel\n    - auth__requiredRole=wg_admin\n    volumes:\n    - ./data:/data:rw\n    - ./appsettings.json:/srv/www/appsettings.json\n    - ./ssl/tls.crt:/etc/ssl/certs/tls.crt\n    ports:\n    - \"5800:5800\"\n```\n\n```json\n// appsettings.json\n{\n  \"api\": {\n    \"url\": \"/api\"\n  },\n  \"auth\": {\n    \"authority\": \"https://keycloak.lan:8443/auth/realms/apps\",\n    \"clientId\": \"wg_tunnel\",\n    \"enabled\": true,\n    \"requiredRole\": \"wg_admin\"\n  }\n}\n```\n\n```sql\n# init_script.sql\nCREATE DATABASE keycloak;\nCREATE DATABASE tunnel;\n```\n\n## License\n\nReleased under the [MIT License](https://github.com/whyvra/tunnel/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhyvra%2Ftunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhyvra%2Ftunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhyvra%2Ftunnel/lists"}