# 反向 SSH 隧道建立流程 (Windows → Linux)
###### tags: `Data Engineering`
###### 更新日期: `2025-10-09`
---
## 背景說明
假設有以下需求
有一台專門跑 Spark 的遠端主機: remote_Spark_IP (所有排程程式都放在此主機)
且需要連線到 ES (ElasticSearch) 遠端主機: remote_ES_IP 撈資料
但是【Spark 主機和 ES 主機的連線不通】,唯【本機可以連通 ES 主機】
可循本教學的步驟,建立反向隧道讓【Spark ~ ES】跑通
當網管暫時沒空處理或還在等簽呈,也可以先行開發 ES 撈資料的功能
當你的 Windows 電腦位於公司內網、防火牆後或 CrowdStrike 阻擋入站 SSH 時,
你可以改用 **反向 SSH 隧道 (Reverse SSH Tunnel)**:
讓 Windows 主動連線到 Spark 主機 (remote_Spark_IP),
並將遠端 Elasticsearch (remote_ES_IP:9200) 的流量反向映射回 Spark 主機
這樣 Spark 主機即可透過本機埠 (127.0.0.1:19200) 連上 Elasticsearch,
無須直接連 Windows 或外部網路
---
## 先決條件
| 項目 | 描述 |
|------|------|
| Windows 跳板機 | 已安裝 OpenSSH Client (內建於 Win10/11) |
| Spark 主機 (Linux) | 可啟動 SSH Server (Port 22) |
| Elasticsearch | IP: `remote_ES_IP`,Port: `9200` |
| 目標轉發 | Spark 主機可透過 `127.0.0.1:19200` 訪問 ES |
---
## Step 1. 確認 Spark 主機開啟 SSH 服務
在 Spark 主機 (remote_Spark_IP) 上執行:
```bash
sudo apt-get update && sudo apt-get install -y openssh-server
sudo systemctl enable --now ssh
sudo systemctl status ssh
```
若顯示 **active (running)** 即代表 SSH 已啟動
---
## Step 2. 測試 Spark 主機 SSH 是否可用
在 Windows PowerShell 測試:
```powershell
ssh <linux_user>@remote_Spark_IP
```
如果能登入或要求密碼,即代表連線通
---
## Step 3. 在 Windows 建立反向隧道
於 Windows PowerShell(或 CMD)執行以下命令:
```powershell
ssh -N -R 127.0.0.1:19200:remote_ES_IP:9200 <linux_user>@remote_Spark_IP
```
### 參數解釋
| 參數 | 意義 |
|-------|------|
| `-N` | 不執行遠端指令,只建立隧道 |
| `-R` | 建立反向轉發 (remote forwarding) |
| `127.0.0.1:19200` | 在 Spark 主機上建立本地埠 19200 |
| `remote_ES_IP:9200` | 對應的目標地址 (Elasticsearch) |
| `<linux_user>@remote_Spark_IP` | SSH 登入的 Linux 帳號與 IP |
執行後畫面不會有輸出(代表隧道持續連線中)
---
## Step 4. 驗證反向隧道是否成功
在 Spark 主機上執行:
```bash
curl http://127.0.0.1:19200/
```
如果出現 Elasticsearch JSON,如:
```json
{
"name" : "es-node01",
"cluster_name" : "elasticsearch",
"version" : { "number" : "7.10.2" },
"tagline" : "You Know, for Search"
}
```
即代表反向隧道成功運作!
---
## Step 5. 修改 Python 程式設定
在 `es_config.py` 或相關設定檔中修改:
```python
host = "127.0.0.1"
port = 19200
use_ssl = False
```
之後 `collect_es_to_cassandra.py`、`merge_GA_ES.py` 等程式即可透過該隧道讀取 ES
---
## Step 6. 可選強化:持久化隧道
### 方法 A:Windows 背景執行
使用 PowerShell 背景工作:
```powershell
Start-Job { ssh -N -R 127.0.0.1:19200:remote_ES_IP:9200 <linux_user>@remote_Spark_IP }
```
### 方法 B:Windows 啟動時自動執行 (.bat)
建立 `start_reverse_tunnel.bat`:
```bat
@echo off
ssh -N -R 127.0.0.1:19200:remote_ES_IP:9200 <linux_user>@remote_Spark_IP
```
然後放入「啟動資料夾」:
```
C:\Users\<YourUser>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```
---
## Step 7. (可選) 讓其他主機也能使用
預設隧道僅限 Spark 主機 (127.0.0.1)
若希望讓 Spark 同網段的其他主機也能用,
可在 Spark 主機的 `/etc/ssh/sshd_config` 啟用:
```
GatewayPorts clientspecified
```
並重啟 SSH:
```bash
sudo systemctl restart ssh
```
再將建立隧道的命令改為:
```powershell
ssh -N -R 0.0.0.0:19200:remote_ES_IP:9200 <linux_user>@remote_Spark_IP
```
這樣 Spark 主機上任何可訪問它的電腦都能透過該通道存取 ES
---
## 總結
| 角色 | 動作 | 說明 |
|--------|--------|------|
| Windows | 主動建立反向隧道 | 維持連線,將 ES 對映到 Spark 主機 |
| Spark 主機 | 接收轉發 | 透過 127.0.0.1:19200 存取 ES |
| Python 程式 | 連接本地 19200 | 安全、穩定、無需直接外網連線 |