diff --git a/apps/cistech-tunnel/build/.gitignore b/apps/cistech-tunnel/build/.gitignore new file mode 100644 index 0000000..0746077 --- /dev/null +++ b/apps/cistech-tunnel/build/.gitignore @@ -0,0 +1,2 @@ +# Large binary files - track tar.gz but not 7z +*.7z diff --git a/apps/cistech-tunnel/build/Dockerfile b/apps/cistech-tunnel/build/Dockerfile index c515fe7..ba01395 100644 --- a/apps/cistech-tunnel/build/Dockerfile +++ b/apps/cistech-tunnel/build/Dockerfile @@ -16,22 +16,23 @@ ENV NOVNC_PORT=6080 ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright ENV VIRTUAL_ENV=/opt/venv ENV PATH=/opt/venv/bin:$PATH -ENV QTWEBENGINE_DISABLE_SANDBOX=1 -ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox --disable-gpu" -# Install system dependencies +# Install systemd and dependencies RUN apt-get update && apt-get install -y \ - openconnect \ - iproute2 \ + systemd \ + systemd-sysv \ + dbus \ + dbus-x11 \ + libgtk-3-0 \ + libglib2.0-0 \ + libstdc++6 \ iptables \ - ca-certificates \ - python3 \ - python3-pip \ - python3-venv \ - vpnc-scripts \ - curl \ - wget \ - openssh-client \ + libxml2 \ + network-manager \ + zlib1g \ + policykit-1 \ + xdg-utils \ + libwebkit2gtk-4.0-37 \ tigervnc-standalone-server \ tigervnc-common \ novnc \ @@ -40,66 +41,65 @@ RUN apt-get update && apt-get install -y \ xterm \ procps \ net-tools \ + curl \ + iproute2 \ + iputils-ping \ nano \ x11vnc \ xvfb \ fluxbox \ + xdotool \ oathtool \ - xauth \ + openconnect \ + python3 \ + python3-pip \ + python3-venv \ + vpnc-scripts \ + libasound2 \ libnss3 \ libatk1.0-0 \ libatk-bridge2.0-0 \ - libx11-6 \ - libx11-xcb1 \ libxcomposite1 \ libxrandr2 \ libgbm1 \ libxdamage1 \ libpango-1.0-0 \ fonts-liberation \ - libegl1 \ - libgl1 \ - libopengl0 \ - libdbus-1-3 \ - libglib2.0-0 \ - libxkbcommon0 \ - libxkbcommon-x11-0 \ - libxcb1 \ - libxcb-cursor0 \ - libxcb-icccm4 \ - libxcb-image0 \ - libxcb-keysyms1 \ - libxcb-render0 \ - libxcb-render-util0 \ - libxcb-shm0 \ - libxcb-xfixes0 \ - libxcb-xinerama0 \ - libxcb-randr0 \ - libxcb-glx0 \ - sudo \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -# Install libasound (different package name on different Ubuntu versions) -RUN apt-get update && (apt-get install -y libasound2t64 || apt-get install -y libasound2) && rm -rf /var/lib/apt/lists/* +# Remove unnecessary systemd services that cause issues in containers +RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ + /etc/systemd/system/*.wants/* \ + /lib/systemd/system/local-fs.target.wants/* \ + /lib/systemd/system/sockets.target.wants/*udev* \ + /lib/systemd/system/sockets.target.wants/*initctl* \ + /lib/systemd/system/sysinit.target.wants/systemd-tmpfiles-setup* \ + /lib/systemd/system/systemd-update-utmp* -# Python venv + openconnect-sso + playwright -RUN python3 -m venv "$VIRTUAL_ENV" -RUN pip install --no-cache-dir openconnect-sso[full] playwright keyring keyrings.alt && \ +# Install openconnect-sso with playwright +RUN python3 -m venv "$VIRTUAL_ENV" && \ + pip install --no-cache-dir openconnect-sso[full] playwright keyring keyrings.alt && \ python -m playwright install --with-deps chromium -# Create directories -RUN mkdir -p /opt/scripts /shared /root/.vnc +RUN mkdir -p /opt/scripts /shared +RUN echo 'IyEvYmluL2Jhc2gKc2V0IC1lCmV4cG9ydCBIT01FPScvcm9vdCcKZXhwb3J0IFVTRVI9J3Jvb3QnCnJtIC1mIC90bXAvLlAxLWxvY2sgL3RtcC8uWDExLXVuaXgvWDEgMj4vZGV2L251bGwgfHwgdHJ1ZQpybSAtcmYgL3RtcC8uWCotbG9jayAvdG1wLy5YMTQtdW5peC8qIDI+L2Rldi9udWxsIHx8IHRydWUKZWNobyAiU3RhcnRpbmcgVGlnZXJWTkMgc2VydmVyIG9uIGRpc3BsYXkgOjEuLi4iCnZuY3NlcnZlciA6MSAtZ2VvbWV0cnkgMTI4MHg4MDAgLWRlcHRoIDI0IC1TZWN1cml0eVR5cGVzIFZuY0F1dGggLWxvY2FsaG9zdCBubwpzbGVlcCAyCmVjaG8gIlN0YXJ0aW5nIG5vVk5DIG9uIHBvcnQgJHtOT1ZOQ19QT1JUOi02MDgwfS4uLiIKd2Vic29ja2lmeSAtLXdlYj0vdXNyL3NoYXJlL25vdm5jLyAke05PVk5DX1BPUlQ6LTYwODB9IGxvY2FsaG9zdDo1OTAxICYKdGFpbCAtZiAvcm9vdC8udm5jLyoubG9nCg==' \ +| base64 -d > /opt/scripts/startup-vnc.sh && \ +chmod +x /opt/scripts/startup-vnc.sh -# Create VNC startup script (embedded) -RUN echo 'IyEvYmluL2Jhc2gKc2V0IC1lCmV4cG9ydCBIT01FPScvcm9vdCcKZXhwb3J0IFVTRVI9J3Jvb3QnCnJtIC1mIC90bXAvLlgxLWxvY2sgL3RtcC8uWDExLXVuaXgvWDEgMj4vZGV2L251bGwgfHwgdHJ1ZQpybSAtcmYgL3RtcC8uWCotbG9jayAvdG1wLy5YMTEtdW5peC8qIDI+L2Rldi9udWxsIHx8IHRydWUKZWNobyAiU3RhcnRpbmcgVGlnZXJWTkMgc2VydmVyIG9uIGRpc3BsYXkgOjEuLi4iCnZuY3NlcnZlciA6MSAtZ2VvbWV0cnkgMTI4MHg4MDAgLWRlcHRoIDI0IC1TZWN1cml0eVR5cGVzIFZuY0F1dGggLWxvY2FsaG9zdCBubwpzbGVlcCAyCmVjaG8gIlN0YXJ0aW5nIG5vVk5DIG9uIHBvcnQgJHtOT1ZOQ19QT1JUOi02MDgwfS4uLiIKd2Vic29ja2lmeSAtLXdlYj0vdXNyL3NoYXJlL25vdm5jLyAke05PVk5DX1BPUlQ6LTYwODB9IGxvY2FsaG9zdDo1OTAxICYKdGFpbCAtZiAvcm9vdC8udm5jLyoubG9nCg==' \ - | base64 -d > /opt/scripts/startup-vnc.sh && \ - chmod +x /opt/scripts/startup-vnc.sh +RUN echo 'W1VuaXRdCkRlc2NyaXB0aW9uPVZOQyBhbmQgbm9WTkMgU2VydmVyCkFmdGVyPW5ldHdvcmsudGFyZ2V0CgpbU2VydmljZV0KVHlwZT1zaW1wbGUKRXhlY1N0YXJ0PS9vcHQvc2NyaXB0cy9zdGFydHVwLXZuYy5zaApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTUKRW52aXJvbm1lbnQ9SE9NRT0vcm9vdApFbnZpcm9ubWVudD1VU0VSPXJvb3QKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAo=' \ +| base64 -d > /lib/systemd/system/vnc.service +RUN chmod 644 /lib/systemd/system/vnc.service && \ + systemctl enable vnc.service # Copy entrypoint script COPY scripts/entrypoint.sh /opt/scripts/ RUN chmod +x /opt/scripts/entrypoint.sh +VOLUME ["/sys/fs/cgroup"] + EXPOSE 5901 6080 +STOPSIGNAL SIGRTMIN+3 + CMD ["/opt/scripts/entrypoint.sh"] diff --git a/apps/cistech-tunnel/build/README.md b/apps/cistech-tunnel/build/README.md new file mode 100644 index 0000000..79aefec --- /dev/null +++ b/apps/cistech-tunnel/build/README.md @@ -0,0 +1,51 @@ +# Rego Tunnel - Build Files + +This directory contains the Dockerfile and scripts to build the Cisco VPN Docker image. + +## Files + +- `Dockerfile` - Docker image definition (Ubuntu 22.04 + Cisco Secure Client + noVNC) +- `cisco-secure-client-full.tar.gz` - Pre-extracted Cisco Secure Client 5.1.14.145 +- `build.sh` - Build and push script +- `scripts/entrypoint.sh` - Container entrypoint (starts systemd) + +## Building + +```bash +cd /etc/runtipi/repos/runtipi/apps/rego-tunnel/build +./build.sh +``` + +This builds and pushes to `git.alexzaw.dev/alexz/cisco-vpn:latest` + +To build without pushing: +```bash +docker build -t git.alexzaw.dev/alexz/cisco-vpn:latest . +``` + +## What's in the image + +The Dockerfile creates an image with: +- Ubuntu 22.04 with systemd +- Cisco Secure Client 5.1.14.145 (VPN, DART, Posture modules) +- TigerVNC server + noVNC (web-based VNC) +- Tools: xdotool, oathtool (for TOTP), xclip, openbox + +### Systemd services (baked in) +- `vpnagentd.service` - Cisco VPN agent +- `vnc.service` - VNC server + noVNC websockify + +### Scripts (baked in via base64 in Dockerfile) +- `/opt/scripts/startup-vnc.sh` - Starts VNC server and noVNC +- `/opt/scripts/entrypoint.sh` - Container entrypoint + +## Runtime mounts (from shared/) + +When running as rego-tunnel app, these are mounted from `shared/`: +- `/shared/cisco-vpn` - Main VPN automation script +- `/shared/xstartup` → `/root/.vnc/xstartup` - VNC session startup + +## Ports + +- `5901` - VNC server +- `6080` - noVNC web interface diff --git a/apps/cistech-tunnel/build/build.sh b/apps/cistech-tunnel/build/build.sh index e08a4ba..5a4bed2 100644 --- a/apps/cistech-tunnel/build/build.sh +++ b/apps/cistech-tunnel/build/build.sh @@ -16,7 +16,7 @@ echo "" echo "Build complete!" echo "" echo "To test locally:" -echo " docker run -d --privileged --cap-add=NET_ADMIN --device=/dev/net/tun -p 5901:5901 -p 6080:6080 -e VNC_PASSWORD=test ${IMAGE_NAME}:${IMAGE_TAG}" +echo " docker run -d --privileged --cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw --cap-add=NET_ADMIN --device=/dev/net/tun -p 5901:5901 -p 6080:6080 ${IMAGE_NAME}:${IMAGE_TAG}" echo "" echo "Then connect via VNC to localhost:5901 or open noVNC at http://localhost:6080/vnc.html" -echo "" +echo "" \ No newline at end of file diff --git a/apps/cistech-tunnel/build/scripts/entrypoint.sh b/apps/cistech-tunnel/build/scripts/entrypoint.sh index 825d9d4..71ce4f6 100644 --- a/apps/cistech-tunnel/build/scripts/entrypoint.sh +++ b/apps/cistech-tunnel/build/scripts/entrypoint.sh @@ -1,16 +1,16 @@ #!/bin/bash -# Entrypoint: VNC password setup + DNS fix + start VNC +# Entrypoint: VNC password setup + DNS fix + systemd set -euo pipefail -# Setup TigerVNC password file from env var +# Setup TigerVNC password file from env var (passed by runtipi) +# TigerVNC expects /root/.vnc/passwd when using SecurityTypes=VncAuth. if [ -n "${VNC_PASSWORD:-}" ]; then mkdir -p /root/.vnc printf '%s\n%s\n' "$VNC_PASSWORD" "$VNC_PASSWORD" | vncpasswd -f > /root/.vnc/passwd chmod 600 /root/.vnc/passwd fi -# DNS fix for containers cp /etc/resolv.conf /tmp/resolv.conf.bak 2>/dev/null || true cp /etc/hosts /tmp/hosts.bak 2>/dev/null || true umount /etc/resolv.conf 2>/dev/null || true @@ -18,25 +18,7 @@ umount /etc/hosts 2>/dev/null || true 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 -# Enable IP forwarding echo 1 > /proc/sys/net/ipv4/ip_forward echo "[entrypoint] IP forwarding enabled" -# Clean up stale X locks -rm -f /tmp/.X1-lock /tmp/.X11-unix/X1 2>/dev/null || true - -# Start VNC server -echo "[entrypoint] Starting TigerVNC server..." -mkdir -p /root/.vnc -vncserver :1 -geometry 1280x800 -depth 24 -SecurityTypes VncAuth -localhost no - -# Wait for VNC to start -sleep 2 - -# Start noVNC websockify -echo "[entrypoint] Starting noVNC on port ${NOVNC_PORT:-6080}..." -websockify --web=/usr/share/novnc/ ${NOVNC_PORT:-6080} localhost:5901 & - -# Keep container running -echo "[entrypoint] VNC ready. Tailing logs..." -tail -f /root/.vnc/*.log +exec /sbin/init diff --git a/apps/cistech-tunnel/docker-compose.json b/apps/cistech-tunnel/docker-compose.json index f4e57ae..e46a95b 100755 --- a/apps/cistech-tunnel/docker-compose.json +++ b/apps/cistech-tunnel/docker-compose.json @@ -18,6 +18,7 @@ { "hostPath": "${APP_DATA_DIR}/config", "containerPath": "/config", "readOnly": false }, { "hostPath": "${APP_DATA_DIR}", "containerPath": "/runtime", "readOnly": false }, { "hostPath": "/etc/runtipi/repos/runtipi/apps/cistech-tunnel/shared", "containerPath": "/shared", "readOnly": false }, + { "hostPath": "/sys/fs/cgroup", "containerPath": "/sys/fs/cgroup", "readOnly": false }, { "hostPath": "/etc/runtipi/repos/runtipi/apps/cistech-tunnel/shared/xstartup", "containerPath": "/root/.vnc/xstartup", "readOnly": true } ], "stopGracePeriod": "30s", diff --git a/apps/cistech-tunnel/shared/host-routing.sh b/apps/cistech-tunnel/shared/host-routing.sh index c796301..be818f9 100644 --- a/apps/cistech-tunnel/shared/host-routing.sh +++ b/apps/cistech-tunnel/shared/host-routing.sh @@ -1,22 +1,22 @@ #!/usr/bin/env bash # -# Host routing script for cistech-tunnel -# Routes target subnets through the VPN container +# Host routing script for rego-tunnel +# Routes TARGET_IP 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" +# Fixed configuration (we assigned these) +CONTAINER_IP="172.31.0.10" +BRIDGE_NAME="br-rego-vpn" +TARGET_IP="${TARGET_IP:-10.35.33.230}" LAN_SUBNET="192.168.0.0/23" LAN_INTERFACES="eth0 eth1 wlan0" -LOG_FILE="/var/log/cistech-routing.log" +LOG_FILE="/var/log/rego-routing.log" log() { - local msg="[$(date '+%Y-%m-%d %H:%M:%S')] [cistech-routing] $*" + local msg="[$(date '+%Y-%m-%d %H:%M:%S')] [rego-routing] $*" echo "$msg" | tee -a "$LOG_FILE" >&2 } @@ -25,10 +25,12 @@ get_lan_interface() { } remove_routes() { - log "Removing stale routes..." - for subnet in $TARGET_SUBNETS; do - ip route del "$subnet" 2>/dev/null || true - done + log "Removing stale routes for $TARGET_IP..." + + # Remove any existing route to TARGET_IP + ip route del "$TARGET_IP" 2>/dev/null || true + ip route del "$TARGET_IP/32" 2>/dev/null || true + log "Stale routes removed" } @@ -39,35 +41,35 @@ apply_routes() { log "Applying host routing rules..." log " Container IP: $CONTAINER_IP" log " Bridge: $BRIDGE_NAME" - log " Target subnets: $TARGET_SUBNETS" + log " Target IP: $TARGET_IP" 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 + # Add route to TARGET_IP via container + ip route replace "$TARGET_IP/32" via "$CONTAINER_IP" dev "$BRIDGE_NAME" + log "Route added: $TARGET_IP via $CONTAINER_IP dev $BRIDGE_NAME" # Allow forwarding in DOCKER-USER chain for all LAN interfaces for lan_if in $LAN_INTERFACES; do + # Check if interface exists 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 traffic from LAN to container for TARGET_IP + iptables -C DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -j ACCEPT 2>/dev/null || \ + iptables -I DOCKER-USER 1 -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -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 + iptables -C DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \ + iptables -I DOCKER-USER 1 -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate 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) + # Masquerade traffic from LAN subnet to VPN bridge (so return traffic routes correctly) + # Use nft since iptables-nft backend doesn't support iptables -t nat commands 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" @@ -75,21 +77,19 @@ apply_routes() { log "NAT masquerade rule already exists for $LAN_SUBNET -> $BRIDGE_NAME" fi - log "OK: Host routing applied" + log "OK: Host routing applied - $TARGET_IP via $CONTAINER_IP ($BRIDGE_NAME)" } 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 route + ip route del "$TARGET_IP/32" via "$CONTAINER_IP" dev "$BRIDGE_NAME" 2>/dev/null || true # 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 + iptables -D DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -j ACCEPT 2>/dev/null || true + iptables -D DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true done # Remove masquerade rule (using nft) diff --git a/apps/cistech-tunnel/shared/install-host-services.sh b/apps/cistech-tunnel/shared/install-host-services.sh index 8ad7fc7..56e09ac 100644 --- a/apps/cistech-tunnel/shared/install-host-services.sh +++ b/apps/cistech-tunnel/shared/install-host-services.sh @@ -1,68 +1,55 @@ #!/usr/bin/env bash # -# Install host-side systemd services for cistech-tunnel -# Run this ONCE on the host after app install +# Install host-side systemd services for rego-tunnel +# Run this ONCE on the host after installing the app in Runtipi # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -APP_DATA_DIR="/etc/runtipi/app-data/runtipi/cistech-tunnel" +APP_DATA_DIR="/etc/runtipi/app-data/runtipi/rego-tunnel" -echo "Installing cistech-tunnel host services..." +echo "Installing rego-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 +# Create the path watcher unit +cat << 'EOF' | sudo tee /etc/systemd/system/rego-routing-watcher.path [Unit] -Description=Watch for cistech-tunnel routing trigger +Description=Watch for rego-tunnel routing trigger [Path] -PathExists=$APP_DATA_DIR/restart-routing -Unit=cistech-routing-watcher.service +PathExists=/etc/runtipi/app-data/runtipi/rego-tunnel/restart-routing +Unit=rego-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 +# Create the service unit +cat << EOF | sudo tee /etc/systemd/system/rego-routing-watcher.service [Unit] -Description=Apply cistech-tunnel routing rules +Description=Apply rego-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' +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" +sudo 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 +sudo systemctl enable --now rego-routing-watcher.path echo "" -echo "Done! Watcher installed and routes applied." +echo "Done! Services installed:" +echo " - rego-routing-watcher.path (watches for trigger file)" +echo " - rego-routing-watcher.service (applies routing rules)" echo "" -echo "To trigger route refresh from container:" -echo " touch /runtime/restart-routing" +echo "To check status:" +echo " systemctl status rego-routing-watcher.path" echo "" -echo "To check watcher status:" -echo " systemctl status cistech-routing-watcher.path" +echo "To manually trigger routing:" +echo " touch ${APP_DATA_DIR}/restart-routing" diff --git a/apps/cistech-tunnel/shared/openconnect-vpn b/apps/cistech-tunnel/shared/openconnect-vpn old mode 100644 new mode 100755 index 350fe64..7abddb4 --- a/apps/cistech-tunnel/shared/openconnect-vpn +++ b/apps/cistech-tunnel/shared/openconnect-vpn @@ -1,33 +1,17 @@ #!/bin/bash # Cistech VPN Connection Script with OpenConnect SSO -# Usage: ./openconnect-vpn [-c|--connect] [-d|--disconnect] [-m|--menu] [-r|--routes] [-s|--status] [--help] +# Uses config.toml for configuration, openconnect-sso handles auto-connect -# Credentials from environment variables (set by runtipi) +# Credentials from environment variables OC_URL="${OC_URL:-}" OC_USER="${OC_USER:-}" OC_PASSWORD="${OC_PASSWORD:-}" OC_TOTP_SECRET="${OC_TOTP_SECRET:-}" -OC_SERVERCERT="${OC_SERVERCERT:-}" OC_INTERFACE="${OC_INTERFACE:-tun0}" -OC_AUTHGROUP="${OC_AUTHGROUP:-}" -OC_USERAGENT="${OC_USERAGENT:-}" -OC_EXTRA_ARGS="${OC_EXTRA_ARGS:-}" -# Log directory -LOG_DIR="/var/log/openconnect-vpn" -LOG_RETENTION_DAYS=7 -mkdir -p "$LOG_DIR" 2>/dev/null - -# Get current log file (changes daily) -get_log_file() { - echo "$LOG_DIR/$(date '+%Y-%m-%d').log" -} - -# Cleanup old logs -cleanup_old_logs() { - find "$LOG_DIR" -name "*.log" -type f -mtime +$LOG_RETENTION_DAYS -delete 2>/dev/null -} +CONFIG_DIR="$HOME/.config/openconnect-sso" +CONFIG_FILE="$CONFIG_DIR/config.toml" # Colors RED='\033[0;31m' @@ -37,48 +21,6 @@ CYAN='\033[0;36m' GRAY='\033[0;90m' NC='\033[0m' -# Flags -SKIP_AUTO_LOGIN=false -DO_CONNECT=false -DO_DISCONNECT=false - -# Logging function -log() { - local level="$1" - local msg="$2" - local timestamp=$(date '+%Y-%m-%d %H:%M:%S') - local timestamp_short=$(date '+%H:%M:%S') - local log_file=$(get_log_file) - - local msg_plain=$(echo -e "$msg" | sed 's/\x1b\[[0-9;]*m//g') - echo "[$timestamp] [$level] $msg_plain" >> "$log_file" - - case $level in - INFO) echo -e "${GRAY}[$timestamp_short]${NC} ${GREEN}[INFO]${NC} $msg" ;; - WARN) echo -e "${GRAY}[$timestamp_short]${NC} ${YELLOW}[WARN]${NC} $msg" ;; - ERROR) echo -e "${GRAY}[$timestamp_short]${NC} ${RED}[ERROR]${NC} $msg" ;; - DEBUG) echo -e "${GRAY}[$timestamp_short]${NC} ${CYAN}[DEBUG]${NC} $msg" ;; - CMD) echo -e "${GRAY}[$timestamp_short]${NC} ${GRAY}[CMD]${NC} $msg" ;; - *) echo -e "${GRAY}[$timestamp_short]${NC} $msg" ;; - esac -} - -# Run command with logging -run_cmd() { - local desc="$1" - shift - log CMD "$desc: $*" - output=$("$@" 2>&1) - local rc=$? - if [ -n "$output" ]; then - echo "$output" | while IFS= read -r line; do - echo -e " ${GRAY}|${NC} $line" - done - fi - return $rc -} - -# Print banner print_banner() { echo -e "${CYAN}========================================${NC}" echo -e "${CYAN} Cistech VPN Connection Script ${NC}" @@ -86,457 +28,165 @@ print_banner() { echo "" } -# Show help -show_help() { - echo -e "${CYAN}Cistech VPN Connection Script${NC}" - echo "" - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " -c, --connect Start VPN connection and exit" - echo " -d, --disconnect Disconnect VPN and exit" - echo " -m, --menu Skip auto-connect, show menu directly" - echo " -r, --routes Show current routing table and exit" - echo " -s, --status Show VPN and network status and exit" - echo " --help Show this help message" +log() { + local level="$1" + local msg="$2" + local ts=$(date '+%H:%M:%S') + case $level in + INFO) echo -e "${GRAY}[$ts]${NC} ${GREEN}[INFO]${NC} $msg" ;; + WARN) echo -e "${GRAY}[$ts]${NC} ${YELLOW}[WARN]${NC} $msg" ;; + ERROR) echo -e "${GRAY}[$ts]${NC} ${RED}[ERROR]${NC} $msg" ;; + DEBUG) echo -e "${GRAY}[$ts]${NC} ${CYAN}[DEBUG]${NC} $msg" ;; + *) echo -e "${GRAY}[$ts]${NC} $msg" ;; + esac } -# Auto-fetch server certificate pin -get_server_cert_pin() { - local url="$1" - local host=$(echo "$url" | sed -E 's|https?://([^/:]+).*|\1|') - local port=443 - - log DEBUG "Fetching certificate pin from $host:$port..." - - 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 - log ERROR "Failed to fetch certificate from $host" - return 1 - fi -} - -# Get current TOTP get_totp() { - if [ -n "$OC_TOTP_SECRET" ]; then - oathtool --totp -b "$OC_TOTP_SECRET" - fi + [ -n "$OC_TOTP_SECRET" ] && oathtool --totp -b "$OC_TOTP_SECRET" } -# Check if VPN is connected get_vpn_interface() { ip link show "$OC_INTERFACE" 2>/dev/null | grep -q "UP" && echo "$OC_INTERFACE" } get_vpn_ip() { local iface=$(get_vpn_interface) - if [ -n "$iface" ]; then - ip addr show "$iface" 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1 - fi + [ -n "$iface" ] && ip addr show "$iface" 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1 } -get_container_ip() { - ip addr show eth0 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1 -} - -# Check VPN status check_vpn_status() { local vpn_iface=$(get_vpn_interface) if [ -n "$vpn_iface" ]; then - local vpn_ip=$(get_vpn_ip) - log INFO "VPN is ${GREEN}CONNECTED${NC}" - log DEBUG " Interface: $vpn_iface" - log DEBUG " VPN IP: $vpn_ip" + log INFO "VPN: ${GREEN}CONNECTED${NC} ($(get_vpn_ip))" return 0 else - log WARN "VPN is ${RED}NOT CONNECTED${NC}" + log WARN "VPN: ${RED}NOT CONNECTED${NC}" return 1 fi } -# Setup keyring with TOTP secret setup_keyring() { if [[ -n "$OC_TOTP_SECRET" && -n "$OC_USER" ]]; then python3 -c " import keyring keyring.set_password('openconnect-sso', 'totp/$OC_USER', '$OC_TOTP_SECRET'.upper()) -print('TOTP secret stored in keyring for $OC_USER') -" +" 2>/dev/null && log INFO "TOTP stored in keyring" fi } -# Kill openconnect processes -kill_vpn_processes() { - log INFO "Killing VPN processes..." - local killed=0 +setup_config() { + mkdir -p "$CONFIG_DIR" - for pid in $(pgrep -f "openconnect" 2>/dev/null); do - log DEBUG "Killing openconnect (PID $pid)" - kill -9 "$pid" 2>/dev/null && ((killed++)) - done + # Determine browser display mode + local browser_mode="hidden" + [ -z "$OC_USER" ] && browser_mode="shown" - for pid in $(pgrep -f "openconnect-sso" 2>/dev/null); do - log DEBUG "Killing openconnect-sso (PID $pid)" - kill -9 "$pid" 2>/dev/null && ((killed++)) - done + cat > "$CONFIG_FILE" << EOF +[openconnect] +server = "$OC_URL" +interface = "$OC_INTERFACE" - if [ $killed -eq 0 ]; then - log INFO "No VPN processes were running" - else - log INFO "Killed $killed process(es)" - sleep 1 - fi +[sso] +browser_display_mode = "$browser_mode" +EOF + + [ -n "$OC_USER" ] && echo "user = \"$OC_USER\"" >> "$CONFIG_FILE" + + log INFO "Config written to $CONFIG_FILE" } -# Disconnect VPN -disconnect_vpn() { - log INFO "Disconnecting VPN..." - kill_vpn_processes - - if check_vpn_status; then - log WARN "VPN still appears connected" - return 1 - fi - - log INFO "VPN disconnected" - return 0 -} - -# Setup IP forwarding setup_forwarding() { log INFO "Setting up IP forwarding..." - local vpn_iface=$(get_vpn_interface) if [ -z "$vpn_iface" ]; then - log ERROR "No VPN interface found! Is VPN connected?" + log ERROR "No VPN interface found!" return 1 fi - - run_cmd "Enabling IP forwarding" sysctl -w net.ipv4.ip_forward=1 - - # NAT masquerade for traffic going through VPN - if ! iptables -t nat -C POSTROUTING -o "$vpn_iface" -j MASQUERADE 2>/dev/null; then - run_cmd "Adding NAT masquerade" iptables -t nat -A POSTROUTING -o "$vpn_iface" -j MASQUERADE - fi - - # Trigger host routing service - log INFO "Triggering host routing service..." - touch /runtime/restart-routing - sleep 2 - if [ ! -f /runtime/restart-routing ]; then - log INFO "Host routing service restarted" - else - log WARN "Host watcher may not be running" - fi - + sysctl -w net.ipv4.ip_forward=1 >/dev/null + iptables -t nat -C POSTROUTING -o "$vpn_iface" -j MASQUERADE 2>/dev/null || \ + iptables -t nat -A POSTROUTING -o "$vpn_iface" -j MASQUERADE + touch /runtime/restart-routing 2>/dev/null log INFO "Forwarding configured" } -# Show routing table -show_routes() { - echo -e "${CYAN}========================================${NC}" - echo -e "${CYAN} Current Routing Table ${NC}" - echo -e "${CYAN}========================================${NC}" +kill_vpn() { + log INFO "Stopping VPN..." + pkill -f "openconnect" 2>/dev/null + sleep 1 +} + +start_vpn() { + log INFO "Starting OpenConnect SSO..." + + setup_keyring + setup_config + + log INFO "Credentials:" + echo -e " ${CYAN}URL: $OC_URL${NC}" + echo -e " ${CYAN}User: $OC_USER${NC}" + [ -n "$OC_TOTP_SECRET" ] && echo -e " ${CYAN}TOTP: $(get_totp)${NC}" echo "" - echo -e "${GREEN}IPv4 Routes:${NC}" - ip -4 route show | while IFS= read -r line; do - if echo "$line" | grep -qE "tun[0-9]"; then - echo -e " ${YELLOW}$line${NC}" - else - echo " $line" - fi - done - echo "" - echo -e "${GREEN}VPN Interface:${NC}" - local vpn_iface=$(get_vpn_interface) - if [ -n "$vpn_iface" ]; then - ip addr show "$vpn_iface" 2>/dev/null | grep -E "inet|link" | while IFS= read -r line; do - echo " $line" - done + + # Run openconnect-sso (it handles reconnection) + if [[ -n "$OC_PASSWORD" ]]; then + echo "$OC_PASSWORD" | openconnect-sso else - echo -e " ${RED}No VPN interface found${NC}" + echo "" | openconnect-sso fi } -# Show network status -show_network_status() { - log INFO "Current network status:" - - echo "" - log DEBUG "Network Interfaces:" - ip -4 addr show | grep -E "inet |^[0-9]+:" | while IFS= read -r line; do - echo -e " ${GRAY}|${NC} $line" - done - - echo "" - local vpn_iface=$(get_vpn_interface) - if [ -n "$vpn_iface" ]; then - local vpn_ip=$(get_vpn_ip) - log INFO "VPN Status: ${GREEN}CONNECTED${NC}" - log DEBUG " Interface: $vpn_iface" - log DEBUG " VPN IP: $vpn_ip" - else - log WARN "VPN Status: ${RED}NOT CONNECTED${NC}" - fi - - local container_ip=$(get_container_ip) - if [ -n "$container_ip" ]; then - log DEBUG "Container IP: $container_ip" - fi - - echo "" -} - -# Print TOTP show_totp() { - if [ -z "$OC_TOTP_SECRET" ]; then - log ERROR "TOTP secret not configured" - return 1 - fi - - log INFO "Starting live TOTP display (Ctrl+C to stop)" - echo "" + [ -z "$OC_TOTP_SECRET" ] && { log ERROR "No TOTP secret"; return 1; } + log INFO "Live TOTP (Ctrl+C to stop)" while true; do - TOTP=$(get_totp) - SECONDS_LEFT=$((30 - ($(date +%s) % 30))) - echo -ne "\r ${CYAN}Current TOTP:${NC} ${GREEN}$TOTP${NC} (expires in ${YELLOW}${SECONDS_LEFT}s${NC}) " + echo -ne "\r TOTP: ${GREEN}$(get_totp)${NC} (${YELLOW}$((30 - $(date +%s) % 30))s${NC}) " sleep 1 done } -# Start VPN connection -start_vpn() { - local do_auto_login="$1" - log INFO "=== Starting OpenConnect VPN ===" - echo "" - - # Kill existing - kill_vpn_processes - - # Get server cert if not set - if [[ -z "$OC_SERVERCERT" ]]; then - log INFO "Fetching server certificate..." - OC_SERVERCERT=$(get_server_cert_pin "$OC_URL") - log DEBUG "Server cert: $OC_SERVERCERT" - fi - - # Setup keyring for TOTP - setup_keyring - - # Build openconnect command - OPENCONNECT_CMD="/usr/sbin/openconnect --protocol=anyconnect --servercert $OC_SERVERCERT --interface $OC_INTERFACE --script /usr/share/vpnc-scripts/vpnc-script" - [[ -n "$OC_AUTHGROUP" ]] && OPENCONNECT_CMD+=" --authgroup $OC_AUTHGROUP" - [[ -n "$OC_USERAGENT" ]] && OPENCONNECT_CMD+=" --useragent $OC_USERAGENT" - [[ -n "$OC_EXTRA_ARGS" ]] && OPENCONNECT_CMD+=" $OC_EXTRA_ARGS" - - # Determine SSO args - if [[ -n "$OC_USER" ]]; then - OC_SSO_ARGS="--browser-display-mode hidden -u $OC_USER" - else - OC_SSO_ARGS="--browser-display-mode shown" - fi - - # Show credentials - log INFO "Credentials:" - echo -e " ${CYAN}URL: $OC_URL${NC}" - echo -e " ${CYAN}User: $OC_USER${NC}" - if [ -n "$OC_PASSWORD" ]; then - echo -e " ${CYAN}Password: (set)${NC}" - fi - if [ -n "$OC_TOTP_SECRET" ]; then - TOTP=$(get_totp) - echo -e " ${CYAN}TOTP: $TOTP${NC}" - fi - echo "" - - log INFO "Launching openconnect-sso..." - - # Run openconnect-sso - if [[ -n "$OC_USER" && -n "$OC_PASSWORD" ]]; then - echo "$OC_PASSWORD" | openconnect-sso -s "$OC_URL" $OC_SSO_ARGS -- $OPENCONNECT_CMD & - elif [[ -n "$OC_USER" ]]; then - echo "" | openconnect-sso -s "$OC_URL" $OC_SSO_ARGS -- $OPENCONNECT_CMD & - else - openconnect-sso -s "$OC_URL" $OC_SSO_ARGS -- $OPENCONNECT_CMD & - fi - VPN_PID=$! - - # Wait for connection - log INFO "Waiting for VPN connection..." - local wait_count=0 - local max_wait=120 - while [ -z "$(get_vpn_interface)" ]; do - sleep 2 - ((wait_count+=2)) - if [ $((wait_count % 10)) -eq 0 ]; then - log DEBUG "Still waiting... (${wait_count}s)" - fi - if [ $wait_count -ge $max_wait ]; then - log ERROR "Timeout waiting for VPN after ${max_wait}s" - return 1 - fi - # Check if process died - if ! kill -0 $VPN_PID 2>/dev/null; then - log ERROR "openconnect-sso process died" - return 1 - fi - done - - log INFO "VPN connected!" - local vpn_ip=$(get_vpn_ip) - log DEBUG " Interface: $OC_INTERFACE" - log DEBUG " VPN IP: $vpn_ip" - - sleep 3 - setup_forwarding - - log INFO "VPN setup complete" - return 0 -} - -# Main menu main_menu() { echo -e "${GREEN}Options:${NC}" - echo -e " ${CYAN}1${NC} - Start VPN connection" - echo -e " ${CYAN}2${NC} - Disconnect VPN" - echo -e " ${CYAN}3${NC} - Show live TOTP" - echo -e " ${CYAN}4${NC} - Setup IP forwarding rules" - echo -e " ${CYAN}5${NC} - Show network status" - echo -e " ${CYAN}6${NC} - Show routing table" - echo -e " ${CYAN}7${NC} - Kill VPN processes" + echo -e " ${CYAN}1${NC} - Start VPN" + echo -e " ${CYAN}2${NC} - Stop VPN" + echo -e " ${CYAN}3${NC} - Show TOTP" + echo -e " ${CYAN}4${NC} - Setup forwarding" + echo -e " ${CYAN}5${NC} - Check status" + echo -e " ${CYAN}6${NC} - Show routes" echo -e " ${CYAN}q${NC} - Quit" echo "" } -# Watchdog -start_watchdog() { - log INFO "Starting VPN watchdog (check every 60s)..." - - local check_interval=60 - local reconnect_attempts=0 - local max_reconnect_attempts=3 - - while true; do - sleep $check_interval - - local vpn_iface=$(get_vpn_interface) - - if [ -n "$vpn_iface" ]; then - reconnect_attempts=0 - else - ((reconnect_attempts++)) - log WARN "VPN disconnected! Attempt $reconnect_attempts/$max_reconnect_attempts..." - - if [ $reconnect_attempts -le $max_reconnect_attempts ]; then - kill_vpn_processes - sleep 2 - start_vpn "true" & - - local wait_count=0 - while [ -z "$(get_vpn_interface)" ] && [ $wait_count -lt 120 ]; do - sleep 2 - ((wait_count+=2)) - done - - if [ -n "$(get_vpn_interface)" ]; then - log INFO "VPN reconnected!" - reconnect_attempts=0 - else - log ERROR "Reconnect failed" - fi - else - log ERROR "Max reconnect attempts reached" - sleep 300 - reconnect_attempts=0 - fi - fi - done -} - # Parse args -parse_args() { - while [[ $# -gt 0 ]]; do - case $1 in - -c|--connect) - DO_CONNECT=true - shift - ;; - -d|--disconnect) - DO_DISCONNECT=true - shift - ;; - -m|--menu) - SKIP_AUTO_LOGIN=true - shift - ;; - -r|--routes) - show_routes - exit 0 - ;; - -s|--status) - print_banner - check_vpn_status - echo "" - show_network_status - exit 0 - ;; - --help) - show_help - exit 0 - ;; - *) - echo "Unknown option: $1" - exit 1 - ;; - esac - done -} +for arg in "$@"; do + case $arg in + -m|--menu) SKIP_AUTO=true ;; + -s|--status) check_vpn_status; exit 0 ;; + --help) echo "Usage: $0 [-m|--menu] [-s|--status]"; exit 0 ;; + esac +done # Main -parse_args "$@" -cleanup_old_logs - -echo "" >> "$(get_log_file)" -log INFO "openconnect-vpn script started" -log DEBUG "OC_URL=$OC_URL" -log DEBUG "OC_USER=$OC_USER" - print_banner +log INFO "openconnect-vpn started" -if [ "$DO_DISCONNECT" = "true" ]; then - disconnect_vpn - exit $? -fi - -if [ "$DO_CONNECT" = "true" ]; then - start_vpn "true" - exit $? -fi - -# Check current status or auto-connect -if [ "$SKIP_AUTO_LOGIN" = "true" ]; then +if [ "${SKIP_AUTO:-false}" = "true" ]; then log INFO "Menu mode - skipping auto-connect" elif check_vpn_status; then - echo "" - log INFO "VPN already connected. Setting up forwarding..." setup_forwarding else - echo "" - log INFO "Auto-starting VPN connection..." - echo "" - if start_vpn "true"; then - # Start watchdog in background - start_watchdog & - WATCHDOG_PID=$! - log DEBUG "Watchdog started (PID $WATCHDOG_PID)" - fi + log INFO "Auto-starting VPN..." + start_vpn & + VPN_PID=$! + + # Wait for connection + for i in {1..60}; do + sleep 2 + if [ -n "$(get_vpn_interface)" ]; then + log INFO "VPN connected!" + setup_forwarding + break + fi + done fi # Menu loop @@ -546,18 +196,14 @@ while true; do echo -ne "${CYAN}Choice: ${NC}" read -r choice echo "" - [[ -z "${choice// }" ]] && continue - case $choice in - 1) start_vpn "true" && { start_watchdog & } ;; - 2) disconnect_vpn ;; + 1) start_vpn ;; + 2) kill_vpn ;; 3) show_totp ;; 4) setup_forwarding ;; - 5) show_network_status ;; - 6) show_routes ;; - 7) kill_vpn_processes ;; + 5) check_vpn_status ;; + 6) ip -4 route show ;; q|Q) log INFO "Goodbye!"; exit 0 ;; - *) ;; esac done diff --git a/apps/cistech-tunnel/shared/uninstall-host-services.sh b/apps/cistech-tunnel/shared/uninstall-host-services.sh index 743b62b..b76a920 100644 --- a/apps/cistech-tunnel/shared/uninstall-host-services.sh +++ b/apps/cistech-tunnel/shared/uninstall-host-services.sh @@ -1,21 +1,21 @@ #!/usr/bin/env bash # -# Uninstall host-side systemd services for cistech-tunnel +# Uninstall host-side systemd services for rego-tunnel # set -euo pipefail -echo "Removing cistech-tunnel host services..." +echo "Removing rego-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 +sudo systemctl stop rego-routing-watcher.path 2>/dev/null || true +sudo systemctl disable rego-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 +/etc/runtipi/repos/runtipi/apps/rego-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 +sudo rm -f /etc/systemd/system/rego-routing-watcher.path +sudo rm -f /etc/systemd/system/rego-routing-watcher.service # Reload systemd sudo systemctl daemon-reload diff --git a/apps/cistech-tunnel/shared/xstartup b/apps/cistech-tunnel/shared/xstartup index 73985f6..5542a79 100644 --- a/apps/cistech-tunnel/shared/xstartup +++ b/apps/cistech-tunnel/shared/xstartup @@ -5,7 +5,7 @@ unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS # Import environment variables from container (PID 1) -# VNC doesn't inherit Docker env vars, so we source them here +# Systemd services don't inherit Docker env vars, so we source them here while IFS= read -r -d '' line; do export "$line" done < /proc/1/environ @@ -14,7 +14,7 @@ export XDG_RUNTIME_DIR=/tmp/runtime-root mkdir -p $XDG_RUNTIME_DIR chmod 700 $XDG_RUNTIME_DIR -# GPU/WebKit workarounds +# GPU/WebKit workarounds for browser export GDK_BACKEND=x11 export WEBKIT_DISABLE_DMABUF_RENDERER=1