| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #!/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
|