1. 程式人生 > >frp 內網穿透實現 ssh 訪問內網主機

frp 內網穿透實現 ssh 訪問內網主機

本文目的

frp 是一個可用於內網穿透的高效能的反向代理應用,支援 tcp, udp, http, https 協議。 本文將基於 frp 來實現內網穿透,從而實現從外網 ssh 登入內網主機,而不對 frp 其他的應用做過多的說明。

frp 的作用

  • 利用處於內網或防火牆後的機器,對外網環境提供 http 或 https 服務。
  • 對於 http, https 服務支援基於域名的虛擬主機,支援自定義域名繫結,使多個域名可以共用一個80埠。
  • 利用處於內網或防火牆後的機器,對外網環境提供 tcp 和 udp 服務,例如在家裡通過 ssh 訪問處於公司內網環境內的主機。

架構

架構

在具有公網IP的伺服器或VPS上安裝執行 frp 的服務端程式frps,並在處於內網的目標主機上面安裝執行 frp 的客戶端程式 frpc ,然後 User 就可以通過公網伺服器來實現內網穿透從而訪問內網主機。

配置 ssh 訪問內網機器

根據不同的系統架構選擇不同的安裝包,從 frp下載連結 上下載合適的安裝包。由於本人的公網伺服器是 vultr 上面的一臺 VPS,作業系統是 CentOS 7;內網機器也是一臺 Linux 伺服器,作業系統是 Ubuntu 16.04,所以我使用的安裝包是 frp_0.21.0_linux_amd64.tar.gz 。配置步驟如下:

  1. 下載安裝包

    在公網伺服器和內網機器上都要下載安裝包並解壓:

    $ wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_linux_amd64.tar.gz
    $ 
    tar -xzvf frp_0.21.0_linux_amd64.tar.gz

    解壓之後的資料夾中既包含了服務端的檔案又包括客戶端的檔案,所以可以分別在兩個機器上刪除掉不必要的檔案,也可以不刪,都沒有影響。強迫症還是來刪一下,在解壓後的資料夾中:

    • 在公網伺服器上刪除客戶端相關的檔案,只保留一下兩個檔案:

      frps  frps.ini
    • 在內網機器上刪除服務端相關的檔案,只保留以下兩個檔案:

      frpc   frpc.ini
  2. 在公網伺服器上配置並啟動

    修改配置檔案 $ vi frps.ini,如下:

    [common]
    bind_port = 7000  #frp服務端埠(必須)

    配置很簡單,然後啟動:

    $ nohup ./frps -c frps.ini &

    檢視 nohup.out 的資訊,success

    
    # tail -f nohup.out 
    
    2018/09/14 05:33:15 [I] [service.go:130] frps tcp listen on 0.0.0.0:7000
    2018/09/14 05:33:15 [I] [root.go:207] Start frps success
    2018/09/14 05:49:47 [I] [service.go:130] frps tcp listen on 0.0.0.0:7000
    2018/09/14 05:49:47 [I] [root.go:207] Start frps success
    2018/09/14 06:28:59 [I] [service.go:319] client login info: ip [125.71.219.33:37092] version [0.21.0] hostname [] os [linux] arch [amd64]
    2018/09/14 06:28:59 [I] [proxy.go:217] [93eec0dde173fc68] [ssh] tcp proxy listen port [6000]
    2018/09/14 06:28:59 [I] [control.go:335] [93eec0dde173fc68] new proxy [ssh] success
  3. 在內網機器上配置並啟動

    修改配置檔案 $ vi frpc.ini,如下:

    [common]
    server_addr = 0.0.0.0   #frp服務端地址,可以填ip或者域名,這裡假設為0.0.0.0
    server_port = 7000      #frp服務端埠,即填寫服務端配置中的 bind_port
    
    [ssh]
    type = tcp              #連線型別,填tcp或udp
    local_ip = 127.0.0.1    #填127.0.0.1或內網ip都可以
    local_port = 22         #需要轉發到的埠,ssh埠是22
    remote_port = 6000      #frp服務端的遠端監聽埠,即你訪問服務端的remote_port就相當於訪
                           #問客戶端的 local_port,如果填0則會隨機分配一個埠

    啟動客戶端程式:

    $ nohup ./frpc -c frpc.ini &

    檢視 nohup.out 的資訊,success

    $ tail -f nohup.out
    2018/09/14 14:28:58 [I] [proxy_manager.go:300] proxy removed: []
    2018/09/14 14:28:58 [I] [proxy_manager.go:310] proxy added: [ssh]
    2018/09/14 14:28:58 [I] [proxy_manager.go:333] visitor removed: []
    2018/09/14 14:28:58 [I] [proxy_manager.go:342] visitor added: []
    2018/09/14 14:28:59 [I] [control.go:246] [93eec0dde173fc68] login to server success, get run id [93eec0dde173fc68], server udp port [0]
    2018/09/14 14:29:00 [I] [control.go:169] [93eec0dde173fc68] [ssh] start proxy success
  4. 登入

    完成前面三步的配置就可以登入對應的內網機器了,執行 ssh 命令:

    ssh -oPort=6000 username@server_addr
    或者
    ssh -p 6000 username@server_addr

    上面登入使用的 username 是內網機器的使用者名稱,server_addr是公網伺服器的IP,port 6000就是設定的 remote_port,最後的登入密碼是內網機器的密碼,而不是公網機器的密碼,這一點一定要注意。

問題解決

在啟動服務端和客戶端程式之後,可能發現還是無法登入到內網內網機器,在內網機器上面執行 tail -f nohup.out 檢視啟動命令的執行結果,可以發現以下的問題:

$ tail -f nohup.out 
2018/09/14 14:11:02 [I] [proxy_manager.go:333] visitor removed: []
2018/09/14 14:11:02 [I] [proxy_manager.go:342] visitor added: []
2018/09/14 14:13:09 [W] [control.go:113] login to server failed: dial tcp xxx.xxx.xxx.xxx:7000: connect: connection timed out
dial tcp xxx.xxx.xxx.xxx:7000: connect: connection timed out

仔細檢查了一下,發現是我公網伺服器防火牆的原因,沒有允許對應埠的流量通過,所以需要配置防火牆:

# firewall-cmd --zone=public --add-port=7000/tcp --permanent
# firewall-cmd --zone=public --add-port=6000/tcp --permanent
# firewall-cmd --reload

上面配置防火牆的命令是針對 CentOS 的,如果是別的系統不太一樣,如 Ubuntu 通過iptables命令來配置。