Files
runtipi/apps/rego-tunnel/metadata/README.md
alexz 154b2bdd2c
Some checks failed
Test / test (push) Has been cancelled
upload current sources
2025-12-24 19:17:46 +00:00

11 KiB
Executable File

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:

  1. Adds routes for 172.32.0.0/24 and 10.35.33.0/24 via 172.31.0.10
  2. Adds DOCKER-USER iptables rules for forwarding
  3. 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

  1. Check route on laptop: route print | findstr 172.31
  2. Check rego-routing.service: sudo systemctl status rego-routing.service
  3. Check if Docker nft rules are blocking: sudo nft list ruleset | grep 172.31

Portproxy not working

  1. Restart IP Helper: net stop iphlpsvc && net start iphlpsvc
  2. Check if SSH is on port 2222: netstat -an | findstr :22
  3. Verify portproxy rules: netsh interface portproxy show all

VPN not connecting

  1. Check vpn-login.js logs in Windows VM
  2. Verify time sync (TOTP requires accurate time)
  3. 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

  1. Edit files in /etc/runtipi/repos/runtipi/apps/rego-tunnel/vpn_scripts/
  2. Commit and push to git
  3. Run sudo ./runtipi-cli appstore update
  4. Restart app: sudo ./runtipi-cli app stop rego-tunnel:runtipi && sudo ./runtipi-cli app start rego-tunnel:runtipi

Updating portproxy rules

  1. Edit /etc/runtipi/user-config/runtipi/rego-tunnel/port-proxy.txt
  2. SSH to VM: ssh -p 2222 docker@172.31.0.10
  3. Reset and re-apply: netsh interface portproxy reset then run the commands from port-proxy.txt