Documents architecture, network configuration, host setup, files, Windows VM config, troubleshooting, and maintenance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rego-Tunnel VPN Bridge
This app runs a Windows VM inside a Docker container with Cisco AnyConnect VPN, providing transparent access to VPN-protected resources (IBM i at 10.35.33.230) from the local network.
Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ Laptop (192.168.0.230) │
│ Route: 172.31.0.0/24 via 192.168.0.150 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Linux Host (192.168.0.150 / 192.168.1.150) │
│ │
│ rego-routing.service: │
│ - Routes 172.32.0.0/24 and 10.35.33.0/24 via 172.31.0.10 │
│ - Removes Docker nft isolation rules for 172.31.0.10 │
│ - DOCKER-USER iptables rules for forwarding │
│ │
│ Bridge: br-vpn-rego (172.31.0.1/24) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Container: rego-tunnel (172.31.0.10) │
│ │
│ start.sh: │
│ - socat: port 2222 → VM:2222 (SSH to VM) │
│ - DNAT: ports 22,23,446,448,449,8470-8476,2000-2020,3000-3020, │
│ 10000-10020,36000-36010 → VM │
│ - MASQUERADE for docker bridge │
│ │
│ Internal docker bridge: 172.32.0.1/24 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Windows VM (172.32.0.20) │
│ │
│ SSH Server: port 2222 │
│ Cisco AnyConnect VPN: connected to corporate network │
│ VPN IP: 10.215.x.x │
│ │
│ Portproxy rules (persistent): │
│ - 0.0.0.0:22 → 10.35.33.230:22 │
│ - 0.0.0.0:23 → 10.35.33.230:23 │
│ - 0.0.0.0:446,448,449 → 10.35.33.230:* │
│ - 0.0.0.0:8470-8476 → 10.35.33.230:* │
│ - 0.0.0.0:2000-2020 → 10.35.33.230:* │
│ - 0.0.0.0:3000-3020 → 10.35.33.230:* │
│ - 0.0.0.0:10000-10020 → 10.35.33.230:* │
│ - 0.0.0.0:36000-36010 → 10.35.33.230:* │
│ │
│ vpn-login.js: │
│ - Auto-login to Cisco AnyConnect via WebView DevTools │
│ - TOTP authentication │
│ - Watchdog: monitors VPN and reconnects if dropped │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ IBM i (10.35.33.230) │
│ Via Cisco VPN tunnel │
└─────────────────────────────────────────────────────────────────────────┘
Network Configuration
IP Addresses
| Component | IP Address |
|---|---|
| Container external (br-vpn-rego) | 172.31.0.10 |
| Container internal bridge | 172.32.0.1 |
| Windows VM | 172.32.0.20 |
| IBM i (via VPN) | 10.35.33.230 |
Ports
| Port | Destination | Purpose |
|---|---|---|
| 2222 | VM SSH (2222) | SSH access to Windows VM |
| 22 | IBM i (via portproxy) | SSH to IBM i |
| 23 | IBM i (via portproxy) | Telnet to IBM i |
| 446,448,449 | IBM i (via portproxy) | IBM i services |
| 8470-8476 | IBM i (via portproxy) | IBM i data ports |
| 2000-2020 | IBM i (via portproxy) | Additional ports |
| 3000-3020 | IBM i (via portproxy) | Additional ports |
| 10000-10020 | IBM i (via portproxy) | Additional ports |
| 36000-36010 | IBM i (via portproxy) | Additional ports |
| 8006 | Container | Web-based Windows viewer |
Host Configuration
Systemd Service: rego-routing.service
Location: /etc/systemd/system/rego-routing.service
This service runs after docker.service and:
- Adds routes for 172.32.0.0/24 and 10.35.33.0/24 via 172.31.0.10
- Adds DOCKER-USER iptables rules for forwarding
- Removes Docker's nft isolation rules that block external access to 172.31.0.10
# Check status
sudo systemctl status rego-routing.service
# Restart if needed
sudo systemctl restart rego-routing.service
Client Route (Windows Laptop)
Add a persistent route to reach the container network:
route add 172.31.0.0 mask 255.255.255.0 192.168.0.150 -p
Where 192.168.0.150 is the Linux host IP.
Files
vpn_scripts/start.sh
Startup script that runs before the Windows VM entry.sh:
- Installs required packages (socat, openssh-client, netcat-openbsd)
- Sets up SSH key for VM access
- Waits for Windows VM to boot
- Configures iptables MASQUERADE and FORWARD rules
- Sets up socat for SSH forwarding (port 2222)
- Configures DNAT rules for all IBM i ports
Important: Uses return 0 (not exit 0) at the end because it's sourced.
vpn_scripts/vpn-login.js
Automated Cisco AnyConnect VPN login:
- Connects via WebView DevTools protocol (port 9222)
- Handles Microsoft/ADFS authentication
- Generates TOTP codes for 2FA
- Watchdog mode: monitors VPN every 2 minutes, reconnects if dropped
vpn_scripts/id_ed25519-lenovo
SSH private key for accessing the Windows VM from the container.
Windows VM Configuration
SSH Server
Windows OpenSSH is configured to listen on port 2222 (not 22) to allow port 22 for IBM i portproxy.
Config: C:\ProgramData\ssh\sshd_config
Port 2222
Portproxy Rules
Portproxy rules forward IBM i ports through the VPN. These are persistent (stored in registry).
# View all portproxy rules
netsh interface portproxy show all
# Add a rule
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=22 connectaddress=10.35.33.230 connectport=22
# Delete all rules
netsh interface portproxy reset
Rules are defined in: /etc/runtipi/user-config/runtipi/rego-tunnel/port-proxy.txt
IP Helper Service
The IP Helper service (iphlpsvc) must be running for portproxy to work:
net start iphlpsvc
User Config
Location: /etc/runtipi/user-config/runtipi/rego-tunnel/docker-compose.yml
networks:
vpn_static-rego:
driver: bridge
driver_opts:
com.docker.network.bridge.name: "br-vpn-rego"
ipam:
config:
- subnet: 172.31.0.0/24
services:
rego-tunnel:
entrypoint: ["/bin/bash", "-c", "source /vpn_scripts/start.sh; exec /run/entry.sh"]
sysctls:
- net.ipv4.conf.all.rp_filter=0
- net.ipv4.conf.default.rp_filter=0
cap_add:
- NET_ADMIN
environment:
- VM_NET_IP=172.32.0.20
volumes:
- /etc/runtipi/repos/runtipi/apps/rego-tunnel/vpn_scripts:/vpn_scripts:ro
networks:
vpn_static-rego:
ipv4_address: 172.31.0.10
Troubleshooting
Container won't start / restarts immediately
Check if start.sh has exit 0 instead of return 0 at the end. Since it's sourced, exit terminates the parent shell.
Can't reach container from laptop
- Check route on laptop:
route print | findstr 172.31 - Check rego-routing.service:
sudo systemctl status rego-routing.service - Check if Docker nft rules are blocking:
sudo nft list ruleset | grep 172.31
Portproxy not working
- Restart IP Helper:
net stop iphlpsvc && net start iphlpsvc - Check if SSH is on port 2222:
netstat -an | findstr :22 - Verify portproxy rules:
netsh interface portproxy show all
VPN not connecting
- Check vpn-login.js logs in Windows VM
- Verify time sync (TOTP requires accurate time)
- Check if VPN credentials in vpn-login.js are correct
Bridge name too long error
Linux bridge names are limited to 15 characters. "br-vpn-static-rego" (18 chars) won't work; use "br-vpn-rego" (11 chars).
Maintenance
Updating vpn_scripts
- Edit files in
/etc/runtipi/repos/runtipi/apps/rego-tunnel/vpn_scripts/ - Commit and push to git
- Run
sudo ./runtipi-cli appstore update - Restart app:
sudo ./runtipi-cli app stop rego-tunnel:runtipi && sudo ./runtipi-cli app start rego-tunnel:runtipi
Updating portproxy rules
- Edit
/etc/runtipi/user-config/runtipi/rego-tunnel/port-proxy.txt - SSH to VM:
ssh -p 2222 docker@172.31.0.10 - Reset and re-apply:
netsh interface portproxy resetthen run the commands from port-proxy.txt