diff --git a/apps/rego-tunnel/shared/init-rego.sh b/apps/rego-tunnel/shared/init-rego.sh deleted file mode 100644 index 6662c28..0000000 --- a/apps/rego-tunnel/shared/init-rego.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -# Rego Tunnel Init Script -# Combines: -# 1. DNS unmount fix (from cisco-vpn) - allows VPN to modify /etc/resolv.conf and /etc/hosts -# 2. Basic network setup (IP forwarding) -# 3. Starts systemd - -set -e - -echo "[init-rego] Starting Rego Tunnel initialization..." - -# ============================================ -# 1. Fix Docker's read-only bind mounts -# ============================================ -echo "[init-rego] Fixing DNS bind mounts..." - -# Backup current DNS config -cp /etc/resolv.conf /tmp/resolv.conf.bak 2>/dev/null || true -cp /etc/hosts /tmp/hosts.bak 2>/dev/null || true - -# Unmount Docker's bind mounts (required for VPN to modify DNS) -umount /etc/resolv.conf 2>/dev/null || true -umount /etc/hosts 2>/dev/null || true - -# Restore DNS config as regular writable files -cat /tmp/resolv.conf.bak > /etc/resolv.conf 2>/dev/null || echo "nameserver 8.8.8.8" > /etc/resolv.conf -cat /tmp/hosts.bak > /etc/hosts 2>/dev/null || echo "127.0.0.1 localhost" > /etc/hosts - -echo "[init-rego] DNS files are now writable" - -# ============================================ -# 2. Network Setup -# ============================================ -echo "[init-rego] Setting up network..." - -# Enable IP forwarding -echo 1 > /proc/sys/net/ipv4/ip_forward -echo "[init-rego] IP forwarding enabled" - -# Note: NAT/forwarding rules for VPN traffic are set up by the cisco-vpn script -# AFTER the VPN connects (it needs to know the VPN interface name) - -# ============================================ -# 3. Make shared scripts executable -# ============================================ -if [ -d /shared ]; then - chmod +x /shared/*.sh 2>/dev/null || true - chmod +x /shared/cisco-vpn 2>/dev/null || true - echo "[init-rego] Shared scripts made executable" -fi - -# ============================================ -# 4. Start systemd -# ============================================ -echo "[init-rego] Starting systemd..." -exec /sbin/init diff --git a/apps/rego-tunnel/shared/setup-network.sh b/apps/rego-tunnel/shared/setup-network.sh deleted file mode 100644 index 8ecd67c..0000000 --- a/apps/rego-tunnel/shared/setup-network.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/bash -# Setup TAP/Bridge networking for QEMU VM -# Defaults: -# BRIDGE_NAME=br-rego-vpn -# TAP_NAME=tap0 -# BRIDGE_CIDR=100.100.0.1/24 -# VM_NET_IP=100.100.0.2 -# VM_SUBNET=100.100.0.0/24 - -set -e - -BRIDGE_NAME="${BRIDGE_NAME:-br-rego-vpn}" -TAP_NAME="${TAP_NAME:-tap0}" -BRIDGE_CIDR="${BRIDGE_CIDR:-100.100.0.1}" -VM_NET_IP="${VM_NET_IP:-100.100.0.2}" -VM_SUBNET="${VM_SUBNET:-100.100.0.0}" -TARGET_IP="${TARGET_IP:-10.35.33.230}" - -# Optional second bridge/tap for a second VM NIC (pure L2 with the container). -# This is opt-in: set BRIDGE2_NAME and TAP2_NAME (and optionally BRIDGE2_CIDR). -BRIDGE2_NAME="${BRIDGE2_NAME:-}" -TAP2_NAME="${TAP2_NAME:-}" -BRIDGE2_CIDR="${BRIDGE2_CIDR:-}" -BRIDGE2_UPLINK_IF="${BRIDGE2_UPLINK_IF:-}" - -if [[ "$BRIDGE_CIDR" != */* ]]; then - BRIDGE_CIDR="$BRIDGE_CIDR/24" -fi - -if [[ "$VM_SUBNET" != */* ]]; then - VM_SUBNET="$VM_SUBNET/24" -fi - -# Pick the outbound interface based on the container's default route. -# (In Docker, this is not always eth1 when multiple networks are attached.) -WAN_IF="$(ip route show default 0.0.0.0/0 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')" -if [ -z "${WAN_IF}" ]; then - WAN_IF="eth1" -fi - -# Ensure bridge exists -if ! ip link show "$BRIDGE_NAME" &>/dev/null; then - ip link add "$BRIDGE_NAME" type bridge -fi - -# Ensure bridge has address and is up -ip addr show dev "$BRIDGE_NAME" | grep -qF "$BRIDGE_CIDR" || ip addr add "$BRIDGE_CIDR" dev "$BRIDGE_NAME" 2>/dev/null || true -ip link set "$BRIDGE_NAME" up - -# Ensure TAP exists -if ! ip link show "$TAP_NAME" &>/dev/null; then - ip tuntap add "$TAP_NAME" mode tap -fi - -# Ensure TAP is attached and up -ip link set "$TAP_NAME" master "$BRIDGE_NAME" 2>/dev/null || true -ip link set "$TAP_NAME" up - -# Optional second bridge/tap (no NAT rules are applied here) -if [ -n "$BRIDGE2_NAME" ] || [ -n "$TAP2_NAME" ]; then - if [ -z "$BRIDGE2_NAME" ] || [ -z "$TAP2_NAME" ]; then - echo "[rego-tunnel] WARN: BRIDGE2_NAME and TAP2_NAME must both be set to enable the second bridge" - else - # Optionally bridge an existing container uplink into BRIDGE2 (e.g. eth0/eth1) - # so the VM NIC shares the same L2 network as that uplink. - if [ -n "$BRIDGE2_UPLINK_IF" ]; then - if ! ip link show "$BRIDGE2_UPLINK_IF" &>/dev/null; then - echo "[rego-tunnel] WARN: BRIDGE2_UPLINK_IF=$BRIDGE2_UPLINK_IF not found; skipping uplink bridging" - BRIDGE2_UPLINK_IF="" - fi - fi - - if ! ip link show "$BRIDGE2_NAME" &>/dev/null; then - ip link add "$BRIDGE2_NAME" type bridge - fi - ip link set "$BRIDGE2_NAME" up - - # If an uplink interface is provided, move its IPv4 address to the bridge. - # This keeps the container reachable on that network while allowing the VM - # to participate in the same L2 broadcast domain. - if [ -n "$BRIDGE2_UPLINK_IF" ]; then - UPLINK_CIDR="$(ip -o -4 addr show dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{print $4}' | head -n1)" - UPLINK_DEFAULT_GW="$(ip route show default dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{print $3}' | head -n1)" - UPLINK_DEFAULT_METRIC="$(ip route show default dev "$BRIDGE2_UPLINK_IF" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="metric"){print $(i+1); exit}}')" - if [ -z "$BRIDGE2_CIDR" ] && [ -n "$UPLINK_CIDR" ]; then - BRIDGE2_CIDR="$UPLINK_CIDR" - fi - if [ -n "$BRIDGE2_CIDR" ]; then - if [[ "$BRIDGE2_CIDR" != */* ]]; then - BRIDGE2_CIDR="$BRIDGE2_CIDR/24" - fi - ip addr show dev "$BRIDGE2_NAME" | grep -qF "$BRIDGE2_CIDR" || ip addr add "$BRIDGE2_CIDR" dev "$BRIDGE2_NAME" 2>/dev/null || true - fi - # Remove IP from uplink and enslave it into the bridge - ip addr flush dev "$BRIDGE2_UPLINK_IF" 2>/dev/null || true - ip link set "$BRIDGE2_UPLINK_IF" master "$BRIDGE2_NAME" 2>/dev/null || true - ip link set "$BRIDGE2_UPLINK_IF" up 2>/dev/null || true - - # If the uplink carried the container default route, it may have been removed - # by the address flush. Restore it on the bridge. - if [ -n "$UPLINK_DEFAULT_GW" ]; then - if ip route show default 2>/dev/null | grep -q '^default '; then - ip route replace default via "$UPLINK_DEFAULT_GW" dev "$BRIDGE2_NAME" ${UPLINK_DEFAULT_METRIC:+metric "$UPLINK_DEFAULT_METRIC"} 2>/dev/null || true - else - ip route add default via "$UPLINK_DEFAULT_GW" dev "$BRIDGE2_NAME" ${UPLINK_DEFAULT_METRIC:+metric "$UPLINK_DEFAULT_METRIC"} 2>/dev/null || true - fi - fi - fi - - if ! ip link show "$TAP2_NAME" &>/dev/null; then - ip tuntap add "$TAP2_NAME" mode tap - fi - ip link set "$TAP2_NAME" master "$BRIDGE2_NAME" 2>/dev/null || true - ip link set "$TAP2_NAME" up - echo "[rego-tunnel] Second bridge enabled: $BRIDGE2_NAME (tap $TAP2_NAME)${BRIDGE2_UPLINK_IF:+ uplink $BRIDGE2_UPLINK_IF}" - fi -fi - -# Enable IP forwarding -echo 1 > /proc/sys/net/ipv4/ip_forward - -# Setup NAT/masquerade for outbound traffic from VM -iptables -t nat -C POSTROUTING -s "$VM_SUBNET" -o "$WAN_IF" -j MASQUERADE 2>/dev/null || \ - iptables -t nat -A POSTROUTING -s "$VM_SUBNET" -o "$WAN_IF" -j MASQUERADE - -# Ensure forwarding between the VM bridge and outbound interface -iptables -C FORWARD -i "$BRIDGE_NAME" -o "$WAN_IF" -j ACCEPT 2>/dev/null || \ - iptables -A FORWARD -i "$BRIDGE_NAME" -o "$WAN_IF" -j ACCEPT -iptables -C FORWARD -i "$WAN_IF" -o "$BRIDGE_NAME" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \ - iptables -A FORWARD -i "$WAN_IF" -o "$BRIDGE_NAME" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - -# Forward traffic destined for VPN networks to VM (TARGET_IP defaults to IBM i) -# The VM will route this through its VPN tunnel -iptables -C FORWARD -d "$TARGET_IP" -j ACCEPT 2>/dev/null || iptables -A FORWARD -d "$TARGET_IP" -j ACCEPT -iptables -C FORWARD -s "$TARGET_IP" -j ACCEPT 2>/dev/null || iptables -A FORWARD -s "$TARGET_IP" -j ACCEPT - -# Route to TARGET_IP through VM -ip route add "$TARGET_IP" via "$VM_NET_IP" 2>/dev/null || true - -echo "Network setup complete" -echo "Bridge: $BRIDGE_NAME = $BRIDGE_CIDR" -echo "TAP: $TAP_NAME attached to $BRIDGE_NAME" -echo "Route: $TARGET_IP via $VM_NET_IP (VM)" -echo "Outbound interface: ${WAN_IF}" - -if [ -n "$BRIDGE2_NAME" ] && [ -n "$TAP2_NAME" ]; then - echo "Bridge2: $BRIDGE2_NAME${BRIDGE2_CIDR:+ = $BRIDGE2_CIDR}" - echo "TAP2: $TAP2_NAME attached to $BRIDGE2_NAME" -fi \ No newline at end of file diff --git a/apps/rego-tunnel/shared/start-dnsmasq.sh b/apps/rego-tunnel/shared/start-dnsmasq.sh deleted file mode 100644 index 2b2c3b8..0000000 --- a/apps/rego-tunnel/shared/start-dnsmasq.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -euo pipefail - -BRIDGE_NAME="${BRIDGE_NAME:-br-rego-vpn}" -BRIDGE_CIDR="${BRIDGE_CIDR:-100.100.0.1}" -VM_NET_IP="${VM_NET_IP:-100.100.0.2}" -VM_MAC="${VM_MAC:-52:54:00:12:34:56}" - -LEASE_TIME="${LEASE_TIME:-12h}" -DNS_SERVERS="${DNS_SERVERS:-1.1.1.1,8.8.8.8}" - -if [[ "$BRIDGE_CIDR" != */* ]]; then - BRIDGE_CIDR="$BRIDGE_CIDR/24" -fi - -GATEWAY_IP="${BRIDGE_CIDR%%/*}" - -mkdir -p /etc/dnsmasq.d - -cat > /etc/dnsmasq.d/rego.conf < ${VM_NET_IP}" -exec dnsmasq --no-daemon --conf-file=/etc/dnsmasq.d/rego.conf diff --git a/apps/rego-tunnel/shared/start-vm.sh b/apps/rego-tunnel/shared/start-vm.sh deleted file mode 100644 index 6ba3031..0000000 --- a/apps/rego-tunnel/shared/start-vm.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# If provided, extract ssh.zip to /root/.ssh (not baked into the image) -SSH_ZIP_PATH="/shared/ssh.zip" -SSH_ZIP_DEST="/root/.ssh" - -if [ -f "$SSH_ZIP_PATH" ]; then - mkdir -p "$SSH_ZIP_DEST" - chmod 700 "$SSH_ZIP_DEST" - - echo "[rego-tunnel] Extracting $SSH_ZIP_PATH -> $SSH_ZIP_DEST" - # Exclude editor swap/backup files; overwrite existing. - 7z x -y -aoa -o"$SSH_ZIP_DEST" "$SSH_ZIP_PATH" \ - -x!*.swp -x!*.swo -x!*.swx -x!*~ -x!.DS_Store >/dev/null - - find "$SSH_ZIP_DEST" -type d -exec chmod 700 {} \; - find "$SSH_ZIP_DEST" -type f -exec chmod 600 {} \; -else - echo "[rego-tunnel] No $SSH_ZIP_PATH found; skipping SSH zip extraction" -fi - -# Wait for network setup -sleep 2 - -TAP_NAME="${TAP_NAME:-tap0}" - -# Optional: provide a dedicated 9p export for host app-data (bind-mounted into the container at /shared/app-data) -TSCLIENT_PATH="/hostshare" -TSCLIENT_TAG="${TSCLIENT_TAG:-TSCLIENT}" -SHARED_TAG="${SHARED_TAG:-shared}" - -# Ensure the VM auto-mounts the 9p shares without manual steps. -# This edits the QCOW2 from the outside (idempotent) before QEMU boots. -AUTO_MOUNT_9P="${AUTO_MOUNT_9P:-1}" -if [ "$AUTO_MOUNT_9P" = "1" ]; then - QCOW2_PATH="/vm/linux-vm.qcow2" - NBD_DEV="${NBD_DEV:-/dev/nbd0}" - VMROOT_MNT="/mnt/vmroot" - - if [ -e "$QCOW2_PATH" ] && [ -e "$NBD_DEV" ]; then - echo "[rego-tunnel] Ensuring guest fstab mounts 9p tags ($SHARED_TAG, $TSCLIENT_TAG)" - modprobe nbd max_part=16 >/dev/null 2>&1 || true - qemu-nbd --disconnect "$NBD_DEV" >/dev/null 2>&1 || true - qemu-nbd --connect "$NBD_DEV" "$QCOW2_PATH" - sleep 1 - - # In containers, the kernel may create sysfs partition entries but not - # auto-create the corresponding /dev/nbd0p* nodes. Create them if missing. - base_dev="$(basename "$NBD_DEV")" - for sysfs_dev in /sys/class/block/${base_dev}p*; do - [ -e "$sysfs_dev" ] || continue - part_name="$(basename "$sysfs_dev")" - devnode="/dev/$part_name" - [ -e "$devnode" ] && continue - if [ -r "$sysfs_dev/dev" ]; then - IFS=: read -r major minor < "$sysfs_dev/dev" || true - if [ -n "${major:-}" ] && [ -n "${minor:-}" ]; then - mknod "$devnode" b "$major" "$minor" 2>/dev/null || true - chmod 660 "$devnode" 2>/dev/null || true - fi - fi - done - - mkdir -p "$VMROOT_MNT" - ROOT_PART="" - for part in "${NBD_DEV}"p*; do - [ -e "$part" ] || continue - # Try mount and detect a Linux root by presence of /etc/fstab and /etc/os-release - if mount "$part" "$VMROOT_MNT" >/dev/null 2>&1; then - if [ -d "$VMROOT_MNT/etc" ] && { [ -f "$VMROOT_MNT/etc/os-release" ] || [ -f "$VMROOT_MNT/usr/lib/os-release" ] || [ -f "$VMROOT_MNT/usr/share/os-release" ]; }; then - ROOT_PART="$part" - break - fi - umount "$VMROOT_MNT" >/dev/null 2>&1 || true - fi - done - - if [ -n "$ROOT_PART" ]; then - # already mounted from loop above - mkdir -p "$VMROOT_MNT/shared" "$VMROOT_MNT/hostshare" - - FSTAB="$VMROOT_MNT/etc/fstab" - # Add entries only if missing - grep -qE "^[[:space:]]*${SHARED_TAG}[[:space:]]+" "$FSTAB" || echo "${SHARED_TAG} /shared 9p trans=virtio,version=9p2000.L,msize=262144,_netdev,nofail,x-systemd.automount 0 0" >> "$FSTAB" - grep -qE "^[[:space:]]*${TSCLIENT_TAG}[[:space:]]+" "$FSTAB" || echo "${TSCLIENT_TAG} /hostshare 9p trans=virtio,version=9p2000.L,msize=262144,_netdev,nofail,x-systemd.automount 0 0" >> "$FSTAB" - - umount "$VMROOT_MNT" >/dev/null 2>&1 || true - else - echo "[rego-tunnel] WARN: could not locate guest root partition; skipping auto-mount setup" - lsblk -fp "$NBD_DEV" 2>/dev/null || true - blkid "$NBD_DEV"* 2>/dev/null || true - fi - - qemu-nbd --disconnect "$NBD_DEV" >/dev/null 2>&1 || true - else - echo "[rego-tunnel] WARN: missing $QCOW2_PATH or $NBD_DEV; skipping auto-mount setup" - fi -fi - -exec qemu-system-x86_64 \ - -enable-kvm \ - -cpu host \ - -m ${VM_RAM:-8G} \ - -smp ${VM_CPUS:-4} \ - -hda /vm/linux-vm.qcow2 \ - -fsdev local,id=fsdev0,path=/shared,security_model=none,multidevs=remap \ - -device virtio-9p-pci,fsdev=fsdev0,mount_tag="$SHARED_TAG" \ - -fsdev local,id=fsdev1,path="$TSCLIENT_PATH",security_model=none,multidevs=remap \ - -device virtio-9p-pci,fsdev=fsdev1,mount_tag="$TSCLIENT_TAG" \ - -netdev tap,id=net0,ifname="$TAP_NAME",script=no,downscript=no \ - -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \ - -vnc :0 \ - -vga virtio \ - -usb \ - -device usb-tablet diff --git a/apps/rego-tunnel/shared/supervisord.conf b/apps/rego-tunnel/shared/supervisord.conf deleted file mode 100644 index 95ac431..0000000 --- a/apps/rego-tunnel/shared/supervisord.conf +++ /dev/null @@ -1,46 +0,0 @@ -[supervisord] -nodaemon=true -logfile=/var/log/supervisord.log - -[program:network-setup] -command=/usr/local/bin/setup-network.sh -autostart=true -autorestart=false -startsecs=0 -priority=1 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:dnsmasq] -command=/usr/local/bin/start-dnsmasq.sh -autostart=true -autorestart=true -priority=5 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:sshd] -command=/usr/sbin/sshd -D -autostart=true -autorestart=true -priority=10 - -[program:qemu] -command=/usr/local/bin/start-vm.sh -autostart=true -autorestart=true -priority=20 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 - -[program:novnc] -command=/usr/bin/websockify --web /usr/share/novnc 8006 localhost:5900 -autostart=true -autorestart=true -priority=30 diff --git a/apps/rego-tunnel/shared/xstartup b/apps/rego-tunnel/shared/xstartup deleted file mode 100644 index d72d626..0000000 --- a/apps/rego-tunnel/shared/xstartup +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# VNC xstartup - launches terminal with cisco-vpn script -# This runs inside the VNC session - -unset SESSION_MANAGER -unset DBUS_SESSION_BUS_ADDRESS - -export XDG_RUNTIME_DIR=/tmp/runtime-root -mkdir -p $XDG_RUNTIME_DIR -chmod 700 $XDG_RUNTIME_DIR - -# GPU/WebKit workarounds for Cisco UI -export GDK_BACKEND=x11 -export WEBKIT_DISABLE_DMABUF_RENDERER=1 - -# Start dbus session -[ -x /usr/bin/dbus-launch ] && eval $(dbus-launch --sh-syntax --exit-with-session) - -# Start window manager -openbox & -sleep 2 - -# Make sure the script is executable -chmod +x /shared/cisco-vpn 2>/dev/null || true - -# Start xterm with the cisco-vpn script -# The script handles everything: vpnagentd, vpnui, auto-login, forwarding -xterm -fa 'Monospace' -fs 11 -bg black -fg white -geometry 130x45+10+10 \ - -title "Rego VPN Terminal" \ - -e "bash -c '/shared/cisco-vpn; exec bash'" & - -wait diff --git a/apps/rego-tunnel/vpn_scripts-not-used/01_install-nodejs.ps1 b/apps/rego-tunnel/vpn_scripts-not-used/01_install-nodejs.ps1 deleted file mode 100755 index bd59882..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/01_install-nodejs.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -# Install Node.js on Windows -# Run as Administrator in PowerShell - -$Username = if ($env:REGO_USER) { $env:REGO_USER } else { $env:USERNAME } -$nodeVersion = "22.9.0" -$nodeUrl = "https://nodejs.org/dist/v$nodeVersion/node-v$nodeVersion-x64.msi" -$installerPath = "$env:TEMP\node-installer.msi" - -Write-Host "Downloading Node.js v$nodeVersion..." -ForegroundColor Cyan -Invoke-WebRequest -Uri $nodeUrl -OutFile $installerPath - -Write-Host "Installing Node.js..." -ForegroundColor Cyan -Start-Process msiexec.exe -Wait -ArgumentList "/i `"$installerPath`" /quiet /norestart" - -# Refresh PATH -$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") - -Write-Host "Verifying installation..." -ForegroundColor Cyan -node --version -npm --version - -Write-Host "Node.js installed successfully!" -ForegroundColor Green - -# Cleanup -Remove-Item $installerPath -Force - -Write-Host "" -Write-Host "Next steps:" -ForegroundColor Yellow -Write-Host "1. Copy vpn-login.js, socks5.js, vpn.bat to C:\Users\$Username\vpn_scripts\" -Write-Host "2. Open CMD in C:\Users\$Username\vpn_scripts\ and run: npm install ws otplib" -Write-Host "3. Add vpn.bat shortcut to shell:startup folder" diff --git a/apps/rego-tunnel/vpn_scripts-not-used/02_setup-autologin-sshd.ps1 b/apps/rego-tunnel/vpn_scripts-not-used/02_setup-autologin-sshd.ps1 deleted file mode 100755 index dac517a..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/02_setup-autologin-sshd.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -# Setup OpenSSH Server and Auto-Login -# Run as Administrator in PowerShell - -$Username = if ($env:REGO_USER) { $env:REGO_USER } else { $env:USERNAME } -$Password = if ($env:REGO_PASS) { $env:REGO_PASS } else { "admin" } - -Write-Host "=== Setting up OpenSSH Server ===" -ForegroundColor Cyan -Write-Host "Using username: $Username" -ForegroundColor Yellow - -# Install OpenSSH Server -$sshCapability = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*' -if ($sshCapability.State -ne 'Installed') { - Write-Host "Installing OpenSSH Server..." -ForegroundColor Yellow - Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 -} else { - Write-Host "OpenSSH Server already installed" -ForegroundColor Green -} - -# Start and enable SSH service -Write-Host "Starting SSH service..." -ForegroundColor Yellow -Start-Service sshd -Set-Service -Name sshd -StartupType 'Automatic' - -# Configure firewall -$fwRule = Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue -if (-not $fwRule) { - Write-Host "Adding firewall rule..." -ForegroundColor Yellow - New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -} - -Write-Host "OpenSSH Server configured!" -ForegroundColor Green - -Write-Host "" -Write-Host "=== Setting up Auto-Login ===" -ForegroundColor Cyan - -$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Set-ItemProperty -Path $RegPath -Name "AutoAdminLogon" -Value "1" -Set-ItemProperty -Path $RegPath -Name "DefaultUserName" -Value $Username -Set-ItemProperty -Path $RegPath -Name "DefaultPassword" -Value $Password -Remove-ItemProperty -Path $RegPath -Name "DefaultDomainName" -ErrorAction SilentlyContinue - -Write-Host "Auto-login configured for '$Username'!" -ForegroundColor Green -Write-Host "" -Write-Host "Setup complete! SSH is now available and auto-login is enabled." -ForegroundColor Green -Write-Host "Reboot to test auto-login." -ForegroundColor Yellow diff --git a/apps/rego-tunnel/vpn_scripts-not-used/03_setup-ssh-keys.ps1 b/apps/rego-tunnel/vpn_scripts-not-used/03_setup-ssh-keys.ps1 deleted file mode 100755 index f8320ba..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/03_setup-ssh-keys.ps1 +++ /dev/null @@ -1,34 +0,0 @@ -# Setup SSH Keys -# Run as Administrator in PowerShell - -$Username = if ($env:REGO_USER) { $env:REGO_USER } else { $env:USERNAME } -$PublicKey = if ($env:REGO_SSH_PUBKEY) { $env:REGO_SSH_PUBKEY } else { "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHUQnw0WfeFRQx76UlImXXhu3xeOH41PmDRid8pWK1D default-key" } - -Write-Host "=== Setting up SSH Keys ===" -ForegroundColor Cyan -Write-Host "Using username: $Username" -ForegroundColor Yellow - -# User authorized_keys -$userSshDir = "C:\Users\$Username\.ssh" -$userAuthKeys = "$userSshDir\authorized_keys" - -Write-Host "Creating user .ssh directory..." -ForegroundColor Yellow -New-Item -ItemType Directory -Path $userSshDir -Force | Out-Null - -Write-Host "Adding key to user authorized_keys..." -ForegroundColor Yellow -Add-Content -Path $userAuthKeys -Value $PublicKey -Force - -# Fix permissions for user file -icacls $userAuthKeys /inheritance:r /grant "${Username}:F" /grant "SYSTEM:F" - -# Administrator authorized_keys (for admin users) -$adminAuthKeys = "C:\ProgramData\ssh\administrators_authorized_keys" - -Write-Host "Adding key to administrators_authorized_keys..." -ForegroundColor Yellow -Add-Content -Path $adminAuthKeys -Value $PublicKey -Force - -# Fix permissions for admin file (required by OpenSSH) -icacls $adminAuthKeys /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" - -Write-Host "" -Write-Host "SSH keys configured!" -ForegroundColor Green -Write-Host "You can now SSH in with the configured key." -ForegroundColor Yellow diff --git a/apps/rego-tunnel/vpn_scripts-not-used/README.md b/apps/rego-tunnel/vpn_scripts-not-used/README.md deleted file mode 100755 index 5f16b78..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/README.md +++ /dev/null @@ -1,188 +0,0 @@ -# Rego VPN Automation - Technical Setup Guide - -## Overview - -Cisco Secure Client VPN running in Windows VM (dockurr/windows) inside Docker container, with SOCKS5 proxy for transparent routing to IBM i systems. - -## Architecture - -``` -Clients → Host (iptables/redsocks) → Container (socat) → Windows VM (SOCKS5) → VPN → 10.35.33.x -``` - -## Components - -### 1. Windows VM (inside container) -- **Container**: `rego-tunnel_runtipi-rego-tunnel-1` -- **Windows VM IP**: `172.30.0.16` or `172.30.0.17` (internal to container) -- **VPN**: Cisco Secure Client with SAML auth (email + password + TOTP) -- **Files on Windows** (`C:\Users\alexz\vpn_scripts`): - - `vpn.bat` - Startup batch file - - `vpn-login.js` - Node.js script that automates SAML login via Chrome DevTools Protocol - - `socks5.js` - Simple SOCKS5 proxy server - - `node_modules/` - ws, otplib packages - -### 2. Container -- **External IPs**: `10.128.16.2` or similar -- **Internal bridge**: `172.30.0.1/24` (Windows VM at .16 or .17) -- **socat**: Forwards port 1080 from container to Windows VM SOCKS5 -- **start.sh**: Mounted at `/run/start.sh` - sets up iptables DNAT rules - -### 3. Host -- **redsocks**: Transparent SOCKS5 redirector (optional) -- **iptables**: Redirects traffic to VPN network through container - -## VPN Credentials - -Located in `vpn-login.js`: -```javascript -const CONFIG = { - email: "c-azaw@regoproducts.com", - password: "Fuckyou4suhail", - totpSecret: "RZQTQSKDWKHZ6ZYR", - devtoolsPort: 9222, - vpnTestIp: "10.35.33.230" -}; -``` - -## Windows Setup Steps - -### 1. Install Node.js -Run PowerShell as Administrator: -```powershell -# Option A: Run the install script -.\install-nodejs.ps1 - -# Option B: Manual download from https://nodejs.org/ -``` - -### 2. Install Cisco Secure Client -- Download from company VPN portal or Cisco -- Install with default options -- Path: `C:\Program Files (x86)\Cisco\Cisco Secure Client\` - -### 3. Setup VPN Scripts -```cmd -mkdir C:\Users\alexz\vpn_scripts -copy \\TSCLIENT\shared\vpn-scripts\*.js C:\Users\alexz\vpn_scripts\ -copy \\TSCLIENT\shared\vpn-scripts\vpn.bat C:\Users\alexz\vpn_scripts\ - -cd C:\Users\alexz\vpn_scripts -npm install ws otplib -``` - -### 4. Add to Windows Startup -```cmd -# Create shortcut to vpn.bat in: -shell:startup -# Or: C:\Users\alexz\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup -``` - -### 5. Enable Remote Debugging for Cisco UI -The vpn-login.js script sets this environment variable before launching Cisco: -``` -WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --remote-allow-origins=* -``` - -## Container Configuration - -### docker-compose.yml (user-config) -```yaml -services: - rego-tunnel: - environment: - USER: alexz - PASS: Az@83278327$$@@ - VERSION: win10 - entrypoint: ["/bin/bash", "-c", "source /run/start.sh; exec /usr/bin/tini -s /run/entry.sh"] -``` - -### start.sh (Container Startup Script) -Located at: `/etc/runtipi/user-config/runtipi/rego-tunnel/scripts/start.sh` - -Sets up: -- iptables MASQUERADE for docker bridge -- Route to IBM i network via Windows VM -- DNAT rules for port forwarding (SSH, IBM i ports) - -## Key Ports - -| Port | Service | -|------|---------| -| 22 | SSH | -| 23 | Telnet (IBM i) | -| 446, 448, 449 | IBM i services | -| 1080 | SOCKS5 proxy | -| 8006 | noVNC web console | -| 8470-8476 | IBM i data ports | -| 9222 | Chrome DevTools (for automation) | - -## Manual Commands - -### Start VPN from host: -```bash -docker exec rego-tunnel_runtipi-rego-tunnel-1 ssh docker@172.30.0.16 'C:\Users\alexz\vpn_scripts\vpn.bat' -``` - -### Start socat in container: -```bash -docker exec -d rego-tunnel_runtipi-rego-tunnel-1 socat TCP-LISTEN:1080,fork,reuseaddr TCP:172.30.0.16:1080 -``` - -### Test SOCKS5 connectivity: -```bash -nc -zv 10.128.16.2 1080 -``` - -### Check VPN status in Windows: -```cmd -ipconfig | findstr 10\. -``` - -## Troubleshooting - -### VPN not connecting -1. Check time sync: `w32tm /resync /force` -2. Verify Cisco agent: `net start "Cisco Secure Client Agent"` -3. Check DevTools: `http://172.30.0.16:9222/json` - -### SOCKS5 not working -1. Verify VPN connected first (ping 10.35.33.230) -2. Check socks5.js running: `tasklist | findstr node` -3. Test locally: `nc -zv 127.0.0.1 1080` - -### Container issues -1. Check logs: `docker logs rego-tunnel_runtipi-rego-tunnel-1` -2. Verify start.sh: `docker exec rego-tunnel_runtipi-rego-tunnel-1 cat /run/start.sh` -3. Check Windows VM IP: `docker exec rego-tunnel_runtipi-rego-tunnel-1 cat /run/qemu.pid` - -## File Locations - -### Host -- `/etc/runtipi/user-config/runtipi/rego-tunnel/docker-compose.yml` - User overrides -- `/etc/runtipi/user-config/runtipi/rego-tunnel/scripts/start.sh` - Container startup -- `/etc/runtipi/repos/runtipi/apps/rego-tunnel/docker-compose.yml` - Base config -- `/etc/runtipi/app-data/runtipi/rego-tunnel/data/storage/` - Windows disk image -- `/etc/runtipi/app-data/runtipi/rego-tunnel/data/shared/` - Shared folder with Windows - -### Windows VM -- `C:\Users\alexz\vpn_scripts\vpn-login.js` - Main automation script -- `C:\Users\alexz\vpn_scripts\socks5.js` - SOCKS5 proxy -- `C:\Users\alexz\vpn_scripts\vpn.bat` - Startup batch file -- `C:\Program Files (x86)\Cisco\Cisco Secure Client\` - Cisco installation - -## Watchdog Mode - -The vpn-login.js script includes a watchdog that: -- Monitors VPN connectivity every 2 minutes -- Auto-reconnects after 2 consecutive failures -- Restarts SOCKS5 proxy after reconnection -- Logs memory usage every hour - -## Notes - -- Windows VM takes ~2-3 minutes to boot -- VPN login takes ~30 seconds -- TOTP requires accurate system time (script syncs automatically) -- The container uses VERSION=win10 for dockurr/windows compatibility -- noVNC password: `Az@83278327$@@` diff --git a/apps/rego-tunnel/vpn_scripts-not-used/anyconnect-win-4.8.03052-core-vpn-webdeploy-k9.exe b/apps/rego-tunnel/vpn_scripts-not-used/anyconnect-win-4.8.03052-core-vpn-webdeploy-k9.exe deleted file mode 100755 index bad7b0e..0000000 Binary files a/apps/rego-tunnel/vpn_scripts-not-used/anyconnect-win-4.8.03052-core-vpn-webdeploy-k9.exe and /dev/null differ diff --git a/apps/rego-tunnel/vpn_scripts-not-used/id_ed25519-lenovo b/apps/rego-tunnel/vpn_scripts-not-used/id_ed25519-lenovo deleted file mode 100755 index f7873e8..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/id_ed25519-lenovo +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACBh1EJ8NFn3hUUMe+lJSJl14bt8Xjh+NT5g0YnfKVitQwAAAJhfESWEXxEl -hAAAAAtzc2gtZWQyNTUxOQAAACBh1EJ8NFn3hUUMe+lJSJl14bt8Xjh+NT5g0YnfKVitQw -AAAEDgYZN7HwPbKY++p612bnhGC10P3GUHQdJlprPEFbODgWHUQnw0WfeFRQx76UlImXXh -u3xeOH41PmDRid8pWK1DAAAAEWFsZXh6QEFaYXdQQy1QMTZTAQIDBA== ------END OPENSSH PRIVATE KEY----- diff --git a/apps/rego-tunnel/vpn_scripts-not-used/setup-all.bat b/apps/rego-tunnel/vpn_scripts-not-used/setup-all.bat deleted file mode 100755 index 2f2bcc4..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/setup-all.bat +++ /dev/null @@ -1,35 +0,0 @@ -@echo off -echo === Rego VPN Windows Setup === -echo. - -echo [1/7] Installing Node.js... -powershell -ExecutionPolicy Bypass -File "%~dp001_install-nodejs.ps1" - -echo [2/7] Setting up OpenSSH and Auto-Login... -powershell -ExecutionPolicy Bypass -File "%~dp002_setup-autologin-sshd.ps1" - -echo [3/7] Configuring SSH Keys... -powershell -ExecutionPolicy Bypass -File "%~dp003_setup-ssh-keys.ps1" - -echo [4/7] Creating vpn_scripts folder... -mkdir "C:\Users\%USERNAME%\vpn_scripts" 2>nul - -echo [5/7] Copying runtime scripts... -copy "%~dp0vpn-login.js" "C:\Users\%USERNAME%\vpn_scripts\" -copy "%~dp0socks5.js" "C:\Users\%USERNAME%\vpn_scripts\" -copy "%~dp0vpn.bat" "C:\Users\%USERNAME%\vpn_scripts\" - -echo [6/7] Installing npm dependencies... -cd /d "C:\Users\%USERNAME%\vpn_scripts" -call npm install ws otplib - -echo [7/7] Adding to startup (Run as Admin)... -copy "%~dp0vpn-startup.lnk" "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\vpn.lnk" - -echo. -echo === Setup Complete === -echo. -echo Manual step remaining: -echo - Install Anyconnect (run anyconnect-win-*.exe from this folder) -echo. -pause diff --git a/apps/rego-tunnel/vpn_scripts-not-used/socks5.js b/apps/rego-tunnel/vpn_scripts-not-used/socks5.js deleted file mode 100755 index ea9438b..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/socks5.js +++ /dev/null @@ -1,69 +0,0 @@ -const net = require('net'); - -const PORT = 1080; -const HOST = '0.0.0.0'; - -const server = net.createServer((client) => { - client.once('data', (data) => { - // SOCKS5 handshake - if (data[0] !== 0x05) { - client.end(); - return; - } - - // No auth required - client.write(Buffer.from([0x05, 0x00])); - - client.once('data', (data) => { - if (data[0] !== 0x05 || data[1] !== 0x01) { - client.write(Buffer.from([0x05, 0x07, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); - client.end(); - return; - } - - let host, port; - const atyp = data[3]; - - if (atyp === 0x01) { - // IPv4 - host = `${data[4]}.${data[5]}.${data[6]}.${data[7]}`; - port = data.readUInt16BE(8); - } else if (atyp === 0x03) { - // Domain - const len = data[4]; - host = data.slice(5, 5 + len).toString(); - port = data.readUInt16BE(5 + len); - } else if (atyp === 0x04) { - // IPv6 - host = ''; - for (let i = 0; i < 16; i += 2) { - host += data.slice(4 + i, 6 + i).toString('hex'); - if (i < 14) host += ':'; - } - port = data.readUInt16BE(20); - } else { - client.write(Buffer.from([0x05, 0x08, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); - client.end(); - return; - } - - const remote = net.createConnection(port, host, () => { - const response = Buffer.from([0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0]); - client.write(response); - client.pipe(remote); - remote.pipe(client); - }); - - remote.on('error', () => { - client.write(Buffer.from([0x05, 0x05, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); - client.end(); - }); - }); - }); - - client.on('error', () => {}); -}); - -server.listen(PORT, HOST, () => { - console.log(`SOCKS5 proxy running on ${HOST}:${PORT}`); -}); diff --git a/apps/rego-tunnel/vpn_scripts-not-used/start.sh b/apps/rego-tunnel/vpn_scripts-not-used/start.sh deleted file mode 100755 index b7fa9e3..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/start.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -# Startup hook - runs after container starts -# Dynamically detects Windows VM IP and sets up networking - -# Install required packages (not persistent across restarts) -echo "[rego-tunnel] Installing required packages..." -apt-get update -qq && apt-get install -y -qq socat openssh-client netcat-openbsd >/dev/null 2>&1 || true - -# Setup SSH key for accessing Windows VM -echo "[rego-tunnel] Setting up SSH key..." -mkdir -p /root/.ssh -cp /vpn_scripts/id_ed25519-lenovo /root/.ssh/ 2>/dev/null || true -chmod 600 /root/.ssh/id_ed25519-lenovo 2>/dev/null || true - -get_windows_ip() { - # Use VM_NET_IP env var if set, otherwise detect from DHCP leases - if [[ -n "${VM_NET_IP:-}" ]]; then - echo "$VM_NET_IP" - return - fi - awk '/Windows/ {print $3}' /var/lib/misc/dnsmasq.leases 2>/dev/null | head -1 -} - -get_container_ip() { - # Get container's external IP (172.31.0.10) - exclude docker bridge gateway (.1) - ip -4 addr 2>/dev/null | grep -oE '172\.31\.0\.[0-9]+' | grep -v '\.1$' | head -1 -} - -( - # Wait for Windows VM to boot and get IP - echo "[rego-tunnel] Waiting for Windows VM..." - WINDOWS_IP="" - for i in {1..120}; do - WINDOWS_IP=$(get_windows_ip) - if [[ -n "$WINDOWS_IP" ]]; then - echo "[rego-tunnel] Windows VM IP: $WINDOWS_IP" - break - fi - sleep 2 - done - - if [[ -z "$WINDOWS_IP" ]]; then - echo "[rego-tunnel] ERROR: Could not detect Windows VM IP" - exit 1 - fi - - # Wait for SSH to be available on Windows - echo "[rego-tunnel] Waiting for SSH on Windows..." - for i in {1..60}; do - if nc -z "$WINDOWS_IP" 22 2>/dev/null; then - echo "[rego-tunnel] SSH is available" - break - fi - sleep 2 - done - - CONTAINER_IP=$(get_container_ip) - echo "[rego-tunnel] Container IP: $CONTAINER_IP" - - # Add MASQUERADE for docker bridge - iptables -t nat -C POSTROUTING -o docker -j MASQUERADE 2>/dev/null || \ - iptables -t nat -A POSTROUTING -o docker -j MASQUERADE - - # Allow forwarding to Windows VM - iptables -C FORWARD -d "$WINDOWS_IP" -j ACCEPT 2>/dev/null || \ - iptables -A FORWARD -d "$WINDOWS_IP" -j ACCEPT - - # Forward port 2222 to VM's SSH (2222) for VM access - pkill -f "socat.*:2222" 2>/dev/null || true - socat TCP-LISTEN:2222,fork,reuseaddr TCP:"$WINDOWS_IP":2222 & - echo "[rego-tunnel] SSH to VM available on port 2222" - - # Add DNAT rules for port forwarding - add_dnat() { - local port=$1 - iptables -t nat -C PREROUTING -d "$CONTAINER_IP" -p tcp --dport "$port" -j DNAT --to-destination "$WINDOWS_IP:$port" 2>/dev/null || \ - iptables -t nat -A PREROUTING -d "$CONTAINER_IP" -p tcp --dport "$port" -j DNAT --to-destination "$WINDOWS_IP:$port" - } - - # IBM i standard ports (via VM portproxy) - add_dnat 22 - add_dnat 23 - add_dnat 446 - add_dnat 448 - add_dnat 449 - - # IBM i data ports - for port in $(seq 8470 8476); do add_dnat $port; done - - # Additional port ranges - for port in $(seq 2000 2020); do add_dnat $port; done - for port in $(seq 3000 3020); do add_dnat $port; done - for port in $(seq 10000 10020); do add_dnat $port; done - for port in $(seq 36000 36010); do add_dnat $port; done - - echo "[rego-tunnel] iptables DNAT rules configured" - echo "[rego-tunnel] Port forwarding ready via $CONTAINER_IP" - - # Set VNC password if VNC_PASSWORD env var is set - if [[ -n "${VNC_PASSWORD:-}" ]]; then - echo "[rego-tunnel] Setting VNC password..." - for i in {1..30}; do - if nc -z localhost 7100 2>/dev/null; then - sleep 2 - echo "set_password vnc ${VNC_PASSWORD}" | nc -q1 localhost 7100 >/dev/null 2>&1 && \ - echo "[rego-tunnel] VNC password set successfully" || \ - echo "[rego-tunnel] Failed to set VNC password" - break - fi - sleep 2 - done - fi -) & - -return 0 diff --git a/apps/rego-tunnel/vpn_scripts-not-used/vpn-login.js b/apps/rego-tunnel/vpn_scripts-not-used/vpn-login.js deleted file mode 100755 index a35851a..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/vpn-login.js +++ /dev/null @@ -1,441 +0,0 @@ -const WebSocket = require("ws"); -const { authenticator } = require("otplib"); -const { execSync, spawn } = require("child_process"); - -const CONFIG = { - email: "c-azaw@regoproducts.com", - password: "Fuckyou4suhail", - totpSecret: "RZQTQSKDWKHZ6ZYR", - devtoolsPort: 9222, - vpnTestIp: "10.35.33.230" -}; - -let ws; -let msgId = 1; - -function log(msg) { - console.log("[" + new Date().toLocaleTimeString() + "] " + msg); -} - -function run(cmd) { - try { execSync(cmd, { stdio: "ignore", timeout: 10000 }); } catch (e) {} -} - -function runOutput(cmd) { - try { - return execSync(cmd, { encoding: "utf8", timeout: 10000 }); - } catch (e) { - return ""; - } -} - -async function getPages() { - const res = await fetch("http://localhost:" + CONFIG.devtoolsPort + "/json"); - return res.json(); -} - -function send(method, params = {}) { - return new Promise((resolve, reject) => { - const id = msgId++; - const timeout = setTimeout(() => reject(new Error("Timeout: " + method)), 15000); - const handler = (data) => { - const msg = JSON.parse(data); - if (msg.id === id) { - clearTimeout(timeout); - ws.off("message", handler); - resolve(msg.result); - } - }; - ws.on("message", handler); - ws.send(JSON.stringify({ id, method, params })); - }); -} - -async function waitForSelector(selector, timeout = 30000) { - const start = Date.now(); - while (Date.now() - start < timeout) { - try { - const result = await send("Runtime.evaluate", { - expression: "document.querySelector('" + selector + "') !== null", - returnByValue: true - }); - if (result.result.value === true) return true; - } catch (e) {} - await sleep(500); - } - return false; -} - -async function typeText(selector, text) { - await send("Runtime.evaluate", { - expression: "var el = document.querySelector('" + selector + "'); el.focus(); el.value = '';" - }); - await sleep(100); - for (const char of text) { - await send("Input.dispatchKeyEvent", { type: "char", text: char }); - await sleep(30); - } -} - -async function click(selector) { - await send("Runtime.evaluate", { - expression: "document.querySelector('" + selector + "').click()" - }); -} - -async function clickSubmit() { - const methods = [ - "document.querySelector('#submitButton') && document.querySelector('#submitButton').click()", - "typeof Login !== 'undefined' && Login.submitLoginRequest && Login.submitLoginRequest()", - "document.querySelector('input[type=\"submit\"]') && document.querySelector('input[type=\"submit\"]').click()", - "document.querySelector('button[type=\"submit\"]') && document.querySelector('button[type=\"submit\"]').click()", - "document.querySelector('#idSIButton9') && document.querySelector('#idSIButton9').click()" - ]; - for (const expr of methods) { - try { await send("Runtime.evaluate", { expression: expr }); } catch (e) {} - } -} - -async function sleep(ms) { - return new Promise(r => setTimeout(r, ms)); -} - -async function waitForDevtools(maxWait = 120000) { - const start = Date.now(); - while (Date.now() - start < maxWait) { - try { - const pages = await getPages(); - const page = pages.find(p => p.type === "page"); - if (page) return page; - } catch (e) {} - log("Waiting for WebView..."); - await sleep(2000); - } - return null; -} - -// VPN adapter check skipped - IP range is unpredictable -// We rely solely on connectivity test to target IP - -// Test connectivity via ping (check for actual reply, not TTL expired) -function testVpnConnectivity(ip) { - try { - const output = execSync(`ping -n 1 -w 3000 ${ip}`, { encoding: "utf8", timeout: 5000 }); - // Must have "Reply from " - not "TTL expired" or "Request timed out" - return output.includes(`Reply from ${ip}`); - } catch (e) { - return false; - } -} - -// Verify VPN is connected with retries (connectivity test only) -async function verifyVpnConnection(maxRetries = 10, retryDelay = 5000) { - log("--- VPN VERIFICATION ---"); - - for (let i = 1; i <= maxRetries; i++) { - log(`Attempt ${i}/${maxRetries}: Pinging ${CONFIG.vpnTestIp}...`); - const connected = testVpnConnectivity(CONFIG.vpnTestIp); - - if (connected) { - log("VPN connectivity confirmed!"); - return true; - } - - log("Not reachable yet, waiting..."); - if (i < maxRetries) { - await sleep(retryDelay); - } - } - - log("VPN verification failed after " + maxRetries + " attempts"); - return false; -} - -async function main() { - console.log(""); - console.log("========================================"); - console.log(" CISCO VPN AUTO-LOGIN"); - console.log("========================================"); - console.log(""); - - // Sync time first (TOTP requires accurate time) - log("Syncing system time..."); - run("sc config w32time start= auto"); - run("net start w32time"); - run("w32tm /config /manualpeerlist:pool.ntp.org /syncfromflags:manual /update"); - run("w32tm /resync /force"); - await sleep(2000); - - // Kill everything - log("Killing Cisco processes..."); - run("taskkill /F /IM csc_ui.exe"); - run("taskkill /F /IM vpnui.exe"); - run("taskkill /F /IM vpnagent.exe"); - run('net stop csc_vpnagent'); - await sleep(2000); - - // Start agent - log("Starting Cisco agent..."); - run('net start csc_vpnagent'); - await sleep(3000); - - // Start UI - log("Starting Cisco UI..."); - process.env.WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = "--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --remote-allow-origins=*"; - spawn("C:\\Program Files (x86)\\Cisco\\Cisco Secure Client\\UI\\csc_ui.exe", [], { - detached: true, - stdio: "ignore" - }).unref(); - - await sleep(5000); - - // Wait for WebView - const page = await waitForDevtools(); - if (!page) { - log("ERROR: WebView not found - rebooting..."); - run("shutdown /r /t 1"); - process.exit(1); - } - - log("WebView: " + page.title); - ws = new WebSocket(page.webSocketDebuggerUrl); - await new Promise((resolve, reject) => { - ws.on("open", resolve); - ws.on("error", reject); - }); - - await send("DOM.enable"); - await send("Runtime.enable"); - await send("Input.enable"); - log("Connected to DevTools"); - - const url = page.url || ""; - const isADFS = url.includes("adfs"); - log("Login type: " + (isADFS ? "ADFS" : "Microsoft")); - - if (isADFS) { - log("--- ADFS LOGIN ---"); - if (!await waitForSelector("#passwordInput", 15000)) { - log("Password field not found"); - process.exit(1); - } - log("Entering password..."); - await typeText("#passwordInput", CONFIG.password); - await sleep(500); - log("Clicking Sign In..."); - await clickSubmit(); - await sleep(3000); - } else { - log("--- EMAIL ---"); - if (await waitForSelector('input[type="email"]', 5000)) { - log("Entering email..."); - await typeText('input[type="email"]', CONFIG.email); - await sleep(500); - log("Clicking Next..."); - await clickSubmit(); - await sleep(3000); - } - - log("--- PASSWORD ---"); - if (!await waitForSelector('input[type="password"]', 15000)) { - log("Password field not found"); - process.exit(1); - } - log("Entering password..."); - await typeText('input[type="password"]', CONFIG.password); - await sleep(500); - log("Clicking Sign In..."); - await clickSubmit(); - await sleep(3000); - } - - // TOTP - log("--- TOTP ---"); - if (await waitForSelector('input[name="otc"]', 15000)) { - await sleep(500); - const totp = authenticator.generate(CONFIG.totpSecret); - log("TOTP: " + totp); - await typeText('input[name="otc"]', totp); - await sleep(500); - log("Submitting..."); - await clickSubmit(); - await sleep(3000); - } else { - log("No TOTP field"); - } - - // Stay signed in - log("--- STAY SIGNED IN ---"); - if (await waitForSelector("#idBtn_Back", 5000)) { - log("Clicking No..."); - await click("#idBtn_Back"); - } - - await sleep(2000); - ws.close(); - - // Verify VPN connection - const vpnConnected = await verifyVpnConnection(); - - if (!vpnConnected) { - log("ERROR: VPN connection could not be verified"); - process.exit(1); - } - - console.log(""); - console.log("========================================"); - console.log(" VPN CONNECTED!"); - console.log(" Entering watchdog mode..."); - console.log("========================================"); - console.log(""); - - // Enter watchdog mode - monitor and reconnect if needed - await watchdogLoop(); -} - -async function watchdogLoop() { - const checkInterval = 2 * 60 * 1000; // 2 minutes - let consecutiveFailures = 0; - let checkCount = 0; - - log("Watchdog: Monitoring every 2 minutes..."); - - while (true) { - await sleep(checkInterval); - checkCount++; - - // Force garbage collection every 10 checks (~20 min) - if (checkCount % 10 === 0 && global.gc) { - global.gc(); - } - - // Log memory every 30 checks (~1 hour) - if (checkCount % 30 === 0) { - const mem = Math.round(process.memoryUsage().heapUsed / 1024 / 1024); - log(`Watchdog: Memory ${mem}MB, checks ${checkCount}`); - } - - const connected = testVpnConnectivity(CONFIG.vpnTestIp); - - if (connected) { - if (consecutiveFailures > 0) { - log("Watchdog: Connection restored"); - } - consecutiveFailures = 0; - } else { - consecutiveFailures++; - log(`Watchdog: Connection FAILED (${consecutiveFailures})`); - - if (consecutiveFailures >= 2) { - log("Watchdog: Reconnecting..."); - await reconnectVpn(); - consecutiveFailures = 0; - } - } - } -} - -async function reconnectVpn() { - // Sync time first (TOTP requires accurate time) - log("Syncing system time..."); - run("sc config w32time start= auto"); - run("net start w32time"); - run("w32tm /resync /force"); - await sleep(1000); - - // Kill and restart VPN - log("Killing Cisco processes..."); - run("taskkill /F /IM csc_ui.exe"); - run("taskkill /F /IM vpnui.exe"); - run("taskkill /F /IM vpnagent.exe"); - run('net stop "Cisco Secure Client Agent"'); - await sleep(2000); - - log("Starting Cisco agent..."); - run('net start "Cisco Secure Client Agent"'); - await sleep(3000); - - log("Starting Cisco UI..."); - spawn("C:\\Program Files (x86)\\Cisco\\Cisco Secure Client\\UI\\csc_ui.exe", [], { - detached: true, - stdio: "ignore" - }).unref(); - - await sleep(5000); - - const page = await waitForDevtools(); - if (!page) { - log("ERROR: WebView not found - rebooting..."); - run("shutdown /r /t 1"); - return false; - } - - ws = new WebSocket(page.webSocketDebuggerUrl); - await new Promise((resolve, reject) => { - ws.on("open", resolve); - ws.on("error", reject); - }); - - await send("DOM.enable"); - await send("Runtime.enable"); - await send("Input.enable"); - - const url = page.url || ""; - const isADFS = url.includes("adfs"); - - if (isADFS) { - if (await waitForSelector("#passwordInput", 15000)) { - await typeText("#passwordInput", CONFIG.password); - await sleep(500); - await clickSubmit(); - await sleep(3000); - } - } else { - if (await waitForSelector('input[type="email"]', 5000)) { - await typeText('input[type="email"]', CONFIG.email); - await sleep(500); - await clickSubmit(); - await sleep(3000); - } - if (await waitForSelector('input[type="password"]', 15000)) { - await typeText('input[type="password"]', CONFIG.password); - await sleep(500); - await clickSubmit(); - await sleep(3000); - } - } - - // TOTP - if (await waitForSelector('input[name="otc"]', 15000)) { - await sleep(500); - const totp = authenticator.generate(CONFIG.totpSecret); - log("TOTP: " + totp); - await typeText('input[name="otc"]', totp); - await sleep(500); - await clickSubmit(); - await sleep(3000); - } - - // Stay signed in - No - if (await waitForSelector("#idBtn_Back", 5000)) { - await click("#idBtn_Back"); - } - - await sleep(2000); - ws.close(); - - // Verify reconnection - const verified = await verifyVpnConnection(); - if (verified) { - log("Reconnection successful!"); - return true; - } - - log("Reconnection failed"); - return false; -} - -main().catch(err => { - log("ERROR: " + err.message); - process.exit(1); -}); diff --git a/apps/rego-tunnel/vpn_scripts-not-used/vpn-startup.lnk b/apps/rego-tunnel/vpn_scripts-not-used/vpn-startup.lnk deleted file mode 100755 index a084348..0000000 Binary files a/apps/rego-tunnel/vpn_scripts-not-used/vpn-startup.lnk and /dev/null differ diff --git a/apps/rego-tunnel/vpn_scripts-not-used/vpn.bat b/apps/rego-tunnel/vpn_scripts-not-used/vpn.bat deleted file mode 100755 index 916d313..0000000 --- a/apps/rego-tunnel/vpn_scripts-not-used/vpn.bat +++ /dev/null @@ -1,4 +0,0 @@ -@echo off -cd /d C:\Users\%USERNAME%\vpn_scripts\ -node vpn-login.js -pause