From 4fd8688685ec7a4daff081f8ccae85405834def2 Mon Sep 17 00:00:00 2001 From: alexz Date: Sat, 17 Jan 2026 11:30:34 +0000 Subject: [PATCH] revert(cistech-tunnel): restore to original working state at a7691b1 - Removed shared/ folder (host routing scripts) - Restored original config.json, docker-compose.json - Restored original Dockerfile and entrypoint.sh Co-Authored-By: Claude Opus 4.5 --- apps/cistech-tunnel/config.json | 36 +++-- apps/cistech-tunnel/docker-compose.json | 24 ++-- apps/cistech-tunnel/shared/host-routing.sh | 123 ------------------ .../shared/install-host-services.sh | 68 ---------- .../shared/uninstall-host-services.sh | 24 ---- apps/cistech-tunnel/source/Dockerfile | 9 +- apps/cistech-tunnel/source/entrypoint.sh | 46 +------ 7 files changed, 34 insertions(+), 296 deletions(-) delete mode 100644 apps/cistech-tunnel/shared/host-routing.sh delete mode 100644 apps/cistech-tunnel/shared/install-host-services.sh delete mode 100644 apps/cistech-tunnel/shared/uninstall-host-services.sh diff --git a/apps/cistech-tunnel/config.json b/apps/cistech-tunnel/config.json index d95ff64..04efcb9 100755 --- a/apps/cistech-tunnel/config.json +++ b/apps/cistech-tunnel/config.json @@ -24,30 +24,26 @@ "required": true, "default": "https://vpn.cistech.net/Employees" }, - { - "label": "Username (email)", - "type": "text", - "env_variable": "OC_USER", - "required": true - }, - { - "label": "VPN Password", - "type": "password", - "env_variable": "OC_PASSWORD", - "required": true - }, - { - "label": "TOTP Secret", - "type": "password", - "env_variable": "OC_TOTP_SECRET", - "required": false, - "hint": "Base32 TOTP secret for auto-login" - }, { "label": "VNC Password", "type": "password", "env_variable": "VNC_PASSWORD", - "required": true + "required": true, + "default": "Az@83278327$$@@" + }, + { + "label": "Server Certificate", + "type": "text", + "env_variable": "OC_SERVERCERT", + "required": true, + "default": "pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0=" + }, + { + "label": "Username", + "type": "text", + "env_variable": "OC_USER", + "required": true, + "default": "alex.zaw@cistech.net" } ], "supported_architectures": [ diff --git a/apps/cistech-tunnel/docker-compose.json b/apps/cistech-tunnel/docker-compose.json index d69aa3b..01d9a8b 100755 --- a/apps/cistech-tunnel/docker-compose.json +++ b/apps/cistech-tunnel/docker-compose.json @@ -1,26 +1,22 @@ { - "schemaVersion": 2, "services": [ { "name": "cistech-tunnel", - "image": "git.alexzaw.dev/alexz/cistech-vpn:latest", + "image": "cistech-vpn:latest", "isMain": true, "internalPort": 6902, "privileged": true, "capAdd": ["NET_ADMIN"], - "devices": ["/dev/net/tun"], - "environment": [ - { "key": "OC_URL", "value": "${OC_URL}" }, - { "key": "OC_USER", "value": "${OC_USER}" }, - { "key": "OC_PASSWORD", "value": "${OC_PASSWORD}" }, - { "key": "OC_TOTP_SECRET", "value": "${OC_TOTP_SECRET}" }, - { "key": "VNC_PASSWORD", "value": "${VNC_PASSWORD}" }, - { "key": "NOVNC_PORT", "value": "6902" } - ], + "devices": ["/dev/net/tun:/dev/net/tun"], + "environment": { + "OC_URL": "${OC_URL}", + "OC_SERVERCERT": "${OC_SERVERCERT}", + "OC_USER": "${OC_USER}", + "VNC_PASSWORD": "${VNC_PASSWORD}", + "NOVNC_PORT": "6902" + }, "volumes": [ - { "hostPath": "${APP_DATA_DIR}/data", "containerPath": "/root" }, - { "hostPath": "${APP_DATA_DIR}", "containerPath": "/runtime" }, - { "hostPath": "/etc/runtipi/repos/runtipi/apps/cistech-tunnel/shared", "containerPath": "/shared" } + { "hostPath": "${APP_DATA_DIR}/data", "containerPath": "/root" } ] } ] diff --git a/apps/cistech-tunnel/shared/host-routing.sh b/apps/cistech-tunnel/shared/host-routing.sh deleted file mode 100644 index c796301..0000000 --- a/apps/cistech-tunnel/shared/host-routing.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash -# -# Host routing script for cistech-tunnel -# Routes target subnets through the VPN container -# -set -euo pipefail - -ACTION="${1:-start}" - -# Fixed configuration -CONTAINER_IP="172.30.0.10" -BRIDGE_NAME="br-vpn-static" -TARGET_SUBNETS="10.3.1.0/24 10.255.255.0/24" -LAN_SUBNET="192.168.0.0/23" -LAN_INTERFACES="eth0 eth1 wlan0" -LOG_FILE="/var/log/cistech-routing.log" - -log() { - local msg="[$(date '+%Y-%m-%d %H:%M:%S')] [cistech-routing] $*" - echo "$msg" | tee -a "$LOG_FILE" >&2 -} - -get_lan_interface() { - ip route show default | awk '/default/ {for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}' | head -1 -} - -remove_routes() { - log "Removing stale routes..." - for subnet in $TARGET_SUBNETS; do - ip route del "$subnet" 2>/dev/null || true - done - log "Stale routes removed" -} - -apply_routes() { - local lan_if - lan_if="$(get_lan_interface)" - - log "Applying host routing rules..." - log " Container IP: $CONTAINER_IP" - log " Bridge: $BRIDGE_NAME" - log " Target subnets: $TARGET_SUBNETS" - log " LAN interface: ${lan_if:-unknown}" - - # Enable IP forwarding - echo 1 > /proc/sys/net/ipv4/ip_forward - log "IP forwarding enabled" - - # Add routes to target subnets via container - for subnet in $TARGET_SUBNETS; do - ip route replace "$subnet" via "$CONTAINER_IP" dev "$BRIDGE_NAME" - log "Route added: $subnet via $CONTAINER_IP dev $BRIDGE_NAME" - done - - # Allow forwarding in DOCKER-USER chain for all LAN interfaces - for lan_if in $LAN_INTERFACES; do - if ip link show "$lan_if" &>/dev/null; then - # Allow traffic from LAN to container bridge - iptables -C DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -j ACCEPT 2>/dev/null || \ - iptables -I DOCKER-USER 1 -i "$lan_if" -o "$BRIDGE_NAME" -j ACCEPT - - # Allow return traffic - iptables -C DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \ - iptables -I DOCKER-USER 1 -i "$BRIDGE_NAME" -o "$lan_if" -m state --state RELATED,ESTABLISHED -j ACCEPT - - log "DOCKER-USER iptables rules added for $lan_if <-> $BRIDGE_NAME" - fi - done - - # Masquerade traffic from LAN subnet to VPN bridge (using nft) - if ! nft list chain ip nat POSTROUTING 2>/dev/null | grep -q "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade"; then - nft add rule ip nat POSTROUTING ip saddr "$LAN_SUBNET" oifname "$BRIDGE_NAME" counter masquerade - log "NAT masquerade rule added for $LAN_SUBNET -> $BRIDGE_NAME" - else - log "NAT masquerade rule already exists for $LAN_SUBNET -> $BRIDGE_NAME" - fi - - log "OK: Host routing applied" -} - -remove_all() { - log "Removing all routing rules..." - - # Remove routes - for subnet in $TARGET_SUBNETS; do - ip route del "$subnet" via "$CONTAINER_IP" dev "$BRIDGE_NAME" 2>/dev/null || true - done - - # Remove iptables rules for all LAN interfaces - for lan_if in $LAN_INTERFACES; do - iptables -D DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -j ACCEPT 2>/dev/null || true - iptables -D DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true - done - - # Remove masquerade rule (using nft) - local handle - handle=$(nft -a list chain ip nat POSTROUTING 2>/dev/null | grep "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade" | grep -oP 'handle \K\d+' | head -1) - if [ -n "$handle" ]; then - nft delete rule ip nat POSTROUTING handle "$handle" 2>/dev/null || true - fi - - log "All routing rules removed" -} - -case "$ACTION" in - start) - remove_routes - apply_routes - ;; - stop) - remove_all - ;; - restart) - remove_all - sleep 1 - remove_routes - apply_routes - ;; - *) - echo "Usage: $0 {start|stop|restart}" >&2 - exit 2 - ;; -esac diff --git a/apps/cistech-tunnel/shared/install-host-services.sh b/apps/cistech-tunnel/shared/install-host-services.sh deleted file mode 100644 index 8ad7fc7..0000000 --- a/apps/cistech-tunnel/shared/install-host-services.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash -# -# Install host-side systemd services for cistech-tunnel -# Run this ONCE on the host after app install -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -APP_DATA_DIR="/etc/runtipi/app-data/runtipi/cistech-tunnel" - -echo "Installing cistech-tunnel host services..." - -# Create app-data directory for trigger file -sudo mkdir -p "$APP_DATA_DIR" - -# Create the path unit (watches for trigger file) -sudo tee /etc/systemd/system/cistech-routing-watcher.path > /dev/null << EOF -[Unit] -Description=Watch for cistech-tunnel routing trigger - -[Path] -PathExists=$APP_DATA_DIR/restart-routing -Unit=cistech-routing-watcher.service - -[Install] -WantedBy=multi-user.target -EOF - -# Create the service unit (applies routes when triggered) -sudo tee /etc/systemd/system/cistech-routing-watcher.service > /dev/null << EOF -[Unit] -Description=Apply cistech-tunnel routing rules -After=docker.service - -[Service] -Type=oneshot -ExecStart=$SCRIPT_DIR/host-routing.sh restart -ExecStartPost=/bin/rm -f $APP_DATA_DIR/restart-routing -ExecStartPost=/bin/bash -c 'echo "trigger cleared at \$(date)" >> $APP_DATA_DIR/watcher.log' -EOF - -# Make host-routing.sh executable -chmod +x "$SCRIPT_DIR/host-routing.sh" - -# Reload systemd and enable the watcher -sudo systemctl daemon-reload -sudo systemctl enable cistech-routing-watcher.path -sudo systemctl start cistech-routing-watcher.path - -# Disable the old boot-only service if it exists -if systemctl is-enabled cistech-routing.service &>/dev/null; then - echo "Disabling old cistech-routing.service (replaced by watcher)..." - sudo systemctl stop cistech-routing.service 2>/dev/null || true - sudo systemctl disable cistech-routing.service 2>/dev/null || true -fi - -# Apply routes now -echo "Applying initial routes..." -sudo "$SCRIPT_DIR/host-routing.sh" start - -echo "" -echo "Done! Watcher installed and routes applied." -echo "" -echo "To trigger route refresh from container:" -echo " touch /runtime/restart-routing" -echo "" -echo "To check watcher status:" -echo " systemctl status cistech-routing-watcher.path" diff --git a/apps/cistech-tunnel/shared/uninstall-host-services.sh b/apps/cistech-tunnel/shared/uninstall-host-services.sh deleted file mode 100644 index 743b62b..0000000 --- a/apps/cistech-tunnel/shared/uninstall-host-services.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# -# Uninstall host-side systemd services for cistech-tunnel -# -set -euo pipefail - -echo "Removing cistech-tunnel host services..." - -# Stop and disable the watcher -sudo systemctl stop cistech-routing-watcher.path 2>/dev/null || true -sudo systemctl disable cistech-routing-watcher.path 2>/dev/null || true - -# Remove routing rules -/etc/runtipi/repos/runtipi/apps/cistech-tunnel/shared/host-routing.sh stop 2>/dev/null || true - -# Remove systemd units -sudo rm -f /etc/systemd/system/cistech-routing-watcher.path -sudo rm -f /etc/systemd/system/cistech-routing-watcher.service - -# Reload systemd -sudo systemctl daemon-reload - -echo "" -echo "Done! Host services removed." diff --git a/apps/cistech-tunnel/source/Dockerfile b/apps/cistech-tunnel/source/Dockerfile index 36d6324..28111e1 100755 --- a/apps/cistech-tunnel/source/Dockerfile +++ b/apps/cistech-tunnel/source/Dockerfile @@ -4,9 +4,12 @@ ENV DEBIAN_FRONTEND=noninteractive \ VIRTUAL_ENV=/opt/venv \ PATH=/opt/venv/bin:$PATH \ QTWEBENGINE_DISABLE_SANDBOX=1 \ - QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox --disable-gpu" -# Credentials come from environment variables at runtime: -# OC_URL, OC_SERVERCERT, OC_USER, OC_TOTP_SECRET, VNC_PASSWORD + QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox --disable-gpu" \ + OC_URL="https://vpn.cistech.net/Employees" \ + OC_SERVERCERT="pin-sha256:HyHob3LiVmIp8ch9AzHJ9jMYqI43tO5N13oWeBLiZ/0=" \ + OC_USER="alex.zaw@cistech.net" \ + OC_TOTP_SECRET="t6ypnjqvyx2yvw2l" \ + VNC_PASSWORD="Az@83278327\$\$@@" RUN apt-get update && apt-get install -y \ openconnect iproute2 iptables ca-certificates \ diff --git a/apps/cistech-tunnel/source/entrypoint.sh b/apps/cistech-tunnel/source/entrypoint.sh index 6eac090..30540fb 100755 --- a/apps/cistech-tunnel/source/entrypoint.sh +++ b/apps/cistech-tunnel/source/entrypoint.sh @@ -2,42 +2,13 @@ set -euo pipefail : "${OC_URL:?OC_URL required}" - -# Auto-fetch server certificate pin if not provided -get_server_cert_pin() { - local url="$1" - local host=$(echo "$url" | sed -E 's|https?://([^/:]+).*|\1|') - local port=443 - - echo "Fetching certificate pin from $host:$port..." >&2 - - # Get certificate and compute pin-sha256 - local pin=$(echo | openssl s_client -connect "$host:$port" -servername "$host" 2>/dev/null | \ - openssl x509 -pubkey -noout 2>/dev/null | \ - openssl pkey -pubin -outform DER 2>/dev/null | \ - openssl dgst -sha256 -binary | \ - base64) - - if [[ -n "$pin" ]]; then - echo "pin-sha256:$pin" - else - echo "ERROR: Failed to fetch certificate from $host" >&2 - return 1 - fi -} - -# Get or fetch OC_SERVERCERT -if [[ -z "${OC_SERVERCERT:-}" ]]; then - OC_SERVERCERT=$(get_server_cert_pin "$OC_URL") - echo "Auto-detected server cert: $OC_SERVERCERT" -fi +: "${OC_SERVERCERT:?OC_SERVERCERT required}" NOVNC_PORT="${NOVNC_PORT:-6901}" VNC_PASSWORD="${VNC_PASSWORD:-changeme}" DISPLAY_ADDR="${DISPLAY:-:1}" OC_INTERFACE="${OC_INTERFACE:-tun0}" OC_USER="${OC_USER:-}" -OC_PASSWORD="${OC_PASSWORD:-}" OC_TOTP_SECRET="${OC_TOTP_SECRET:-}" # Default to hidden browser if OC_USER is set @@ -74,7 +45,6 @@ export OC_URL="$OC_URL" export OC_SERVERCERT="$OC_SERVERCERT" export OC_INTERFACE="$OC_INTERFACE" export OC_USER="$OC_USER" -export OC_PASSWORD="$OC_PASSWORD" export OC_SSO_ARGS_DEFAULT="$OC_SSO_ARGS_DEFAULT" export OC_SSO_ARGS="${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT}" export OC_AUTHGROUP="${OC_AUTHGROUP:-}" @@ -96,14 +66,8 @@ ENVFILE source /etc/vpn.env echo "[$(date)] Starting VPN connection..." -# Set password for openconnect -export OPENCONNECT_PASSWORD="$OC_PASSWORD" - # openconnect-sso reads TOTP from keyring automatically -# Pass password via stdin for SSO form if needed -if [[ -n "$OC_USER" && -n "$OC_PASSWORD" ]]; then - echo "$OC_PASSWORD" | openconnect-sso -s "$OC_URL" ${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT} -- $OPENCONNECT_CMD -elif [[ -n "$OC_USER" ]]; then +if [[ -n "$OC_USER" ]]; then echo "" | openconnect-sso -s "$OC_URL" ${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT} -- $OPENCONNECT_CMD else openconnect-sso -s "$OC_URL" ${OC_SSO_ARGS:-$OC_SSO_ARGS_DEFAULT} -- $OPENCONNECT_CMD @@ -196,12 +160,6 @@ setup_nat() { iptables -t nat -C POSTROUTING -o "$OC_INTERFACE" -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -o "$OC_INTERFACE" -j MASQUERADE echo "NAT enabled on $OC_INTERFACE" - - # Trigger host routing service - if [ -d /runtime ]; then - touch /runtime/restart-routing - echo "Host routing trigger sent" - fi break fi sleep 2