start-tun.sh 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/bin/bash
  2. # ~/.ssh/start-my-tunnel.sh
  3. # Persistent multi-port SSH tunnel using autossh + systemd
  4. # Survives suspend, reboot, network changes
  5. # ────────────────────────────────
  6. # EDIT THIS SECTION ONLY
  7. # ────────────────────────────────
  8. USER="root" # Remote SSH user
  9. HOST="oscara2.hopto.org" # Remote SSH host
  10. SSH_PORT="4922" # Usually 22, change if needed
  11. # Define your port forwarding map:
  12. # Format: "local_port:remote_ip:remote_port"
  13. declare -a FORWARDS=(
  14. "3000:192.168.1.38:3000" # ryzen7 Ollama
  15. "8188:192.168.1.38:8188" # ryzen7 ComfyUI
  16. "3822:192.168.1.38:22" # ryzen7 ssh
  17. "11922:192.168.1.119:22" # yazoo ssh
  18. "9084:192.168.1.119:9084" # yazoo transmission-gm
  19. )
  20. # custom identity file (recommended)
  21. IDENTITY_FILE="$HOME/.ssh/id_ed25519"
  22. # 1. You're on your home Wi-Fi SSID
  23. HOME_SSID="W739A" # leave empty to disable SSID check
  24. # 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)
  25. HOME_IP_PREFIX="192.168.1." # e.g. 192.168.1.0/24 → your home LAN
  26. # HOME_IP_PREFIX="10.0.0." # uncomment if you use 10.x at home
  27. # 3. You already have the corporate/openconnect/anyconnect VPN up
  28. VPN_INTERFACE="wg0" # WireGuard example
  29. # 4. Test if you can reach one of the remote destinations directly (ultimate test)
  30. DIRECT_REACH_TEST="192.168.6.1:22" # IP:port that only works when on VPN or home
  31. # ────────────────────────────────
  32. # DO NOT EDIT BELOW THIS LINE
  33. # ────────────────────────────────
  34. log() { echo "$(date '+%Y-%m-%d %H:%M:%S') | $*"; }
  35. # 1. Check if already running → exit cleanly
  36. if pgrep -f "autossh.*$USER@$HOST" > /dev/null; then
  37. log "Tunnel already running – nothing to do."
  38. exit 0
  39. fi
  40. # 2. Are we at home (local IP match)?
  41. #if [[ -n "$HOME_IP_PREFIX" ]]; then
  42. # CURRENT_IP=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7}' | head -n1)
  43. # if [[ "$CURRENT_IP" == "$HOME_IP_PREFIX"* ]]; then
  44. # log "On home network ($CURRENT_IP) – no tunnel needed."
  45. # exit 0
  46. # fi
  47. #fi
  48. # 3. Are we on home Wi-Fi SSID?
  49. if [[ -n "$HOME_SSID" && -x /usr/sbin/iwgetid || -x /sbin/iwgetid ]]; then
  50. CURRENT_SSID=$(iwgetid -r 2>/dev/null || true)
  51. if [[ "$CURRENT_SSID" == "$HOME_SSID" ]]; then
  52. log "Connected to home SSID '$HOME_SSID' – skipping tunnel."
  53. exit 0
  54. fi
  55. fi
  56. # 5. Can we reach a target directly? (most definitive test)
  57. if [[ -n "$DIRECT_REACH_TEST" ]]; then
  58. HOST_PORT=(${DIRECT_REACH_TEST/:/ })
  59. if timeout 3 bash -c "cat < /dev/null > /dev/tcp/${HOST_PORT[0]}/${HOST_PORT[1]}" 2>/dev/null; then
  60. log "Direct connection to $DIRECT_REACH_TEST works – no tunnel needed."
  61. exit 0
  62. fi
  63. fi
  64. # If we get here → we really need the tunnel
  65. log "Outside trusted network/VPN – starting tunnel to $USER@$HOST"
  66. # Build the -L arguments for all forwards
  67. FORWARD_ARGS=""
  68. for mapping in "${FORWARDS[@]}"; do
  69. # Skip empty lines or comments
  70. [[ -z "$mapping" || "$mapping" =~ ^[[:space:]]*# ]] && continue
  71. # Validate format
  72. if ! [[ $mapping =~ ^([0-9]+):([^:]+):([0-9]+)$ ]]; then
  73. echo "ERROR: Invalid forwarding syntax: $mapping" >&2
  74. echo " Expected: local_port:remote_ip:remote_port" >&2
  75. exit 1
  76. fi
  77. LOCAL="${BASH_REMATCH[1]}"
  78. REMOTE_IP="${BASH_REMATCH[2]}"
  79. REMOTE_PORT="${BASH_REMATCH[3]}"
  80. FORWARD_ARGS="$FORWARD_ARGS -L $LOCAL:$REMOTE_IP:$REMOTE_PORT"
  81. done
  82. if [[ -z "$FORWARD_ARGS" ]]; then
  83. echo "No valid port forwards defined. Exiting."
  84. exit 1
  85. fi
  86. # Build the final command
  87. CMD="autossh -M 0 \
  88. -o ServerAliveInterval=30 \
  89. -o ServerAliveCountMax=3 \
  90. -o ExitOnForwardFailure=yes \
  91. -o StrictHostKeyChecking=no \
  92. -o UserKnownHostsFile=/dev/null \
  93. -f -N \
  94. $FORWARD_ARGS \
  95. ${IDENTITY_FILE:+-i \"$IDENTITY_FILE\"} \
  96. $USER@$HOST -p $SSH_PORT"
  97. echo "$(date): Starting/restarting tunnel to $USER@$HOST ($SSH_PORT)"
  98. echo "Forwards: ${FORWARDS[*]}"
  99. # Execute
  100. eval $CMD
  101. # Log for debugging
  102. echo "$(date): autossh command executed (PID: $!)" >> ~/autossh-tunnel.log