392 lines
15 KiB
Markdown
392 lines
15 KiB
Markdown
# Phase 2: The "Fossorial" Tunnel Stack (Pangolin, Gerbil, Newt)
|
|
|
|
## Goal
|
|
Deploy the Fossorial tunnel stack using your MikroTik's static IP (62.73.120.142) to host tunnels without requiring a VPS, with MikroTik container fallback for resilience.
|
|
|
|
---
|
|
|
|
## What is Fossorial?
|
|
|
|
Fossorial is a self-hosted tunnel solution consisting of:
|
|
|
|
| Component | Purpose | Role |
|
|
|-----------|---------|------|
|
|
| **Pangolin** | Central controller/dashboard | Manages tunnels, provides web UI |
|
|
| **Gerbil** | WireGuard manager | Handles WireGuard peer configuration |
|
|
| **Newt** | Tunnel connector | Lightweight agent that "dials out" to establish tunnels |
|
|
|
|
**Why Fossorial over plain WireGuard?**
|
|
- Automatic peer management
|
|
- Web-based tunnel configuration
|
|
- Self-healing connections via Newt
|
|
- Easier certificate/identity management
|
|
|
|
---
|
|
|
|
## Current WireGuard State (MikroTik)
|
|
|
|
```
|
|
Interface: back-to-home-vpn
|
|
├── Listen Port: 59188 (non-standard - good!)
|
|
├── Address: 192.168.216.1/24
|
|
├── Public Key: 3e+p++SJ6f5EURt6WCKApOLMQHWpURm/vn/0s9+EKzs=
|
|
└── Peers: 3 configured
|
|
```
|
|
|
|
**Port 51820 Status:** NOT in use - available for Fossorial
|
|
|
|
---
|
|
|
|
## Architecture Overview
|
|
|
|
```
|
|
Internet
|
|
│
|
|
┌────────────▼────────────┐
|
|
│ MikroTik (62.73.120.142)│
|
|
│ Port Forward: │
|
|
│ UDP 51820 → Unraid │
|
|
│ TCP 443 → Traefik │
|
|
└────────────┬────────────┘
|
|
│
|
|
┌──────────────────┼──────────────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ Pangolin │ │ Gerbil │ │ Newt │
|
|
│ (Controller) │ │ (WG Manager) │ │ (Connector) │
|
|
│ :3000 web UI │ │ :51820 WG │ │ Outbound only │
|
|
│ │ │ :8080 API │ │ │
|
|
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
|
|
│ │ │
|
|
└───────────────────┴───────────────────┘
|
|
Internal Network
|
|
192.168.31.0/24
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Steps
|
|
|
|
### Step 2.1: Create Docker Network for Fossorial
|
|
|
|
```bash
|
|
docker network create --driver bridge fossorial
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.2: Deploy Pangolin (Controller)
|
|
|
|
**Unraid Docker Template:**
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<Container version="2">
|
|
<Name>pangolin</Name>
|
|
<Repository>fossoriumtech/pangolin:latest</Repository>
|
|
<Registry>https://hub.docker.com/r/fossoriumtech/pangolin</Registry>
|
|
<Network>fossorial</Network>
|
|
<Shell>sh</Shell>
|
|
<Privileged>false</Privileged>
|
|
<Overview>Pangolin - Fossorial tunnel controller and dashboard</Overview>
|
|
<Category>Network:VPN</Category>
|
|
<WebUI>https://pangolin.xtrm-lab.org</WebUI>
|
|
<ExtraParams>--restart unless-stopped</ExtraParams>
|
|
|
|
<!-- Ports -->
|
|
<Config Name="Web UI" Target="3000" Default="3000" Mode="tcp" Type="Port" Display="always" Required="true">3000</Config>
|
|
|
|
<!-- Volumes -->
|
|
<Config Name="Data" Target="/app/data" Default="/mnt/user/appdata/pangolin/data" Mode="rw" Type="Path" Display="always" Required="true">/mnt/user/appdata/pangolin/data</Config>
|
|
<Config Name="Config" Target="/app/config" Default="/mnt/user/appdata/pangolin/config" Mode="rw" Type="Path" Display="always" Required="true">/mnt/user/appdata/pangolin/config</Config>
|
|
|
|
<!-- Environment -->
|
|
<Config Name="BASE_URL" Target="PANGOLIN_BASE_URL" Default="https://pangolin.xtrm-lab.org" Mode="" Type="Variable" Display="always" Required="true">https://pangolin.xtrm-lab.org</Config>
|
|
<Config Name="SECRET_KEY" Target="PANGOLIN_SECRET_KEY" Default="" Mode="" Type="Variable" Display="always" Required="true" Mask="true">GENERATE_A_SECURE_32_CHAR_KEY</Config>
|
|
|
|
<!-- Traefik Labels -->
|
|
<Config Name="traefik.enable" Target="traefik.enable" Type="Label" Display="always">true</Config>
|
|
<Config Name="traefik.http.routers.pangolin.rule" Target="traefik.http.routers.pangolin.rule" Type="Label" Display="always">Host(`pangolin.xtrm-lab.org`)</Config>
|
|
<Config Name="traefik.http.routers.pangolin.entrypoints" Target="traefik.http.routers.pangolin.entrypoints" Type="Label" Display="always">https</Config>
|
|
<Config Name="traefik.http.routers.pangolin.tls.certresolver" Target="traefik.http.routers.pangolin.tls.certresolver" Type="Label" Display="always">cloudflare</Config>
|
|
<Config Name="traefik.http.routers.pangolin.middlewares" Target="traefik.http.routers.pangolin.middlewares" Type="Label" Display="always">default-headers@file</Config>
|
|
<Config Name="traefik.http.services.pangolin.loadbalancer.server.port" Target="traefik.http.services.pangolin.loadbalancer.server.port" Type="Label" Display="always">3000</Config>
|
|
<Config Name="traefik.docker.network" Target="traefik.docker.network" Type="Label" Display="always">dockerproxy</Config>
|
|
|
|
<!-- AutoKuma -->
|
|
<Config Name="kuma" Target="kuma" Type="Label" Display="advanced">https://pangolin.xtrm-lab.org</Config>
|
|
<Config Name="kuma.name" Target="kuma.name" Type="Label" Display="advanced">Pangolin Dashboard</Config>
|
|
<Config Name="kuma.type" Target="kuma.type" Type="Label" Display="advanced">http</Config>
|
|
|
|
<!-- Tailscale (optional) -->
|
|
<Config Name="TailScale Fallback State Directory" Target="CA_TS_FALLBACK_DIR" Type="Variable" Display="advanced">/app/data</Config>
|
|
</Container>
|
|
```
|
|
|
|
**Generate Secret Key:**
|
|
```bash
|
|
openssl rand -hex 32
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.3: Deploy Gerbil (WireGuard Manager)
|
|
|
|
**Unraid Docker Template:**
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<Container version="2">
|
|
<Name>gerbil</Name>
|
|
<Repository>fossoriumtech/gerbil:latest</Repository>
|
|
<Registry>https://hub.docker.com/r/fossoriumtech/gerbil</Registry>
|
|
<Network>fossorial</Network>
|
|
<Shell>sh</Shell>
|
|
<Privileged>true</Privileged>
|
|
<Overview>Gerbil - Fossorial WireGuard manager</Overview>
|
|
<Category>Network:VPN</Category>
|
|
<ExtraParams>--cap-add=NET_ADMIN --cap-add=SYS_MODULE --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.conf.all.src_valid_mark=1</ExtraParams>
|
|
|
|
<!-- Ports -->
|
|
<Config Name="WireGuard UDP" Target="51820" Default="51820" Mode="udp" Type="Port" Display="always" Required="true">51820</Config>
|
|
<Config Name="API" Target="8080" Default="8080" Mode="tcp" Type="Port" Display="always" Required="true">8080</Config>
|
|
|
|
<!-- Volumes -->
|
|
<Config Name="WireGuard Config" Target="/etc/wireguard" Default="/mnt/user/appdata/gerbil/wireguard" Mode="rw" Type="Path" Display="always" Required="true">/mnt/user/appdata/gerbil/wireguard</Config>
|
|
<Config Name="Data" Target="/app/data" Default="/mnt/user/appdata/gerbil/data" Mode="rw" Type="Path" Display="always" Required="true">/mnt/user/appdata/gerbil/data</Config>
|
|
|
|
<!-- Environment -->
|
|
<Config Name="PANGOLIN_URL" Target="GERBIL_PANGOLIN_URL" Default="http://pangolin:3000" Mode="" Type="Variable" Display="always" Required="true">http://pangolin:3000</Config>
|
|
<Config Name="PUBLIC_IP" Target="GERBIL_PUBLIC_IP" Default="" Mode="" Type="Variable" Display="always" Required="true">62.73.120.142</Config>
|
|
<Config Name="PUBLIC_PORT" Target="GERBIL_PUBLIC_PORT" Default="51820" Mode="" Type="Variable" Display="always" Required="true">51820</Config>
|
|
<Config Name="WG_INTERFACE" Target="GERBIL_WG_INTERFACE" Default="wg0" Mode="" Type="Variable" Display="always" Required="true">wg0</Config>
|
|
<Config Name="API_KEY" Target="GERBIL_API_KEY" Default="" Mode="" Type="Variable" Display="always" Required="true" Mask="true">SAME_AS_PANGOLIN_SECRET</Config>
|
|
|
|
<!-- AutoKuma -->
|
|
<Config Name="kuma" Target="kuma" Type="Label" Display="advanced">http://192.168.31.2:8080/health</Config>
|
|
<Config Name="kuma.name" Target="kuma.name" Type="Label" Display="advanced">Gerbil WireGuard</Config>
|
|
<Config Name="kuma.type" Target="kuma.type" Type="Label" Display="advanced">http</Config>
|
|
</Container>
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.4: Deploy Newt (Connector)
|
|
|
|
**Unraid Docker Template:**
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<Container version="2">
|
|
<Name>newt</Name>
|
|
<Repository>fossoriumtech/newt:latest</Repository>
|
|
<Registry>https://hub.docker.com/r/fossoriumtech/newt</Registry>
|
|
<Network>fossorial</Network>
|
|
<Shell>sh</Shell>
|
|
<Privileged>false</Privileged>
|
|
<Overview>Newt - Fossorial tunnel connector (dials out to establish tunnels)</Overview>
|
|
<Category>Network:VPN</Category>
|
|
<ExtraParams>--restart unless-stopped</ExtraParams>
|
|
|
|
<!-- Volumes -->
|
|
<Config Name="Data" Target="/app/data" Default="/mnt/user/appdata/newt/data" Mode="rw" Type="Path" Display="always" Required="true">/mnt/user/appdata/newt/data</Config>
|
|
|
|
<!-- Environment -->
|
|
<Config Name="PANGOLIN_URL" Target="NEWT_PANGOLIN_URL" Default="" Mode="" Type="Variable" Display="always" Required="true">https://pangolin.xtrm-lab.org</Config>
|
|
<Config Name="ENDPOINT" Target="NEWT_ENDPOINT" Default="" Mode="" Type="Variable" Display="always" Required="true">62.73.120.142:51820</Config>
|
|
<Config Name="API_KEY" Target="NEWT_API_KEY" Default="" Mode="" Type="Variable" Display="always" Required="true" Mask="true">GENERATE_VIA_PANGOLIN_UI</Config>
|
|
<Config Name="TUNNEL_NAME" Target="NEWT_TUNNEL_NAME" Default="unraid-local" Mode="" Type="Variable" Display="always" Required="true">unraid-local</Config>
|
|
|
|
<!-- AutoKuma -->
|
|
<Config Name="kuma" Target="kuma" Type="Label" Display="advanced">docker</Config>
|
|
<Config Name="kuma.name" Target="kuma.name" Type="Label" Display="advanced">Newt Connector</Config>
|
|
<Config Name="kuma.type" Target="kuma.type" Type="Label" Display="advanced">docker</Config>
|
|
</Container>
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.5: MikroTik Port Forward for WireGuard
|
|
|
|
**Add NAT rule for Fossorial WireGuard:**
|
|
|
|
```routeros
|
|
# Connect via SSH
|
|
ssh -i /root/.ssh/mikrotik_key -p 2222 unraid@192.168.31.1
|
|
|
|
# Add port forward
|
|
/ip/firewall/nat add chain=dstnat \
|
|
action=dst-nat \
|
|
to-addresses=192.168.31.2 \
|
|
to-ports=51820 \
|
|
protocol=udp \
|
|
dst-address=62.73.120.142 \
|
|
dst-port=51820 \
|
|
comment="Fossorial WireGuard"
|
|
|
|
# Add firewall rule to allow
|
|
/ip/firewall/filter add chain=forward \
|
|
action=accept \
|
|
protocol=udp \
|
|
dst-address=192.168.31.2 \
|
|
dst-port=51820 \
|
|
comment="Allow Fossorial WireGuard" \
|
|
place-before=14
|
|
```
|
|
|
|
**Verification:**
|
|
```routeros
|
|
/ip/firewall/nat print where comment~"Fossorial"
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.6: Connect Networks (fossorial ↔ dockerproxy)
|
|
|
|
Pangolin needs to be accessible via Traefik. Either:
|
|
|
|
**Option A: Connect Pangolin to both networks**
|
|
```bash
|
|
docker network connect dockerproxy pangolin
|
|
```
|
|
|
|
**Option B: Use Traefik external routing in dynamic.yml**
|
|
```yaml
|
|
# Add to /mnt/user/appdata/traefik/dynamic.yml
|
|
http:
|
|
routers:
|
|
pangolin-secure:
|
|
rule: "Host(`pangolin.xtrm-lab.org`)"
|
|
entryPoints:
|
|
- https
|
|
middlewares:
|
|
- default-headers
|
|
tls:
|
|
certResolver: cloudflare
|
|
service: pangolin
|
|
|
|
services:
|
|
pangolin:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://192.168.31.2:3000"
|
|
```
|
|
|
|
---
|
|
|
|
### Step 2.7: MikroTik Container Fallback (Optional)
|
|
|
|
Deploy a lightweight Gerbil instance on MikroTik for resilience:
|
|
|
|
**Prerequisites:**
|
|
- USB storage connected to MikroTik (already present: `usb1`)
|
|
- Container mode enabled
|
|
|
|
**MikroTik Commands:**
|
|
|
|
```routeros
|
|
# Create container for Gerbil fallback
|
|
/container/config set registry-url=https://registry-1.docker.io tmpdir=usb1/tmp
|
|
|
|
# Pull gerbil image
|
|
/container add \
|
|
remote-image=fossoriumtech/gerbil:latest \
|
|
interface=docker-bridge \
|
|
root-dir=usb1/gerbil \
|
|
start-on-boot=yes \
|
|
comment="Fossorial Gerbil Fallback"
|
|
|
|
# Configure environment
|
|
/container/envs add name=gerbil-env key=GERBIL_PUBLIC_IP value="62.73.120.142"
|
|
/container/envs add name=gerbil-env key=GERBIL_PUBLIC_PORT value="51821"
|
|
/container/envs add name=gerbil-env key=GERBIL_MODE value="standalone"
|
|
```
|
|
|
|
**Note:** MikroTik containers have limited resources. This is a fallback for critical services only (Pi-hole access, Authentik).
|
|
|
|
---
|
|
|
|
## Service Interruption Assessment
|
|
|
|
| Action | Risk | Impact | Mitigation |
|
|
|--------|------|--------|------------|
|
|
| Deploy Pangolin/Gerbil/Newt | NONE | New containers | - |
|
|
| Port forward 51820 | LOW | New port, existing WG on 59188 unaffected | - |
|
|
| Connect fossorial network | LOW | Container networking | Test connectivity |
|
|
| MikroTik container | MEDIUM | Router resources | Monitor CPU/memory |
|
|
|
|
**Existing WireGuard (back-to-home-vpn) Impact:** NONE
|
|
- Uses port 59188, not 51820
|
|
- Completely separate interface
|
|
|
|
---
|
|
|
|
## Verification Checklist
|
|
|
|
- [ ] All three containers running: `docker ps | grep -E "pangolin|gerbil|newt"`
|
|
- [ ] Pangolin web UI accessible: https://pangolin.xtrm-lab.org
|
|
- [ ] Gerbil API responding: `curl http://192.168.31.2:8080/health`
|
|
- [ ] MikroTik NAT rule in place: `ssh ... "/ip/firewall/nat print"`
|
|
- [ ] External WireGuard test: Connect from external network to 62.73.120.142:51820
|
|
- [ ] Newt connected in Pangolin dashboard
|
|
|
|
---
|
|
|
|
## Initial Pangolin Setup
|
|
|
|
1. Navigate to https://pangolin.xtrm-lab.org
|
|
2. Create admin account
|
|
3. Add Gerbil node:
|
|
- Name: `unraid-gerbil`
|
|
- API URL: `http://gerbil:8080`
|
|
- API Key: (same as GERBIL_API_KEY)
|
|
4. Create a tunnel:
|
|
- Name: `home-services`
|
|
- Assign to Gerbil node
|
|
5. Generate Newt API key in Pangolin UI
|
|
6. Update Newt container with the API key
|
|
|
|
---
|
|
|
|
## Rollback Procedure
|
|
|
|
1. **Stop containers:**
|
|
```bash
|
|
docker stop newt gerbil pangolin
|
|
docker rm newt gerbil pangolin
|
|
```
|
|
|
|
2. **Remove MikroTik NAT:**
|
|
```routeros
|
|
/ip/firewall/nat remove [find comment="Fossorial WireGuard"]
|
|
```
|
|
|
|
3. **Remove network:**
|
|
```bash
|
|
docker network rm fossorial
|
|
```
|
|
|
|
4. **Clean up data (if desired):**
|
|
```bash
|
|
rm -rf /mnt/user/appdata/pangolin /mnt/user/appdata/gerbil /mnt/user/appdata/newt
|
|
```
|
|
|
|
---
|
|
|
|
## Files Modified
|
|
|
|
| File/System | Change | Backup Required |
|
|
|-------------|--------|-----------------|
|
|
| MikroTik NAT | Add UDP 51820 forward | N/A (can remove) |
|
|
| /mnt/user/appdata/traefik/dynamic.yml | Add pangolin route | YES |
|
|
| New directories created | /mnt/user/appdata/pangolin,gerbil,newt | N/A |
|
|
|
|
---
|
|
|
|
## Dependencies for Next Phase
|
|
|
|
Phase 3 (Authentik) can now use Fossorial tunnels to:
|
|
- Expose Authentik externally without Cloudflare dependency
|
|
- Create secure tunnels for mobile OIDC authentication
|