|
|
@@ -0,0 +1,127 @@
|
|
|
+#!/bin/bash
|
|
|
+# ~/.ssh/start-my-tunnel.sh
|
|
|
+# Persistent multi-port SSH tunnel using autossh + systemd
|
|
|
+# Survives suspend, reboot, network changes
|
|
|
+
|
|
|
+# ────────────────────────────────
|
|
|
+# EDIT THIS SECTION ONLY
|
|
|
+# ────────────────────────────────
|
|
|
+USER="root" # Remote SSH user
|
|
|
+HOST="oscara2.hopto.org" # Remote SSH host
|
|
|
+SSH_PORT="4922" # Usually 22, change if needed
|
|
|
+
|
|
|
+# Define your port forwarding map:
|
|
|
+# Format: "local_port:remote_ip:remote_port"
|
|
|
+declare -a FORWARDS=(
|
|
|
+ "3000:192.168.1.38:3000" # ryzen7 Ollama
|
|
|
+ "8188:192.168.1.38:8188" # ryzen7 ComfyUI
|
|
|
+ "3822:192.168.1.38:22" # ryzen7 ssh
|
|
|
+ "11922:192.168.1.119:22" # yazoo ssh
|
|
|
+ "9084:192.168.1.119:9084" # yazoo transmission-gm
|
|
|
+)
|
|
|
+
|
|
|
+# custom identity file (recommended)
|
|
|
+IDENTITY_FILE="$HOME/.ssh/id_ed25519"
|
|
|
+# 1. You're on your home Wi-Fi SSID
|
|
|
+HOME_SSID="W739A" # leave empty to disable SSID check
|
|
|
+
|
|
|
+
|
|
|
+# 2. Your laptop has a specific local IP range (skip this test as it will fail on Franklin router which assigns the same ip range 192.168.1.0 like that at home 39A)
|
|
|
+HOME_IP_PREFIX="192.168.1." # e.g. 192.168.1.0/24 → your home LAN
|
|
|
+# HOME_IP_PREFIX="10.0.0." # uncomment if you use 10.x at home
|
|
|
+
|
|
|
+# 3. You already have the corporate/openconnect/anyconnect VPN up
|
|
|
+VPN_INTERFACE="wg0" # WireGuard example
|
|
|
+
|
|
|
+# 4. Test if you can reach one of the remote destinations directly (ultimate test)
|
|
|
+DIRECT_REACH_TEST="192.168.6.1:22" # IP:port that only works when on VPN or home
|
|
|
+
|
|
|
+# ────────────────────────────────
|
|
|
+# DO NOT EDIT BELOW THIS LINE
|
|
|
+# ────────────────────────────────
|
|
|
+log() { echo "$(date '+%Y-%m-%d %H:%M:%S') | $*"; }
|
|
|
+
|
|
|
+
|
|
|
+# 1. Check if already running → exit cleanly
|
|
|
+if pgrep -f "autossh.*$USER@$HOST" > /dev/null; then
|
|
|
+ log "Tunnel already running – nothing to do."
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+# 2. Are we at home (local IP match)?
|
|
|
+#if [[ -n "$HOME_IP_PREFIX" ]]; then
|
|
|
+# CURRENT_IP=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7}' | head -n1)
|
|
|
+# if [[ "$CURRENT_IP" == "$HOME_IP_PREFIX"* ]]; then
|
|
|
+# log "On home network ($CURRENT_IP) – no tunnel needed."
|
|
|
+# exit 0
|
|
|
+# fi
|
|
|
+#fi
|
|
|
+
|
|
|
+# 3. Are we on home Wi-Fi SSID?
|
|
|
+if [[ -n "$HOME_SSID" && -x /usr/sbin/iwgetid || -x /sbin/iwgetid ]]; then
|
|
|
+ CURRENT_SSID=$(iwgetid -r 2>/dev/null || true)
|
|
|
+ if [[ "$CURRENT_SSID" == "$HOME_SSID" ]]; then
|
|
|
+ log "Connected to home SSID '$HOME_SSID' – skipping tunnel."
|
|
|
+ exit 0
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+# 5. Can we reach a target directly? (most definitive test)
|
|
|
+if [[ -n "$DIRECT_REACH_TEST" ]]; then
|
|
|
+ HOST_PORT=(${DIRECT_REACH_TEST/:/ })
|
|
|
+ if timeout 3 bash -c "cat < /dev/null > /dev/tcp/${HOST_PORT[0]}/${HOST_PORT[1]}" 2>/dev/null; then
|
|
|
+ log "Direct connection to $DIRECT_REACH_TEST works – no tunnel needed."
|
|
|
+ exit 0
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+# If we get here → we really need the tunnel
|
|
|
+log "Outside trusted network/VPN – starting tunnel to $USER@$HOST"
|
|
|
+
|
|
|
+
|
|
|
+# Build the -L arguments for all forwards
|
|
|
+FORWARD_ARGS=""
|
|
|
+for mapping in "${FORWARDS[@]}"; do
|
|
|
+ # Skip empty lines or comments
|
|
|
+ [[ -z "$mapping" || "$mapping" =~ ^[[:space:]]*# ]] && continue
|
|
|
+
|
|
|
+ # Validate format
|
|
|
+ if ! [[ $mapping =~ ^([0-9]+):([^:]+):([0-9]+)$ ]]; then
|
|
|
+ echo "ERROR: Invalid forwarding syntax: $mapping" >&2
|
|
|
+ echo " Expected: local_port:remote_ip:remote_port" >&2
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ LOCAL="${BASH_REMATCH[1]}"
|
|
|
+ REMOTE_IP="${BASH_REMATCH[2]}"
|
|
|
+ REMOTE_PORT="${BASH_REMATCH[3]}"
|
|
|
+
|
|
|
+ FORWARD_ARGS="$FORWARD_ARGS -L $LOCAL:$REMOTE_IP:$REMOTE_PORT"
|
|
|
+done
|
|
|
+
|
|
|
+if [[ -z "$FORWARD_ARGS" ]]; then
|
|
|
+ echo "No valid port forwards defined. Exiting."
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+# Build the final command
|
|
|
+CMD="autossh -M 0 \
|
|
|
+ -o ServerAliveInterval=30 \
|
|
|
+ -o ServerAliveCountMax=3 \
|
|
|
+ -o ExitOnForwardFailure=yes \
|
|
|
+ -o StrictHostKeyChecking=no \
|
|
|
+ -o UserKnownHostsFile=/dev/null \
|
|
|
+ -f -N \
|
|
|
+ $FORWARD_ARGS \
|
|
|
+ ${IDENTITY_FILE:+-i \"$IDENTITY_FILE\"} \
|
|
|
+ $USER@$HOST -p $SSH_PORT"
|
|
|
+
|
|
|
+echo "$(date): Starting/restarting tunnel to $USER@$HOST ($SSH_PORT)"
|
|
|
+echo "Forwards: ${FORWARDS[*]}"
|
|
|
+
|
|
|
+# Execute
|
|
|
+eval $CMD
|
|
|
+
|
|
|
+# Log for debugging
|
|
|
+echo "$(date): autossh command executed (PID: $!)" >> ~/autossh-tunnel.log
|