Pages

Thursday, 5 August 2021

利用本地電腦建立隧道供無法連結外網的遠程服務器上網

 

當本地電腦可以透過 SSH 連結遠程服務器,遠程服務器無法連結外網時,可以利用 ssh -R 建立隧道,以本地電腦為跳板供遠程服務器連結外網。

環境

  1. 可以訪問外網(百度或谷歌)的電腦 A,可以是我們自己的電腦或局域網內的電腦
  2. 無法訪問外網的遠程服務器 B
  3. 其他用戶 C,D,E …
  4. A,C,D,E 可以透過 SSH 連接到 B

原理

A,C,D,E —Intra/Internet—> B —SSH Port Forwaring—> A —Internet—-> 外網

方法 1: SOCKS5

在本地搭建一個 socks5 服務端,將端口映射到遠程服務器上。以下用 Ubuntu 20.04 示範

搭建 SOCKS5

  1. 安裝 dante-server,一個輕量的 SOCKS5 服務端
    1
    sudo apt-get install dante-server
  2. 編輯 /etc/danted.conf
    1
    sudo nano /etc/danted.conf
    將內容改成如下 (external 要改成 A 電腦的實際網絡介面名稱)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    logoutput: stderr

    user.privileged: proxy
    user.unprivileged: nobody
    user.libwrap: nobody

    internal: 0.0.0.0 port=10800
    external: wifi0 #or eth0

    clientmethod: none
    socksmethod: none

    client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: connect disconnect error
    }

    socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: connect disconnect error
    }
  3. 啟動 danted-server
    1
    sudo service danted start

    建立隧道

    在 A 上運行
    1
    ssh -R {username}@{ip_B} -p {port_B} -R {local_ip_A}:10800:localhost:10800
    local_ip_A 是 A 的內網 IP

    設置代理

    在 B 上運行
    1
    2
    echo 'alias setproxy="export ALL_PROXY=socks5://127.0.0.1:10800"' >> ~/.bashrc
    echo 'alias unsetproxy="unset ALL_PROXY"' >> ~/.bashrc
    然後重啟終端

    使用

    之後每次登入後先運行一次 setproxy,即可讓後續流量都走代理
    1
    2
    3
    setproxy
    curl -i http://ip.cn
    # or do whatever you want

    優點

  • 簡單高效,適合個人使用
  • 當跳板的主機不需要有公網 IP
  • 遠程服務器上不需要額外安裝客戶端

    缺點

  • 需要 Linux 環境,若 Linux 環境是 WSL,持久化會比較麻煩(可以用 Windows 端的 SOCKS5 解決,例如 v2ray-core)
  • 要求 Linux 與網絡知識
  • SOCKS5 是明文協議,即使是內網傳輸仍有安全疑慮

方法 2: Shadowsocks

Shadowsocks 雖然己經不適合突破防火牆了,拿來當內網代理還是相當好用。以下用 Windows 10 做示範

搭建 SS 服務端

  1. 下載最新版 libQtShadowsocks
  2. 建立配置文件,放到與 libQtShadowsocks 同一目錄,命名為 config.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "server":"192.168.100.100", //監聽內網地址
    "server_port":10800,
    "password":"ilovethisworld", //密碼,改自己的密碼
    "timeout":600,
    "method":"aes-128-gcm", //加密方法,可以根據需要修改
    "http_proxy": false, //代理,不明白的不需要修改
    "auth": false //需要驗證,不明白的不需要修改
    }
  3. 啟動 SS 服務端
    1
    shadowsocks-libqss.exe -c config.json -S
    可以寫一個簡單的 .bat 腳本實現開機自啟

    建立隧道

    1
    ssh -R {username}@{ip_B} -p {port_B} -R {local_ip_A}:10800:localhost:10800

    在遠程服務器上安裝 SS 客戶端

    推薦使用 shadowsocks-libev
  4. 安裝客戶端
    Ubuntu
    1
    2
    sudo apt-get install shadowsocks-libev # ubuntu
    sudo yum install shadowsocks-libev # centos
    CentOS
    1
    2
    3
    sudo cd /etc/yum.repos.d/
    sudo curl -O https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/repo/epel-7/librehat-shadowsocks-epel-7.repo
    sudo yum install -y shadowsocks-libev
  5. 編輯 /etc/shadowsocks-libev/config.json
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "server":"127.0.0.1",
    "server_port":10800,
    "local_port":10801,
    "password":"ilovethisworld",
    "timeout":600,
    "method":"aes-128-gcm"
    }
  6. 設定開機自啟 & 啟動 SS 客戶端
    1
    2
    sudo systemctl enable shadowsocks-libev-local
    sudo systemctl start shadowsocks-libev-local

    設置代理

    在 B 上運行
    1
    2
    echo 'alias setproxy="export ALL_PROXY=socks5://127.0.0.1:10801"' >> ~/.bashrc
    echo 'alias unsetproxy="unset ALL_PROXY"' >> ~/.bashrc
    然後重啟終端

    使用

    之後每次登入後先運行一次 setproxy,即可讓後續流量都走代理
    1
    2
    3
    setproxy
    curl -i icanhazip.com # 若 ip 有變代表成功
    # or do whatever you want

    優點

  • 和方法 1 相比,持久化較容易(雖然這是代理軟件與平台選擇的問題,但是此方案搭建起來更簡單)
  • 當跳板的主機不需要有公網 IP
  • 跨平台(幾乎每個平台都有好用的 SS-Server)
  • 保障密碼學安全

    缺點

  • 需要在遠程服務器上安裝客戶端

Refernce

No comments:

Post a Comment