使用 SSH Tunnel, 把 localhost 變成遠端 server

文章目錄

需求

因為要使用 ActivityWatch 來記錄使用資料, 單機跑起來沒有問題, 而我有 3 台 PC, 因此希望能把資料放在一個集中的 server. 本來是想用 Remote server 的方法, 大致上也都通了, 但最後卡在他的 Chrome extension, 因為這個 extension 固定只能送資料給 http://localhost, 作者已經表明不會修改 (參考: https://github.com/ActivityWatch/aw-watcher-web/issues/44), 因此放棄 Remote server 這招, 改用 SSH Tunnel (SSH port forwarding) 來實現需求.

簡單來講, 就是我在一台 server 上跑了一個 service, 他使用的是 port 5600, 而且他 只收 localhost 的連線, 不對外開放, 然後我在 client 的 AP 要連上那個 service.

方法

  1. 啟動 server, 他要去聽 http://localhost:5600
  2. 在 client 上面執行 ssh
    1ssh -L 5600:127.0.0.1:5600 ubuntu@xxx.xxx.xxx.xxx -i '.\xxx.pem' -N
    
    參數說明
    1. -N 是不執行指令
  3. 這時候 client 上的程式, 如果連線到 http://localhost:5600, 他就會連到 server 上的 5600, 而不是 client 上的 5600.

Trouble shooting

  1. 若遇到 Permissions for '.\xxx.pem' are too open. 訊息如下, 那就是檔案權限開大太, SSH 覺得不安全
    1@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    2@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
    3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    4Permissions for '.\\xxx.pem' are too open.
    5It is required that your private key files are NOT accessible by others.
    6This private key will be ignored.
    7Load key ".\\xxx.pem": bad permissions
    8ubuntu@x.x.x.x: Permission denied (publickey).
    
  2. 如果是 Linux 就簡單多了, 直接 chmod 600 xxx.pem 就好. 但可惜我們這次是在 Windows, 解法可參考: https://leesonhsu.blogspot.com/2021/03/ssh-key-windows-permission-denied.html

What's next

  1. 包成 Windows service: 這樣才方便, 不用手動連, 而且應該要有 auto re-connect 功能.
  2. 找找看好用的 Android SSH Tunnel 方案.

其他方案 - SOCAT

socat 也可以做到 port forwarding, 譬如以下指令就會起一個 socat 去收 port 8080, 然後把收到的東西全都轉到 localhost:9090

1socat -v TCP-LISTEN:8080,fork,reuseaddr TCP:localhost:9090