基於frp構建內網穿透

開篇廢話

第一次接觸到內網穿透這一概念大概是20017年左右,手中有一樹莓派,想到如何能夠在公司訪問運行在家裏的樹莓派呢?百度之,基本就是下面這種情況——廣告勸退,我一個小小的需求,要什麼花裏胡哨的東西,當時不了了之。後來瞭解到NATAPP,使用方便,價格也不貴,關鍵是配置簡單,還支持自定義二級域名(當然是要錢的啦),這樣使用了很長一段時間。但後來發現自己的使用場景是希望長期處於內網穿透,偶爾用一下,頻率相當低。即使使用NATAPP這樣低至9元/月的服務都嫌貴。

在這裏插入圖片描述

無疑,開源軟件是拯救我的唯一方式。gayhub是個好地方。goproxy(8k star)frp(33k star)映入眼簾。大致查看了使用教程,無論從簡易程度,還是受歡迎程度,我都傾向於選擇frp。它通過命令行配置。別跟我整那些花裏胡哨的dashboard,簡單易用纔是硬道理,我不需要複雜的功能。

frp簡介

frp使用go語言編寫,工作原理是反向代理,下面的官方的架構圖。

在這裏插入圖片描述

需要說明的是,該項目目前處於開發狀態,未經充分測試和驗證,因此不推薦用於生產環境。

關於使用frp的前置條件,是你需要有一臺VPS,我手裏有一臺阿里雲服務器,正好。

需求說明

自己目前有兩個需求

  • 可通過公網IP ssh到樹莓派進行操作
  • 可通過域名訪問運行在樹莓派上的web服務,端口7000。暫時只要http

下面針對這兩個需求進行配置

服務端

frp配置

到項目的release頁下載符合自己服務器版本的壓縮包。

在這裏插入圖片描述

我的VPS是ubuntu 64位,因此下載frp_0.31.2_linux_amd64.tar.gz。 依照如下步驟

  • 解壓

    tar -zxvf frp_0.31.2_linux_amd64.tar.gz
    
  • 修改ini配置文件

    修改目錄下的服務器配置文件frps.ini,注意別改到客戶端配置文件frpc.ini。

    這裏指定了frp的tcp服務監聽7000端口,http服務監聽7001端口。

    # frps.ini
    [common]
    bind_port = 7000
    vhost_http_port = 7001
    
  • 啓動

    ./frps -c ./frps.ini
    

    看到如下輸出,代表成功了。

    2020/02/23 19:09:37 [I] [service.go:152] frps tcp listen on 0.0.0.0:7000                    
    2020/02/23 19:09:37 [I] [service.go:194] http service listen on 0.0.0.0:7001               
    2020/02/23 19:09:37 [I] [root.go:205] start frps success 
    

nginx配置

第二點需求可以通過nginx實現,直接在80端口上監聽,將對應域名轉發到該域名下7001端口。

server {
    listen 80;
    server_name awtrix.pi.zouguodong.top;
    
    location / {
        proxy_pass http://awtrix.pi.zouguodong.top:7001/;
    }
}

客戶端

frp將客戶端和服務端文件放在一個包中,你可以觀察到上面解壓出來的包中包含了frpc——即客戶端命令和配置文件。因此,如果客戶端環境也是linux 64位,可以直接使用剛纔下載的那個包。

但我的客戶端是樹莓派,因此需要下載arm 32位版,即frp_0.31.2_linux_arm.tar.gz,注意不要下載64位,樹莓派3使用了64位CPU,但操作系統依然是32位。

執行如下步驟

  • 解壓

    tar -zxvf frp_0.31.2_linux_arm.tar.gz
    
  • 修改配置文件

    修改frpc.ini

    # frpc.ini
    # 這裏填寫服務端的IP和端口號
    [common]
    server_addr = x.x.x.x
    server_port = 7000
    
    # 將服務端的6000端口轉發到本地的22端口
    [ssh]
    type = tcp
    local_ip = 127.0.0.1
    local_port = 22
    remote_port = 6000
    
    # 將服務端的指定域名的請求轉發到本地7000端口
    [web]
    type = http
    local_port = 7000
    custom_domains = <你的域名>
    
  • 啓動

    ./frpc -c ./frpc.ini
    

    啓動輸出如下

    2020/02/23 19:19:34 [I] [service.go:250] [ae46f3632a860bba] login to server success, get run id [ae46f3632a860bba], server udp port [0]
    2020/02/23 19:19:34 [I] [proxy_manager.go:144] [ae46f3632a860bba] proxy added: [web ssh]
    2020/02/23 19:19:34 [I] [control.go:164] [ae46f3632a860bba] [web] start proxy success
    2020/02/23 19:19:34 [I] [control.go:164] [ae46f3632a860bba] [ssh] start proxy success
    

    同時觀察服務端輸出,增加了如下輸出

    2020/02/23 19:19:34 [I] [service.go:392] [ae46f3632a860bba] client login info: ip [113.110.200.14:46946] version [0.31.2] hostname [] os [linux] arch [arm]                                                                                                                                            
    2020/02/23 19:19:34 [I] [http.go:92] [ae46f3632a860bba] [web] http proxy listen for host [xxx.xxx.xxx] location [] group []
    2020/02/23 19:19:34 [I] [control.go:445] [ae46f3632a860bba] new proxy [web] success
    2020/02/23 19:19:34 [I] [tcp.go:63] [ae46f3632a860bba] [ssh] tcp proxy listen port [6000]
    2020/02/23 19:19:34 [I] [control.go:445] [ae46f3632a860bba] new proxy [ssh] success
    

    至此,通過ssh命令登錄VPS的6000端口,即可遠程訪問到樹莓派;通過指定的域名,即可訪問到樹莓派中暴露於7000端口的web服務。

驗證

  • 測試需求一

    # 嘗試遠程ssh登錄
    ssh -oPort=6000 pi@<VPS公網IP>
    

    ssh登錄成功

    floyd@floyd-ThinkPad-T490:~$ ssh -oPort=6000 [email protected]
    The authenticity of host '[blog]:6000 ([xxx.xxx.xxx.xxx]:6000)' can't be established.
    ECDSA key fingerprint is SHA256:o4+aSfAmCMmE5l/UAj+8/XJ8YyWDYrMzlbVelu0ggAA.
    Are you sure you want to continue connecting (yes/no)? 
    
  • 測試需求二

    瀏覽器訪問指定域名,成功訪問到樹莓派中運行的服務——AWTRIX控制檯
    在這裏插入圖片描述

總結

通過frp,完美實現了上述兩個需求,關鍵是免費。當然,該軟件還有更加強大的功能,如有需要,儘管去折騰。

在配置過程中也有遇到坑和覺得可以改善的地方,如下

  • VPS安全組問題。阿里雲的訪問白名單默認沒有開啓6000\7000\7001三個端口的訪問,需要手動添加,否則無法訪問
    在這裏插入圖片描述

  • 服務端可客戶端的啓動腳本,可以加入開機自啓動。爲了方便,服務端使用了supervisor進行管理。客戶端則直接添加到/etc/rc.local

    • 服務端

      supervisor配置文件

      [program:frp]
      directory = /root/frp/frp_0.31.2_linux_amd64
      command = /root/frp/frp_0.31.2_linux_amd64/frps -c /root/frp/frp_0.31.2_linux_amd64/frps.ini
      autostart = true
      startsecs = 10
      autorestart = true
      startretries = 3
      user = root
      redirect_stderr = true
      stdout_logfile_maxbytes = 50MB
      stdout_logfile_backups = 20
      stdout_logfile = /var/log/frp/frp.log
      
      # 更新supervisor
      supervisorctl update
      
    • 客戶端

      在/etc/systemd/system下創建frp.service文件,內容如下

      [Unit]
      Description=FRP Client
      After=network.target
      
      [Service]
      Type=simple
      WorkingDirectory=/home/pi/frp/frp_0.31.2_linux_arm
      ExecStart=/home/pi/frp/frp_0.31.2_linux_arm/frpc -c /home/pi/frp/frp_0.31.2_linux_arm/frpc.ini
      
      [Install]
      WantedBy=multi-user.target
      

      執行命令如下

      # 自啓動開啓
      sudo systemctl enable frp.service
      # 啓動服務
      sudo systemctl start frp.service
      

參考文檔

  1. frp手冊
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章