easybot-tunnel-client/README.md

194 lines
5.7 KiB
Markdown
Raw Permalink Normal View History

2026-05-16 14:30:56 +02:00
# EasyBot Tunnel Client
Lightweight reverse-tunnel client that connects private services (databases, APIs, etc.) behind firewalls to your EasyBot runtime via a secure WebSocket connection.
The client connects **outbound** to your EasyBot server — no inbound ports, firewall rules, or public IPs needed on the client side.
## Prerequisites
1. An EasyBot instance with the Tunnels feature enabled
2. A tunnel created from the EasyBot dashboard (Settings > Tunnels)
3. The **token** shown once at creation time (starts with `eb_tun_`)
## Quick Start (Docker)
```bash
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://YOUR_RUNTIME_URL/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_YOUR_TOKEN_HERE \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
```
Replace:
- `YOUR_RUNTIME_URL` with your EasyBot runtime hostname (e.g. `runtime.example.com`)
- `eb_tun_YOUR_TOKEN_HERE` with the token from the dashboard
## Installation by OS
### Linux (Docker)
```bash
# Pull and run
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_xxxxx \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
# Check logs
docker logs -f easybot-tunnel
```
### Linux (systemd, without Docker)
```bash
# Install Node.js 20+
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs
# Download and install
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Create systemd service
sudo tee /etc/systemd/system/easybot-tunnel.service <<EOF
[Unit]
Description=EasyBot Tunnel Client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Restart=always
RestartSec=5
Environment=TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel
Environment=TUNNEL_TOKEN=eb_tun_xxxxx
WorkingDirectory=$(pwd)
ExecStart=/usr/bin/node dist/index.js
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now easybot-tunnel
sudo journalctl -u easybot-tunnel -f
```
### Windows (Docker Desktop)
```powershell
docker run -d --restart always --name easybot-tunnel `
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel `
-e TUNNEL_TOKEN=eb_tun_xxxxx `
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
```
### Windows (as a service, without Docker)
```powershell
# Install Node.js 20+ from https://nodejs.org
# Download and build
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Install as Windows service using nssm (https://nssm.cc)
nssm install EasyBotTunnel "C:\Program Files\nodejs\node.exe" "C:\easybot-tunnel-client\dist\index.js"
nssm set EasyBotTunnel AppEnvironmentExtra TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel TUNNEL_TOKEN=eb_tun_xxxxx
nssm set EasyBotTunnel AppRestartDelay 5000
nssm start EasyBotTunnel
```
### macOS (Docker)
```bash
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_xxxxx \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
```
### macOS (launchd, without Docker)
```bash
# Install Node.js
brew install node@22
# Download and build
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Create launch agent
cat > ~/Library/LaunchAgents/com.easybot.tunnel.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.easybot.tunnel</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>$(pwd)/dist/index.js</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>TUNNEL_SERVER</key><string>wss://runtime.example.com/ws/tunnel</string>
<key>TUNNEL_TOKEN</key><string>eb_tun_xxxxx</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.easybot.tunnel.plist
```
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `TUNNEL_SERVER` | Yes | WebSocket URL of your EasyBot runtime (e.g. `wss://runtime.example.com/ws/tunnel`) |
| `TUNNEL_TOKEN` | Yes | Authentication token from the dashboard (starts with `eb_tun_`) |
## How It Works
1. The client connects to your EasyBot runtime via WebSocket (outbound only)
2. The server sends a **config** with port mappings (e.g. "forward localhost:5432 on this tunnel")
3. When EasyBot needs to reach your private service, it opens a TCP connection through the tunnel
4. Traffic flows bidirectionally: EasyBot runtime <-> WebSocket <-> Tunnel Client <-> Your private service
All port mappings are configured **server-side** in the EasyBot dashboard. The client only needs the server URL and token.
## Verifying the Connection
After starting the client, check the EasyBot dashboard (Tunnels section). Your tunnel should show:
- Status: **Connected** (green)
- Latency in ms
- Client IP
## Troubleshooting
| Issue | Solution |
|-------|----------|
| "Connection refused" | Check TUNNEL_SERVER URL is correct and reachable |
| "Authentication failed" | Verify TUNNEL_TOKEN is correct (not expired/regenerated) |
| Keeps reconnecting | Check firewall allows outbound WSS (port 443) |
| Target not reachable | Ensure the target service (e.g. PostgreSQL) is running and accessible from the machine running the tunnel client |
## Building from Source
```bash
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install
npm run build
node dist/index.js
```