雙 nginx 反向代理,並以 frp 做 NAT 穿透的具體配置過程

2025 年 4 月 2 日
文章摘要
FakeGPT
加載中...
此內容由人工不智慧生成。

應用場景

我們知道,當前家庭網路中很難從電訊運營商那裡申請到公網 IPv4,一般都是使用 NAT 技術,將家庭網路中的設備共享一個公網 IP。這樣就會導致家庭網路中的設備無法直接被外網訪問。這時候我們可以使用 frp 進行 NAT 穿透,實現對內網服務的訪問。

使用 frp,本質上是將內網服務使用 frp 服務端映射到公網上,這樣就可以透過公網 IP 訪問到內網服務。因此,該方案要求你擁有一個公網 IPv4,最簡單直接的辦法就是在雲服務商處租賃一個 VPS。

而偷懶是人類的天性,儘管 frp 官方有支援 http 和 https 服務的映射,但是每次新增服務的時候,都需要重新配置一個 proxy,還是有夠麻煩。因此,我們可以僅映射兩個 tcp 連接埠到 vps 上,然後在內網伺服器上使用 nginx 作為反向代理,再加上高顏值的 GUI 管理工具 Nginx Proxy Manager(NPM),爽歪歪。以下是圖示:

1

好,到現在為止,我們完成了偷懶的配置。但是現在請你想一下,這個方案僅僅是將公網伺服器作為一個 frps 的中介,是否是有一些浪費了?答案顯而易見是的。由於 frps 直接監聽了 80 和 443 連接埠,導致我們無法在 VPS 上省略連接埠號使用其他的 Web 服務了。那麼如果我們需要在 VPS 上使用其他 Web 服務的話,該怎麼辦呢?答案是在 frps 之前再加一層 nginx 反向代理,讓 nginx 去監聽公網伺服器上的 80 和 443 連接埠,再根據網域分別代理到本機 Web 服務或 frps。圖示如下:

2

在公網伺服器上的操作

安裝 nginx

如果你對 nginx 的配置已足夠熟悉,你可以直接安裝 nginx,在 Debian/Ubuntu 下:

Terminal window
sudo apt install nginx

而如果你對 nginx 的配置不甚熟悉,或者只是和我一樣想要偷懶的話,建議使用 Nginx Proxy Manager(NPM)來進行配置。這裡推薦使用 Docker Compose 來安裝 NPM。附上 Docker Compose 的配置檔:

version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

其中,80443 連接埠分別是 HTTP 和 HTTPS 的連接埠,81 是 NPM 的管理介面的連接埠。./data./letsencrypt 是 NPM 的資料和憑證的儲存路徑,你可以根據自己的需要進行修改。然後啟動容器即可。

安裝 frps

在公網伺服器上安裝 frps,這裡以 Debian/Ubuntu 為例。當然,這裡的 frps 也可以使用 Docker 來安裝,附上 DC 配置檔:

version: '3.8'
services:
frps:
image: snowdreamtech/frps:debian
container_name: frps
restart: always
network_mode: host
volumes:
- /etc/frp/frps.toml:/etc/frp/frps.toml
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7500"]
interval: 30s
timeout: 10s
retries: 3

這裡使用的是 snowdreamtech/frps:debian 的 Docker 映像檔,這是一個基於 Debian 的 frps 映像檔。network_mode: host 是為了讓 frps 使用主機的網路,以方便直接監聽主機連接埠。/etc/frp/frps.toml 是 frps 的配置檔,你可以根據自己的需要進行修改。這裡貼上我的配置檔:

bindPort = 7000
auth.token = "token123456"
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "changeme"

bindPort 是 frps 監聽的連接埠,auth.token 是 frps 的驗證 token,webServer.addrwebServer.port 是 frps 的 Web 介面的地址和連接埠,webServer.userwebServer.password 是 Web 介面的用戶名和密碼。這裡的配置檔僅供參考,你可以根據自己的需要進行修改。

然後啟動容器即可。

安裝 NPM

我們透過 NPM 的管理介面來配置 nginx,推薦這種方式,簡單快捷。

首先,我們仍透過 Docker Compose 來安裝 NPM。附上 Docker Compose 的配置檔:

version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

啟動容器,造訪 http://<your-server-ip>:81,使用預設的帳戶密碼登入 NPM 的管理介面。預設的帳戶密碼如下:

  • 帳戶:admin@example.com
  • 密碼:changeme

登入後,請務必修改密碼。

配置 NPM

下圖為 NPM 的管理介面: 3

我們依次執行下面的作業,當然,在此之前,你需要為您的網域新增一個 A 記錄,指向你 VPS 的 IP。

3.5

4

5

6

OK,至此,我們已經完成了 NPM proxy 向 frps 的配置。你亦可以在此處增加必須在 VPS 上運行的 Web 服務的 proxy,這裡就不贅述了。

在內網伺服器上的操作

安裝 frpc

在內網伺服器上安裝 frpc,這裡以 Debian/Ubuntu 為例。當然,這裡的 frpc 也可以使用 Docker 來安裝,附上 DC 配置檔:

version: '3.8'
services:
frpc:
image: snowdreamtech/frpc:debian
container_name: frpc
restart: always
network_mode: host
volumes:
- /etc/frp/frpc.toml:/etc/frp/frpc.toml
- /etc/frp/conf.d:/root # frpc 的配置檔
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7500"]
interval: 30s
timeout: 10s
retries: 3

frpc 的配置檔如下:

serverAddr = "your-server-ip"
serverPort = 7000 # 同 frps 的配置保持一致
auth.method = "token"
auth.token = "token123456" # 同 frps 的配置保持一致
webServer.addr = "0.0.0.0"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "yourpassword"
webServer.pprofEnable = false
# tls
#transport.tls.certFile = "/etc/frp/ssl/client.crt"
#transport.tls.keyFile = "/etc/frp/ssl/client.key"
#transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"
# config
includes = ["/root/*.toml"]

解釋一下配置檔的最後一行。由於 frpc 的配置檔是以 toml 格式編寫的,因此我們可以將所有的配置檔放在 /root 目錄下,然後在 frpc 的配置檔中使用 includes 指令來包含這些配置檔。這樣就可以將所有的配置檔放在一個目錄下,方便管理。至於為什麼使用 /root 目錄,這是因為容器建立時候就已經有建立了 /root 目錄,因此我們可以直接使用這個目錄來放置配置檔,比較方便直接,省掉諸多麻煩。當然,你也可以將配置檔放在其他的目錄下,只要在 frpc 的配置檔中指定正確的路徑即可。而且,我在 Docker Compose 中已經將 /etc/frp/conf.d 目錄掛載到 /root 目錄下,因此我們可以直接在 /etc/frp/conf.d 目錄下放置配置檔,實現配置檔的持久化存儲。

配置 frpc

至於放在 conf.d 目錄下最為重要的配置檔,那當然是對接 VPS 上 1234 連接埠的配置檔了。這個配置檔將會將所有透過 VPS 上 nginx 分流到 frps 的請求,轉發到內網伺服器上。這裡的配置檔如下:

[[proxies]]
name = "http"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 1234 # VPS 上 nginx 的配置檔中的 proxy_pass 的連接埠

該配置檔成功將內網伺服器的 80 連接埠映射到 VPS 上的 1234 連接埠。

接下來,我們只需要使用 nginx 監聽 80 連接埠,即可完成對內網伺服器中不同服務的反向代理。

安裝和配置 NPM

安裝 NPM 的步驟不做贅述,Docker Compose 配置檔可以直接把上面 VPS 上的拿來用。

然後在 NPM 管理介面中,新增 Host Proxy,將網域代理到內網服務即可。

推薦首先將 NPM 的管理介面進行反向代理(我代理我自己),這樣即可使用網域來訪問 NPM 的管理介面了。然後再將其他的服務進行反向代理。

由於在 VPS 的 NPM 上已經配置了廣泛網域的 SSL 憑證,甚至在新增服務的時候,只要是用到廣泛網域,甚至都不再需要配置 SSL 了。這樣就可以省去許多麻煩。

總結

這是一套複雜、性能可能沒有那麼好,但可以滿足所有需求的方案。

總有一些服務是需要 24 小時保證不當機的。而我們在家庭中搭建的 NAT 伺服器,可玩性、可配性都極高,但肯定不能夠像 VPS 機房那樣有著高穩定性。使用這種方案,只要你的 VPS 供應商不抽風,VPS 可以保證儘量不 Down,那麼你運行在 VPS 上的服務就可以保證不會 Down 掉,即使你的 NAT 伺服器遭遇了頻繁的斷電、斷網等情況,也不會影響到 VPS 上的服務。

推薦在 VPS 上運行需要高穩定性,但不需要高性能的服務,比如說 Web 服務、FTP 服務等。這些服務對於性能的要求並不高,但對於穩定性的要求卻是非常高的。而在內網伺服器上運行需要高性能的服務,比如說遊戲伺服器、影視轉碼等。畢竟,我如果能買得起高性能的 VPS,我也不會在家裡搭建一台內網伺服器了(笑)。

雙 nginx 反向代理,並以 frp 做 NAT 穿透的具體配置過程
https://blog.kynix.tw/posts/1743575746646/
作者
Adrian Chen
建檔時間
2025 年 4 月 2 日
協議
BY-NC-SA 4.0
姓名標示-非商業性-相同方式分享 4.0 國際