larry1chan@qq.com vor 1 Monat
Commit
e269928465
2 geänderte Dateien mit 242 neuen und 0 gelöschten Zeilen
  1. 115 0
      readme.md
  2. 127 0
      start-tun.sh

+ 115 - 0
readme.md

@@ -0,0 +1,115 @@
+# README – Persistent Home-Lab SSH Tunnel (autossh + systemd)
+
+This setup keeps multiple local ports automatically forwarded to your home lab machines **whenever you are away from home** (coffee shop, hotel, mobile hotspot, etc.).  
+As soon as you come back home or connect to your WireGuard VPN, the tunnel **stops itself** – no duplicate tunnels, no wasted bandwidth.
+
+(this set up has been tested on my ubuntu HP laptop (kirin)
+## What it does
+
+- Forwards these ports from your laptop → home network:
+  - 3000  → ryzen7 Ollama
+  - 8188  → ryzen7 ComfyUI
+  - 3822  → ryzen7 SSH
+  - 11922 → yazoo SSH
+  - 9084  → yazoo Transmission-GM web UI
+- Uses key-based authentication (passwordless)
+- Survives suspend/resume, reboots, Wi-Fi changes, temporary disconnects
+- Automatically disables itself when you are already at home or on your own WireGuard VPN
+
+## Files & Locations
+
+```
+~/.ssh/start-my-tunnel.sh                  ← main script (this file)
+~/.config/systemd/user/my-ssh-tunnel.service ← systemd user service
+~/autossh-tunnel.log                       ← runtime log (optional but useful)
+```
+
+## Prerequisites (done once)
+
+```bash
+# Install autossh
+sudo apt update && sudo apt install autossh
+
+# Make sure your SSH key is in the jump box (oscara2.hopto.org)
+ssh-copy-id root@oscara2.hopto.org -p 4922
+# (or manually paste ~/.ssh/id_ed25519.pub into /root/.ssh/authorized_keys on the jump box)
+```
+
+## Installation steps (copy-paste)
+
+```bash
+# 1. Save the script exactly as-is
+mkdir -p ~/.ssh
+curl -o ~/.ssh/start-my-tunnel.sh https://raw.githubusercontent.com/yourrepo/...   # or just edit it manually
+chmod +x ~/.ssh/start-my-tunnel.sh
+
+# 2. Create the systemd user service
+mkdir -p ~/.config/systemd/user
+cat > ~/.config/systemd/user/my-ssh-tunnel.service <<'EOF'
+[Unit]
+Description=Persistent home-lab SSH tunnel (autossh)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+Restart=always
+RestartSec=10
+ExecStart=/home/%u/.ssh/start-my-tunnel.sh
+Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+
+[Install]
+WantedBy=default.target
+EOF
+
+# 3. Enable and start it
+systemctl --user daemon-reload
+systemctl --user enable --now my-ssh-tunnel.service
+```
+
+That’s it. From now on everything is 100 % automatic.
+
+## How to check everything is working
+
+```bash
+# Quick status
+systemctl --user status my-ssh-tunnel.service
+
+# Live logs
+journalctl --user -u my-ssh-tunnel.service -f
+
+# See the actual listening ports
+ss -ltnp | grep autossh
+
+# Or check the old-school log
+tail -f ~/autossh-tunnel.log
+```
+
+## When the tunnel should NOT start (and it correctly doesn’t)
+
+| Condition                                 | Detection method used                              | Variable in script             |
+|-------------------------------------------|-----------------------------------------------------|--------------------------------|
+| Connected to home Wi-Fi “W739A”           | SSID check via `iwgetid`                            | `HOME_SSID="W739A"`            |
+| Your own WireGuard VPN is up              | Interface `wg0` exists                              | `VPN_INTERFACE="wg0"`          |
+| You can already reach an internal machine | Direct TCP connect test to 192.168.6.1:22           | `DIRECT_REACH_TEST`            |
+
+You can comment-out or modify any of these checks if your setup changes.
+
+## Updating the port list later
+
+Just edit the `FORWARDS=( ... )` array in `~/.ssh/start-my-tunnel.sh` and then restart the service:
+
+```bash
+systemctl --user restart my-ssh-tunnel.service
+```
+
+## Removing everything (if you ever want to)
+
+```bash
+systemctl --user disable --now my-ssh-tunnel.service
+rm ~/.config/systemd/user/my-ssh-tunnel.service
+rm ~/.ssh/start-my-tunnel.sh
+systemctl --user daemon-reload
+```
+
+Enjoy seamless access to Ollama, ComfyUI, and your home servers from anywhere — with zero manual intervention.

+ 127 - 0
start-tun.sh

@@ -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