Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ntnj/tunwg
Secure private tunnel to your local servers
https://github.com/ntnj/tunwg
ngrok-alternative self-hosted tunnel wireguard wireguard-tunnel
Last synced: 2 months ago
JSON representation
Secure private tunnel to your local servers
- Host: GitHub
- URL: https://github.com/ntnj/tunwg
- Owner: ntnj
- License: mit
- Created: 2023-01-16T17:51:13.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-06-07T10:34:56.000Z (8 months ago)
- Last Synced: 2024-08-03T22:19:12.531Z (6 months ago)
- Topics: ngrok-alternative, self-hosted, tunnel, wireguard, wireguard-tunnel
- Language: Go
- Homepage: https://tunwg.com
- Size: 52.7 KB
- Stars: 207
- Watchers: 5
- Forks: 8
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - ntnj/tunwg - Secure private tunnel to your local servers (Go)
README
# Tunwg
End to end encrypted secure tunnel to local servers
## Use
To expose port 8080:
```bash
tunwg -p 8080
```
or
```bash
tunwg --forward=http://localhost:8080
```
You can run tunwg in docker too:
```bash
docker run -it --rm --network=host -v tunwg_keys:/data ghcr.io/ntnj/tunwg tunwg --forward=http://localhost:8080
```
`--network=host` is needed to access the port 8080 on host.## Install
You can download a pre-compiled binary from [Github releases](https://github.com/ntnj/tunwg/releases) for [Windows](https://github.com/ntnj/tunwg/releases/latest/download/tunwg.exe), [Linux](https://github.com/ntnj/tunwg/releases/latest/download/tunwg) and Mac ([Arm](https://github.com/ntnj/tunwg/releases/latest/download/tunwg-darwin-arm64)/[Intel](https://github.com/ntnj/tunwg/releases/latest/download/tunwg-darwin))
To install from source:
```bash
go install github.com/ntnj/tunwg/tunwg@latest
```## Privacy
Tunwg provides end to end SSL encryption and forwards TCP stream to the tunwg instance running on your local machine. The local instance running on your machine is responsible for generating an HTTPS certificate for you and forwards the decrypted traffic to your local server. This means that your traffic is completely private to you.
You can also self-host your own server.
## Features
### Custom domains
To use your own domain name instead of a subdomain on tunwg.com, add a CNAME record in your DNS provider to the encoded domain on tunwg.com e.g. for `test.example.com`, add a CNAME entry for `test` to `xxxxxxxx.l.tunwg.com`
### Use directly in Go programs
If you're writing your HTTP server in golang, you can use `tunwg` directly without running a separate binary.
```go
import "github.com/ntnj/tunwg"listener, err := tunwg.NewListener("")
http.Serve(listener, httpHandler)
```### Persistent URLs
Since the generated subdomain is derived from your wireguard key and the forwarded address, it'll remain constant across process restarts. The wireguard key is stored in `.config/tunwg/` ([os.UserConfigDir](https://pkg.go.dev/os#UserConfigDir)/tunwg) or `/data/` in docker. It can be customized with `TUNWG_PATH` environment variable.
### Automatic SSL certificates
Automatic SSL certificate are issued through LetsEncrypt and automatically renewed. Fallback to ZeroSSL is supported in case of LetsEncrypt rate limits.
### Relay traffic over HTTPS
In case your firewall blocks UDP packets, you can relay the traffic over HTTPS. To use, just add `TUNWG_RELAY=true` to client environment variables.
This will effectively be TCP over UDP over TCP, so performance will suffer in case of packet drops. Use this option only if needed.### Expose ports on other hosts
You can forward any ports on local network which the machine running tunwg has access to, without installing tunwg on the forwarded host. e.g.
```bash
tunwg --forward=http://10.0.0.2:8000,http://10.0.0.10:9000
```This is especially useful when running `tunwg` with docker compose to expose the ports on other containers without making any modifications to those images. e.g. `docker-compose.yml`
```docker-compose.yml
tunwg:
image: ghcr.io/ntnj/tunwg
command: tunwg --forward=http://whoamiwhoami:
image: traefik/whoami
```
You can then run `docker compose logs tunwg` to view the generated URL.### HTTP Basic Auth support
To expose private servers using tunwg, you can use the inbuilt basic auth support.
```bash
tunwg --forward=... --limit=$(htpasswd -nbB )
```### PROXY Protocol support
[PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) enables local server to receive the remote user's IP address.
## Security considerations
Even though the subdomain generated by tunwg seems random, they're not private. Since SSL certificates are issued for them by tunwg client, the encoded subdomain is added to certificate transparency logs. Many crawlers and attackers monitor those transparency logs, so you'll get some automated traffic to your servers after you first issue the certificate. Do not foward any local servers which may be vulnerable or expose private data without auth, and if you need to do that, use the inbuilt tunwg basic auth.
Since anyone can run a server on `l.tunwg.com` domain, be careful when using cookies received from the browser.
## Self hosting
The instance at `l.tunwg.com` runs on a VPS with very limited resources and may be bandwidth limited. For critical use cases, you can self-host your own tunwg server.
```bash
go install github.com/ntnj/tunwg/tunwg@latest
TUNWG_RUN_SERVER=true TUNWG_API=example.com TUNWG_IP= TUNWG_PORT= tunwg
```With docker:
```docker-compose.yml
tunwgs:
image: ghcr.io/ntnj/tunwg
network_mode: host # or ports, 80,443,443/udp
environment:
TUNWG_RUN_SERVER: true
TUNWG_PORT: 443 # udp port that is used for wireguard connections.
TUNWG_IP: "a.b.c.d" # ip of server
TUNWG_API: example.com # all subdomains should resolve to server
```Clients will connect to your hosted instance if you set the same `TUNWG_API` environment variable there.
You can also set the `TUNWG_AUTH` environment variable to limit which clients can use your server. In that case, clients would need to set the same `TUNWG_AUTH`.
The server listens on port 443 (for HTTPS traffic) and on port 80 (to redirect to HTTPS and for http-01 SSL challenges). It also listens on UDP port `TUNWG_PORT` for wireguard UDP traffic. The public instance listens on UDP 443, since it's less likely to be blocked by firewalls.
The server is fully stateless and doesn't require any storage. It caches the wireguard private key and recent peers on disk to enable instant reconnection of tunnels after server restart. The tunwg client will add itself as peer again if the wireguard handshake with server is missed.
If you're running it behind a reverse proxy like caddy/nginx, you should make sure that the reverse proxy passes through TLS instead of decrypting HTTPS traffic.
## Internal Details
One of the primary goals for tunwg was to securely allow new clients to join without requiring any configuration or database on server, and to allow end to end SSL.
The `tunwg` binary runs a user-space TCP/IP stack using [`gVisor netstack`](https://gvisor.dev/docs/user_guide/networking/). It generates a wireguard private key, and derives the IP address of wireguard connection based on a hash of the public key. On startup, it sends the public key to the tunwg server which replies with its own public key, establishing a wireguard connection between client and server.
The generated domain name is an encoding of the internal wireguard IP address and the port. When tunwg server receives a request, it parses the TLS SNI to get the domain and decodes it to an IP:port pair, which it then forwards the connection to over the internal wireguard network.
### Develop locally
Run server: `TUNWG_TEST_LOCALHOST=true TUNWG_RUN_SERVER=true TUNWG_KEY=tunwgs TUNWG_PORT=443 TUNWG_IP=127.0.0.1 go run ./tunwg`
Run client: `TUNWG_TEST_LOCALHOST=true go run ./tunwg --forward=http://localhost:8000`
Test: `curl -k -Li --connect-to ::127.0.0.1: https://abcd.l.tunwg.com`
## Possible Future Improvements
- Allow distributed servers