refactor(rego-tunnel): Replace QEMU VM with native Docker Cisco VPN
Some checks failed
Test / test (push) Has been cancelled

- Switch from linux-vm QEMU image to cisco-vpn native Docker image
- Change port from 8006 to 6080 (noVNC)
- Remove VM-specific config (RAM, CPU, bridges, taps, QEMU)
- Add VPN credential fields (email, password, TOTP, VPN host)
- Add auto-connect and VNC password options
- Update description.md with new documentation
- Simplify Docker requirements (no /dev/kvm needed)

Benefits:
- No QEMU/VM overhead - runs natively in Docker
- Full Cisco Secure Client 5.1.14.145 with GUI
- Auto-login with TOTP support
- Auto-reconnect on disconnect

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-16 19:47:11 +00:00
parent 96153fa557
commit 8523c79999
4 changed files with 127 additions and 304 deletions

View File

@@ -1,179 +1,79 @@
{
"name": "Rego Tunnel",
"available": true,
"port": 8006,
"port": 6080,
"exposable": true,
"dynamic_config": true,
"id": "rego-tunnel",
"description": "Linux VM with Cisco AnyConnect VPN for accessing Rego environments securely.",
"tipi_version": 3,
"version": "latest",
"description": "Cisco Secure Client VPN in Docker with noVNC web UI for accessing Rego environments. No VM overhead.",
"tipi_version": 4,
"version": "5.1.14.145",
"categories": ["utilities"],
"short_desc": "Linux VM VPN tunnel to Rego environments.",
"short_desc": "Cisco VPN tunnel to Rego environments (native Docker, no VM)",
"author": "alexz",
"source": "https://git.alexzaw.dev/alexz/runtipi",
"form_fields": [
{
"type": "number",
"label": "RAM (GB)",
"hint": "RAM to assign to the VM (in gigabytes)",
"placeholder": "8",
"required": true,
"env_variable": "WINDOWS_RAM_GB",
"default": "8"
},
{
"type": "number",
"label": "CPU Cores",
"hint": "CPU cores to assign to the VM",
"placeholder": "4",
"required": true,
"env_variable": "WINDOWS_CPU_CORES",
"default": "4"
},
{
"type": "text",
"label": "VM IP (internal)",
"hint": "Internal VM IP on the tap/bridge network",
"placeholder": "100.100.0.2",
"required": true,
"env_variable": "VM_NET_IP",
"default": "100.100.0.2"
},
{
"type": "text",
"label": "VM MAC",
"hint": "Used for DHCP reservation (VM must use DHCP)",
"placeholder": "52:54:00:12:34:56",
"required": true,
"env_variable": "VM_MAC",
"default": "52:54:00:12:34:56"
},
{
"type": "text",
"label": "Bridge name",
"hint": "Linux bridge created inside the container for VM networking",
"placeholder": "br-rego-vpn",
"required": true,
"env_variable": "BRIDGE_NAME",
"default": "br-rego-vpn"
},
{
"type": "text",
"label": "TAP name",
"hint": "Tap interface name used by QEMU",
"placeholder": "tap0",
"required": true,
"env_variable": "TAP_NAME",
"default": "tap0"
},
{
"type": "ip",
"label": "Bridge CIDR",
"hint": "Bridge address/CIDR assigned inside the container",
"placeholder": "100.100.0.1",
"required": true,
"env_variable": "BRIDGE_CIDR",
"default": "100.100.0.1"
},
{
"type": "text",
"label": "QEMU binary",
"hint": "Override the QEMU system binary (e.g. /usr/bin/qemu-system-amd64). Leave empty for default.",
"placeholder": "/usr/bin/qemu-system-amd64",
"type": "email",
"label": "VPN Email",
"hint": "Email address for VPN SSO login",
"placeholder": "your-email@company.com",
"required": false,
"env_variable": "QEMU_BIN",
"default": "/usr/bin/qemu-system-amd64"
"env_variable": "VPN_EMAIL",
"default": ""
},
{
"type": "text",
"label": "TAP2 name (shared network)",
"hint": "Optional second TAP interface for a second VM NIC. Set to enable NIC2 (e.g. tap1).",
"placeholder": "tap1",
"type": "password",
"label": "VPN Password",
"hint": "Password for VPN SSO login. Leave empty for manual login via noVNC.",
"placeholder": "",
"required": false,
"env_variable": "TAP2_NAME",
"default": "tap1"
"env_variable": "VPN_PASSWORD",
"default": ""
},
{
"type": "text",
"label": "Bridge2 name (shared network)",
"hint": "Optional second Linux bridge for NIC2 (e.g. br-app).",
"placeholder": "br-app",
"label": "TOTP Secret",
"hint": "Base32 encoded TOTP secret for 2FA (from authenticator app setup). Leave empty if not using TOTP.",
"placeholder": "",
"required": false,
"env_variable": "BRIDGE2_NAME",
"default": "br-app"
"env_variable": "VPN_TOTP_SECRET",
"default": ""
},
{
"type": "text",
"label": "Bridge2 uplink interface",
"hint": "If set, bridge NIC2 onto this container interface (e.g. eth0 for 10.x app network, eth1 for 172.x main network).",
"placeholder": "eth0",
"label": "VPN Host",
"hint": "VPN server hostname (for reference)",
"placeholder": "vpn.company.com",
"required": false,
"env_variable": "BRIDGE2_UPLINK_IF",
"default": "eth0"
"env_variable": "VPN_HOST",
"default": ""
},
{
"type": "text",
"label": "Bridge2 CIDR (optional)",
"hint": "Optional IPv4/CIDR for Bridge2. If empty and uplink is set, the bridge inherits the uplink IPv4 address.",
"placeholder": "10.128.13.2/24",
"type": "boolean",
"label": "Auto-Connect on Start",
"hint": "Automatically connect to VPN when container starts (requires credentials above)",
"required": false,
"env_variable": "BRIDGE2_CIDR",
"default": "10.128.13.2/24"
"env_variable": "VPN_AUTO_CONNECT",
"default": false
},
{
"type": "text",
"label": "VM MAC2 (shared network)",
"hint": "Optional MAC for NIC2 (e.g. 52:54:00:12:34:57).",
"placeholder": "52:54:00:12:34:57",
"type": "password",
"label": "VNC Password",
"hint": "Password for noVNC web interface",
"placeholder": "cisco123",
"required": false,
"env_variable": "VM_MAC2",
"default": "52:54:00:12:34:57"
},
{
"type": "ip",
"label": "VM subnet",
"hint": "Subnet that should be NATed out of the container",
"placeholder": "100.100.0.0",
"required": true,
"env_variable": "VM_SUBNET",
"default": "100.100.0.0"
},
{
"type": "ip",
"label": "Target IP (routed via VM)",
"hint": "Traffic to this IP is routed via the VM (VPN inside the VM)",
"placeholder": "10.35.33.230",
"required": true,
"env_variable": "TARGET_IP",
"default": "10.35.33.230"
"env_variable": "VNC_PASSWORD",
"default": "cisco123"
},
{
"type": "text",
"label": "DNS servers",
"hint": "DNS servers offered to the VM via DHCP",
"placeholder": "1.1.1.1,8.8.8.8",
"required": true,
"env_variable": "DNS_SERVERS",
"default": "1.1.1.1,8.8.8.8"
},
{
"type": "text",
"label": "DHCP lease time",
"hint": "Lease duration (dnsmasq format, e.g. 12h)",
"placeholder": "12h",
"required": true,
"env_variable": "LEASE_TIME",
"default": "12h"
},
{
"type": "text",
"label": "Host share directory",
"hint": "Host path mounted into the container at /hostshare and exported into the VM",
"placeholder": "${APP_DATA_DIR}",
"required": true,
"env_variable": "HOSTSHARE_DIR",
"default": "/etc/runtipi/user-config/runtipi/rego-tunnel/shared"
"label": "Basic Auth Users",
"hint": "Traefik basic auth users string (htpasswd format). Use generate-traefik-basicauth.sh to create.",
"placeholder": "user:$$apr1$$hash",
"required": false,
"env_variable": "BASICAUTH_USERS",
"default": ""
}
],
"supported_architectures": ["amd64"]

View File

@@ -3,86 +3,42 @@
"services": [
{
"name": "rego-tunnel",
"image": "git.alexzaw.dev/alexz/linux-vm:latest",
"image": "git.alexzaw.dev/alexz/cisco-vpn:latest",
"environment": [
{
"key": "VM_RAM",
"value": "${WINDOWS_RAM_GB}G"
"key": "VPN_EMAIL",
"value": "${VPN_EMAIL}"
},
{
"key": "VM_CPUS",
"value": "${WINDOWS_CPU_CORES}"
"key": "VPN_PASSWORD",
"value": "${VPN_PASSWORD}"
},
{
"key": "BRIDGE_NAME",
"value": "${BRIDGE_NAME}"
"key": "VPN_TOTP_SECRET",
"value": "${VPN_TOTP_SECRET}"
},
{
"key": "TAP_NAME",
"value": "${TAP_NAME}"
"key": "VPN_HOST",
"value": "${VPN_HOST}"
},
{
"key": "TAP2_NAME",
"value": "${TAP2_NAME}"
"key": "VPN_AUTO_CONNECT",
"value": "${VPN_AUTO_CONNECT}"
},
{
"key": "BRIDGE_CIDR",
"value": "${BRIDGE_CIDR}"
"key": "VNC_PASSWORD",
"value": "${VNC_PASSWORD}"
},
{
"key": "VM_NET_IP",
"value": "${VM_NET_IP}"
},
{
"key": "VM_SUBNET",
"value": "${VM_SUBNET}"
},
{
"key": "TARGET_IP",
"value": "${TARGET_IP}"
},
{
"key": "VM_MAC",
"value": "${VM_MAC}"
},
{
"key": "VM_MAC2",
"value": "${VM_MAC2}"
},
{
"key": "DNS_SERVERS",
"value": "${DNS_SERVERS}"
},
{
"key": "LEASE_TIME",
"value": "${LEASE_TIME}"
},
{
"key": "HOSTSHARE_DIR",
"value": "${HOSTSHARE_DIR}"
},
{
"key": "BRIDGE2_NAME",
"value": "${BRIDGE2_NAME}"
},
{
"key": "BRIDGE2_CIDR",
"value": "${BRIDGE2_CIDR}"
},
{
"key": "BRIDGE2_UPLINK_IF",
"value": "${BRIDGE2_UPLINK_IF}"
},
{
"key": "QEMU_BIN",
"value": "${QEMU_BIN}"
"key": "TZ",
"value": "${TZ}"
}
],
"internalPort": 8006,
"internalPort": 6080,
"volumes": [
{
"hostPath": "/etc/runtipi/user-config/runtipi/rego-tunnel/storage/linux-vm.qcow2",
"containerPath": "/vm/linux-vm.qcow2",
"hostPath": "${APP_DATA_DIR}/config",
"containerPath": "/config",
"readOnly": false,
"shared": false,
"private": false
@@ -93,19 +49,11 @@
"readOnly": false,
"shared": false,
"private": false
},
{
"hostPath": "${HOSTSHARE_DIR}",
"containerPath": "/hostshare",
"readOnly": false,
"shared": false,
"private": false
}
],
"stopGracePeriod": "2m",
"stopGracePeriod": "30s",
"sysctls": {},
"devices": [
"/dev/kvm",
"/dev/net/tun"
],
"privileged": true,
@@ -114,7 +62,7 @@
],
"isMain": true,
"extraLabels": {
"traefik.http.middlewares.rego-tunnel-runtipi-auth.basicauth.users": "alexz:$$2y$$05$$nv5ygL66/LEYut3RBuslFuXBwHIDg1yKFmhB8B4Nyqd8GJnN4gy5u",
"traefik.http.middlewares.rego-tunnel-runtipi-auth.basicauth.users": "${BASICAUTH_USERS}",
"traefik.http.routers.rego-tunnel-runtipi.middlewares": "rego-tunnel-runtipi-auth",
"runtipi.managed": true
}

View File

@@ -1,6 +1,6 @@
services:
rego-tunnel:
image: git.alexzaw.dev/alexz/linux-vm:latest
image: git.alexzaw.dev/alexz/cisco-vpn:latest
restart: unless-stopped
networks:
rego-tunnel_runtipi_network:
@@ -8,41 +8,29 @@ services:
tipi_main_network:
gw_priority: 1
environment:
VM_RAM: ${WINDOWS_RAM_GB}G
VM_CPUS: ${WINDOWS_CPU_CORES}
BRIDGE_NAME: ${BRIDGE_NAME}
TAP_NAME: ${TAP_NAME}
TAP2_NAME: ${TAP2_NAME}
BRIDGE_CIDR: ${BRIDGE_CIDR}
VM_NET_IP: ${VM_NET_IP}
VM_SUBNET: ${VM_SUBNET}
TARGET_IP: ${TARGET_IP}
VM_MAC: ${VM_MAC}
VM_MAC2: ${VM_MAC2}
DNS_SERVERS: ${DNS_SERVERS}
LEASE_TIME: ${LEASE_TIME}
HOSTSHARE_DIR: ${HOSTSHARE_DIR}
BRIDGE2_NAME: ${BRIDGE2_NAME}
BRIDGE2_CIDR: ${BRIDGE2_CIDR}
BRIDGE2_UPLINK_IF: ${BRIDGE2_UPLINK_IF}
QEMU_BIN: ${QEMU_BIN}
VPN_EMAIL: ${VPN_EMAIL}
VPN_PASSWORD: ${VPN_PASSWORD}
VPN_TOTP_SECRET: ${VPN_TOTP_SECRET}
VPN_HOST: ${VPN_HOST}
VPN_AUTO_CONNECT: ${VPN_AUTO_CONNECT}
VNC_PASSWORD: ${VNC_PASSWORD}
TZ: ${TZ}
ports:
- ${APP_PORT}:8006
- ${APP_PORT}:6080
volumes:
- /etc/runtipi/user-config/runtipi/rego-tunnel/storage/linux-vm.qcow2:/vm/linux-vm.qcow2
- ${APP_DATA_DIR}/config:/config
- /etc/runtipi/user-config/runtipi/rego-tunnel/shared:/shared
- ${HOSTSHARE_DIR}:/hostshare
labels:
generated: true
traefik.enable: true
traefik.docker.network: runtipi_tipi_main_network
traefik.http.middlewares.rego-tunnel-runtipi-web-redirect.redirectscheme.scheme: https
traefik.http.services.rego-tunnel-runtipi.loadbalancer.server.port: "8006"
traefik.http.services.rego-tunnel-runtipi.loadbalancer.server.port: "6080"
traefik.http.routers.rego-tunnel-runtipi-insecure.rule: Host(`${APP_DOMAIN}`)
traefik.http.routers.rego-tunnel-runtipi-insecure.entrypoints: web
traefik.http.routers.rego-tunnel-runtipi-insecure.service: rego-tunnel-runtipi
traefik.http.routers.rego-tunnel-runtipi-insecure.middlewares: rego-tunnel-runtipi-web-redirect
traefik.http.middlewares.rego-tunnel-runtipi-auth.basicauth.users: "alexz:$$2y$$05$$nv5ygL66/LEYut3RBuslFuXBwHIDg1yKFmhB8B4Nyqd8GJnN4gy5u"
traefik.http.middlewares.rego-tunnel-runtipi-auth.basicauth.users: "${BASICAUTH_USERS}"
traefik.http.routers.rego-tunnel-runtipi.rule: Host(`${APP_DOMAIN}`)
traefik.http.routers.rego-tunnel-runtipi.entrypoints: websecure
traefik.http.routers.rego-tunnel-runtipi.service: rego-tunnel-runtipi
@@ -53,8 +41,6 @@ services:
cap_add:
- NET_ADMIN
devices:
- /dev/kvm
- /dev/net/tun
privileged: true
stop_grace_period: 2m
sysctls: {}
stop_grace_period: 30s

View File

@@ -1,82 +1,71 @@
<h1 align="center">Windows<br />
<div align="center">
<a href="https://github.com/dockur/windows"><img src="https://github.com/dockur/windows/raw/master/.github/logo.png" title="Logo" style="max-width:100%;" width="128" /></a>
</div>
<div align="center">
# Rego Tunnel - Cisco Secure Client VPN
</div></h1>
Windows in a Docker container.
Run Cisco Secure Client (AnyConnect) with full GUI support in Docker using noVNC.
## Features
- ISO downloader
- KVM acceleration
- Web-based viewer
- **Full Cisco Secure Client 5.1.14.145** with GUI
- VPN, DART, and Posture modules pre-installed
- **Web-based VNC access** via noVNC
- Systemd support for proper service management
- **No QEMU or VM overhead** - runs natively in Docker
- **Auto-login with TOTP support** - fully automated connection
- Auto-reconnect on disconnect
## FAQ
## Quick Start
* ### How do I use it?
1. **Install the app** through Runtipi
2. **Configure credentials** (optional) through app settings for auto-connect
3. **Access the VPN GUI** at `http://<your-server>:6080/vnc.html`
4. Default VNC password: `cisco123`
Very simple! These are the steps:
## Auto-Connect
- Start the container and connect to [port 8006](http://localhost:8006) using your web browser.
For fully automated VPN connection:
- Sit back and relax while the magic happens, the whole installation will be performed fully automatic.
1. Fill in your VPN Email, Password, and TOTP Secret in app settings
2. Enable "Auto-Connect on Start"
3. The container will automatically connect to VPN on startup
- Once you see the desktop, your Windows installation is ready for use.
## Manual Connect
Enjoy your brand new machine, and don't forget to star this repo!
If you prefer manual login:
* ### How do I select the Windows version?
1. Access the noVNC interface at port 6080
2. Use the Cisco Secure Client GUI to connect
3. Enter your credentials manually
By default, Windows 11 will be installed. But you can change that in settings, in order to specify an alternative Windows version to be downloaded:
Select from the values below:
| **Value** | **Description** | **Source** | **Transfer** | **Size** |
|---|---|---|---|---|
| `win11` | Windows 11 Pro | Microsoft | Fast | 6.4 GB |
| `win10` | Windows 10 Pro | Microsoft | Fast | 5.8 GB |
| `ltsc10` | Windows 10 LTSC | Microsoft | Fast | 4.6 GB |
| `win81` | Windows 8.1 Pro | Microsoft | Fast | 4.2 GB |
| `win7` | Windows 7 SP1 | Bob Pony | Medium | 3.0 GB |
| `vista` | Windows Vista SP2 | Bob Pony | Medium | 3.6 GB |
| `winxp` | Windows XP SP3 | Bob Pony | Medium | 0.6 GB |
||||||
| `2022` | Windows Server 2022 | Microsoft | Fast | 4.7 GB |
| `2019` | Windows Server 2019 | Microsoft | Fast | 5.3 GB |
| `2016` | Windows Server 2016 | Microsoft | Fast | 6.5 GB |
| `2012` | Windows Server 2012 R2 | Microsoft | Fast | 4.3 GB |
| `2008` | Windows Server 2008 R2 | Microsoft | Fast | 3.0 GB |
||||||
| `core11` | Tiny 11 Core | Archive.org | Slow | 2.1 GB |
| `tiny11` | Tiny 11 | Archive.org | Slow | 3.8 GB |
| `tiny10` | Tiny 10 | Archive.org | Slow | 3.6 GB |
* ### How do I connect using RDP?
The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example.
So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `docker` and by leaving the password empty.
There is a good RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store. One for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) is in the Apple Store. For Linux you can use [rdesktop](http://www.rdesktop.org/) and for Windows you don't need to install anything as it is already ships as part of the operating system.
* ### How do I verify if my system supports KVM?
To verify if your system supports KVM, run the following commands:
## VPN CLI (inside container)
```bash
sudo apt install cpu-checker
sudo kvm-ok
# Connect to VPN
docker exec -it rego-tunnel /opt/cisco/secureclient/bin/vpn connect <server>
# Check status
docker exec -it rego-tunnel /opt/cisco/secureclient/bin/vpn state
# Disconnect
docker exec -it rego-tunnel /opt/cisco/secureclient/bin/vpn disconnect
```
If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS.
## Troubleshooting
* ### Is this project legal?
### VPN connects but immediately disconnects
Check if the DNS files are writable. Restart the container if needed.
Yes, this project contains only open-source code and does not distribute any copyrighted material. Any product keys found in the code are just generic placeholders provided by Microsoft for trial purposes. So under all applicable laws, this project would be considered legal.
### "Unable to start VA" error
This usually means the DNS files are read-only. Restart the container.
## Disclaimer
### noVNC not accessible
Check if the VNC service is running:
```bash
docker exec rego-tunnel systemctl status vnc.service
```
The product names, logos, brands, and other trademarks referred to within this project are the property of their respective trademark holders. This project is not affiliated, sponsored, or endorsed by Microsoft Corporation.
## Technical Details
The container uses:
- `--privileged` mode for systemd and DNS mount manipulation
- `NET_ADMIN` capability for VPN tunnel creation
- `/dev/net/tun` device for the VPN tunnel
- Ports: 6080 (noVNC web UI), 5901 (VNC)