概述
平時我們想從外網訪問內網的時候,通常可以用花生殼、nat123之類的服務。
但是這些服務不是開源的,而且還收費,體驗也很不穩定,使用的時候不免心理有些犯嘀咕。
對於已經購買過阿里雲等服務器的人來說,其實有一個更好的選擇frps/frpc.
frps/frpc的主要功能
1.通過 SSH 訪問內網機器;
2.通過自定義域名訪問內網的服務;
3.轉發 DNS 查詢請求;
4.轉發 Unix 域套接字;
5.對外提供簡單的文件訪問服務;
6.為本地 HTTP 服務啟用 HTTPS;
7.安全地暴露內網服務;
8.點對點內網穿透.
體驗結果
1.涵蓋了花生殼和nat123的所有功能;
2.從測試結果上,frps/frpc(golang寫的)的穩定性更高(相對於花生殼和nat123的免費用戶來說),
#http siege的測試結果
Transactions: 678011 hits
Availability: 100.00 %
Elapsed time: 120.00 secs
Data transferred: 6403.18 MB
Response time: 0.02 secs
Transaction rate: 5650.09 trans/sec
Throughput: 53.36 MB/sec
Concurrency: 95.81
Successful transactions: 96911
Failed transactions: 0
Longest transaction: 0.53
Shortest transaction: 0.00
3.支持dashboard和prometheus,非常方便。
4.各種平台都支持;
#支持的平台
frp_0.37.0_darwin_amd64.tar.gz
frp_0.37.0_freebsd_386.tar.gz
frp_0.37.0_freebsd_amd64.tar.gz
frp_0.37.0_linux_386.tar.gz
frp_0.37.0_linux_amd64.tar.gz
frp_0.37.0_linux_arm64.tar.gz
frp_0.37.0_linux_arm.tar.gz
frp_0.37.0_linux_mips64le.tar.gz
frp_0.37.0_linux_mips64.tar.gz
frp_0.37.0_linux_mipsle.tar.gz
frp_0.37.0_linux_mips.tar.gz
frp_0.37.0_windows_386.zip
frp_0.37.0_windows_amd64.zip
frps/frpc獲取方式
源碼和包:https://github.com/fatedier/frp/releases
文檔:https://gofrp.org/docs/examples/xtcp/
運行方法
nohup ./frps -c /etc/frps.ini &
nohup ./frpc -c /etc/frpc.ini &
附錄(文檔備份)
文檔可能不能訪問,備份到下面
通過 SSH 訪問內網機器
這個示例通過簡單配置 TCP 類型的代理讓用戶訪問到內網的服務器。
- 在具有公網 IP 的機器上部署 frps,修改 frps.ini
文件,這里使用了最簡化的配置,設置了 frp
服務器用戶接收客戶端連接的端口:
[common]
bind_port = 7000
- 在需要被訪問的內網機器上(SSH 服務通常監聽在 22 端口)部署
frpc,修改 frpc.ini 文件,假設 frps 所在服務器的公網 IP 為 x.x.x.x:
[common]
server_addr = x.x.x.x
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
local_ip 和 local_port 配置為本地需要暴露到公網的服務地址和端口。remote_port 表示在
frp 服務端監聽的端口,訪問此端口的流量將會被轉發到本地服務對應的端口。
-
分別啟動 frps 和 frpc。
-
通過 SSH 訪問內網機器,假設用戶名為 test:
ssh -oPort=6000 test\@x.x.x.x
frp 會將請求 x.x.x.x:6000 的流量轉發到內網機器的 22 端口。
通過自定義域名訪問內網的 Web 服務
這個示例通過簡單配置 HTTP 類型的代理讓用戶訪問到內網的 Web 服務。
HTTP 類型的代理相比於 TCP
類型,不僅在服務端只需要監聽一個額外的端口 vhost_http_port 用於接收 HTTP
請求,還額外提供了基於 HTTP 協議的諸多功能。
- 修改 frps.ini 文件,設置監聽 HTTP 請求端口為 8080:
[common]
bind_port = 7000
vhost_http_port = 8080
- 修改 frpc.ini 文件,假設 frps 所在的服務器的 IP 為
x.x.x.x,local_port 為本地機器上 Web 服務監聽的端口,
綁定自定義域名為 custom_domains。
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com
[web2]
type = http
local_port = 8080
custom_domains = www.yourdomain2.com
-
分別啟動 frps 和 frpc。
-
將 www.yourdomain.com 和 www.yourdomain2.com 的域名 A 記錄解析到
IP x.x.x.x,如果服務器已經有對應的域名,也可以將 CNAME
記錄解析到服務器原先的域名。或者可以通過修改 HTTP 請求的 Host
字段來實現同樣的效果。 -
通過瀏覽器訪問 http://www.yourdomain.com:8080 即可訪問到處於內網機器上
80
端口的服務,訪問 http://www.yourdomain2.com:8080 則訪問到內網機器上
8080 端口的服務。
轉發 DNS 查詢請求
這個示例通過簡單配置 UDP 類型的代理轉發 DNS 查詢請求。
DNS 查詢請求通常使用 UDP 協議,frp 支持對內網 UDP 服務的穿透,配置方式和
TCP 基本一致。
- frps.ini 內容如下:
[common]
bind_port = 7000
- frpc.ini 內容如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000
這里反代了 Google 的 DNS 查詢服務器的地址,僅僅用於測試 UDP
代理,並無實際意義。
-
分別啟動 frps 和 frpc。
-
通過 dig 測試 UDP
包轉發是否成功,預期會返回 www.baidu.com 域名的解析結果。
dig @x.x.x.x -p 6000 www.baidu.com
轉發 Unix 域套接字
這個示例通過配置 Unix域套接字客戶端插件來通過 TCP 端口訪問內網的
Unix域套接字服務,例如 Docker Daemon。
- frps.ini 內容如下:
[common]
bind_port = 7000
- frpc.ini 內容如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock
-
分別啟動 frps 和 frpc。
-
通過 curl 命令查看 docker 版本信息
curl <http://x.x.x.x:6000/version
對外提供簡單的文件訪問服務
這個示例通過配置 static_file 客戶端插件來將本地文件暴露在公網上供其他人訪問。
通過 static_file 插件可以對外提供一個簡單的基於 HTTP 的文件訪問服務。
- frps.ini 內容如下:
[common]
bind_port = 7000
- frpc.ini 內容如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[test_static_file]
type = tcp
remote_port = 6000
plugin = static_file
# 要對外暴露的文件目錄
plugin_local_path = /tmp/file
# 用戶訪問 URL 中會被去除的前綴,保留的內容即為要訪問的文件路徑
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc
-
分別啟動 frps 和 frpc。
-
通過瀏覽器訪問 http://x.x.x.x:6000/static/ 來查看位於 /tmp/file 目錄下的文件,會要求輸入已設置好的用戶名和密碼。
為本地 HTTP 服務啟用 HTTPS
通過 https2http 插件可以讓本地 HTTP 服務轉換成 HTTPS 服務對外提供。
- frps.ini 內容如下:
[common]
bind_port = 7000
- frpc.ini 內容如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[test_htts2http]
type = https
custom_domains = test.yourdomain.com
plugin = https2http
plugin_local_addr = 127.0.0.1:80
# HTTPS 證書相關的配置
plugin_crt_path = ./server.crt
plugin_key_path = ./server.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
-
分別啟動 frps 和 frpc。
-
通過瀏覽器訪問 https://test.yourdomain.com。
點對點內網穿透
這個示例將會演示一種不通過服務器中轉流量的方式來訪問內網服務。
frp
提供了一種新的代理類型 xtcp 用於應對在希望傳輸大量數據且流量不經過服務器的場景。
使用方式同 stcp 類似,需要在兩邊都部署上 frpc 用於建立直接的連接。
**目前處於開發的初級階段,並不能穿透所有類型的 NAT
設備,所以穿透成功率較低。穿透失敗時可以嘗試 stcp 的方式。**
- frps.ini 內容如下,需要額外配置監聽一個 UDP
端口用於支持該類型的客戶端:
[common]
bind_port = 7000
bind_udp_port = 7000
- 在需要暴露到內網的機器上部署 frpc,且配置如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh]
type = xtcp
# 只有 sk 一致的用戶才能訪問到此服務
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
- 在想要訪問內網服務的機器上也部署 frpc,且配置如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh_visitor]
type = xtcp
# xtcp 的訪問者
role = visitor
# 要訪問的 xtcp 代理的名字
server_name = p2p_ssh
sk = abcdefg
# 綁定本地端口用於訪問 ssh 服務
bind_addr = 127.0.0.1
bind_port = 6000
- 通過 SSH 訪問內網機器,假設用戶名為 test:
ssh -oPort=6000 test\@127.0.0.1
