?
![](/files/attmgn/2025/1/admin20250113184010968.jpeg)
動機
學校的服務器,NAT上的管理權(quán)在網(wǎng)管,想把一些服務開放到公網(wǎng)上就得做內(nèi)網(wǎng)穿透。STUN
和ZeroTier
太麻煩,且需要依賴別人的服務器,被排除了。自己有NAS、有公網(wǎng)IPv4地址、有域名,做FRP
穿透是最好的選擇。
找遍全網(wǎng),基本都是介紹在云主機上部署FRPS
+Nginx
的方案,對于家用NAS來說太麻煩;一些回答也太冗長,不簡潔、太陳舊。
原理
FRP
的英文全稱是Fast Reverse Proxy,就是一種代理。
- 服務端叫
FRPS
,要有能偵聽公網(wǎng)端口的能力,且其連接公網(wǎng)的設(shè)備要能通過域名或固定IP被訪問到。
需偵聽一個bind_port
,和一堆remote_port
。把remote_port
收到的數(shù)據(jù),轉(zhuǎn)發(fā)給bind_port
。
- 客戶端叫
FRPC
,要有能訪問公網(wǎng)的能力。
需訪問FRPS
的bind_port
,根據(jù)收到的內(nèi)容,代理到指定的local_ip
和local_port
。
- 用戶端訪問
FRPS
的remote_port
,就等同于訪問各local_ip
的local_port
。
可見,其本質(zhì)是由于客戶端缺少偵聽公網(wǎng)端口的能力,FRP
就在服務端開放這些端口(remote_port
),并通過bind_port
這個通道讓客戶端自己把所需的服務代理到內(nèi)網(wǎng)。整個系統(tǒng)對外開放的總端口數(shù)并沒有減少,至少還增加了一個bind_port
。
配置說明
網(wǎng)絡(luò)拓撲圖如下所示,家里的NAT均可控,學校的NAT不可控。其中,綠色虛線代表HTTPS的訪問通道;紫色的虛線代表TCP、UDP等普通應用的訪問通道;紅色虛線代表固有通道。
![](/files/attmgn/2025/1/admin20250113184031226_0.jpg)
?
網(wǎng)絡(luò)拓撲圖
NAT的配置
需要把FRPC
上指定使用的端口在家庭路由器上做端口轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)到NAS;再把NAS上的這些端口轉(zhuǎn)發(fā)給容器。
FRPC
上配置的server_port
最終轉(zhuǎn)發(fā)到FRPS
上配置的bind_port
,FRPC
上配置的remote_port
最終也要能轉(zhuǎn)發(fā)到FRPS
上。
lucky是個好東西,不光可以做泛域名的DDNS和SSL證書,還能做子域名的泛域名DDNS、SSL證書和反向代理。這里我們先設(shè)置*.university.example.com
的DDNS,再設(shè)置*.university.example.com
的SSL證書,最后把https://*.university.example.com:6666
(proxy port
)代理到http://frps_ip:8080
(vhost_http_port
)。以上,就完成了擁有SSL證書的泛子域名反向代理。
FRP上的配置
TCP、UDP等穿透很簡單,把remote_port
和local_ip
+local_port
建立聯(lián)系即可。
HTTP的穿透,需要配合FRP
上的代理功能。FRPS
上,指定泛域名subdomain_host = university.example.com
;FRPC
上, 根據(jù)不同的subdomain
選擇對應的local_ip
和local_port
。由于FRPS
和FRPC
之間是HTTP明文傳輸,開啟了加密use_encryption
;其實FRP
還支持雙端SSL認證,太麻煩就沒搞(誰會沒事閑的攻擊我呢?哈哈)。
下面給出4份配置文件,配合網(wǎng)絡(luò)拓撲圖一看就懂。
服務端配置
docker-compose.yaml
version: '3.3'
services:
frps:
image: snowdreamtech/frps
environment:
TZ: Asia/Shanghai
restart: unless-stopped
ports:
- "7070:7070" # dashboard
- "8000:8000" # bind
- "8001:8001" # App 1
- "8002:8002" # App 2
- "8080:8080" # http
volumes:
- ./frps.toml:/etc/frp/frps.toml
配置文件frps.toml
這里要注意,最新版的服務端和客戶端的配置文件擴展名不再是.ini
,而是.toml
。
[common]
bind_port = 8000
token = PrNnmRqYrsSLpWpmTFBBsdCphHqtfFGk
# HTTP協(xié)議相關(guān)
vhost_http_port = 8080
subdomain_host = university.example.com
# 以下為看板端口和用戶/密碼,非必須
dashboard_user = admin
dashboard_pwd = 123456
dashboard_port = 7070
客戶端配置
docker-compose.yaml
version: '3.3'
services:
frpc:
image: snowdreamtech/frpc
environment:
TZ: Asia/Shanghai
restart: unless-stopped
ports:
- "7070:7070" # dashboard
volumes:
- ./frpc.toml:/etc/frp/frpc.toml
配置文件frpc.toml
[common]
server_addr = cloud.example.com
server_port = 8000
token = PrNnmRqYrsSLpWpmTFBBsdCphHqtfFGk # 和服務端的token一致
# 指定可用的域名服務器以訪問公網(wǎng),特定環(huán)境下可能需要
dns_server = 114.114.114.114
[App 1]
type = tcp
local_ip = 192.168.1.2
local_port = 5901
remote_port = 8001
[App 2]
type = tcp
local_ip = 192.168.1.3
local_port = 3389
remote_port = 8002
[Gitlab]
type = http
local_ip = 192.168.1.10
local_port = 8080
subdomain = gitlab
use_encryption = true
[iKuai]
type = http
local_ip = 192.168.1.11
local_port = 80
subdomain = gw
use_encryption = true
# 以下為看板端口和用戶/密碼,非必須
admin_port = 7070
admin_user = admin
admin_pwd = 123456
效果
App 1:訪問cloud.example.com
的tcp 8001
端口,被穿透到學校內(nèi)網(wǎng)的192.168.1.2
的tcp 5901
端口。
App 2:訪問cloud.example.com
的tcp 8002
端口,被穿透到學校內(nèi)網(wǎng)的192.168.1.3
的tcp 3389
端口。
GitLab HTTP:訪問https://gitlab.university.example.com:6666
,被穿透到學校內(nèi)網(wǎng)的http://192.168.1.10:8080
。
iKuai HTTP:訪問https://gw.university.example.com:6666
,被穿透到學校內(nèi)網(wǎng)的http://192.168.1.11:80
。
貢獻
本文通過圖文介紹了FRP
內(nèi)網(wǎng)穿透的原理,提出了一種在NAT環(huán)境下利用docker-compose
一鍵部署FRPS
和FRPC
容器進行內(nèi)網(wǎng)穿透的方案。配合lucky
反向代理,實現(xiàn)了低代碼構(gòu)建基于泛子域名、帶SSL證書的HTTP內(nèi)網(wǎng)穿透。
閱讀原文:https://zhuanlan.zhihu.com/p/687477877
該文章在 2025/1/13 18:41:00 編輯過