# How to use frp reverse proxy
## Introduction
在某些情況下,工作站可能無法直接獲得外網IP,該類情況通常是因為組織的安全限制或工作站管理者的各種考量,使用者在使用這類工作站時可能需要先連接VPN才可使用。
雖然VPN增強了安全性,但也帶來了額外的步驟,有時還會遭遇網路提供者的防火牆過濾。若是你手上剛好有一台具備外網IP工作站,可以透過FRP(Fast Reverse Proxy)來連線到只具備內網IP的工作站。
*本文不討論FRP對安全性的影響!*
## Configuration
Step 1, Download FRP from github
首先,到[FRP releases](https://github.com/fatedier/frp/releases)中,,根據作業系統與架構,在擁有public IP的工作站A與LAN中的工作站B上下載相應版本。

NOTE: 兩個工作站可以是不同作業系統與架構
Step 2, Set up FRP server (frps)
FRP中區分為兩個角色分別為FRPS(frp server)與FRPC(frp client)。
具備public IP的工作站A擔任FRPS,而LAN中的工作站B則是FRPC。
在`frps.toml`上設定bindPort便完成基本設定。
不過建議加上auth.method與auth.token以避免未授權使用者的濫用。
`frps.toml` example
```
bindPort = 52508
auth.method = "token"
auth.token = "068a085c120791fe09cffc0d6ff2e487"
```
在設定好`frps.toml`後,在tmux中執行`./frps -c ./frps.toml`啟動FRPS。
Step 3, Set up FRP client (frpc)
FRPC為FRP中的client端,負責透過frp server的address與bind port設定新的proxy connection。
在`frpc.toml`中需要設定frps的serverAddr與serverPort(也就是Step2的bindPort)。如果frps中設定了auth,在frpc中也需要加上對應的auth.method與auth.token。
最後則是根據需要proxy的服務設定,例如想要將工作站B上的ssh(port 22, tcp)服務由工作站的12345代理,則需要在frpc中加入以下`type = "tcp"`, `localIP = "127.0.0.1"`, `localPort = 22`, `remotePort = 12345`。
`frpc.toml` example
```
serverAddr = "140.114.***.***"
serverPort = 52508
auth.method = "token"
auth.token = "068a085c120791fe09cffc0d6ff2e487"
[[proxies]]
name = "ssh proxy(依需求修改名稱)"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 12345
```
在設定好`frpc.toml`後,在tmux中執行`./frpc -c ./frpc.toml`啟動FRPC。
NOTE: 如需代理多個服務,可在frpc.toml尾部再加上額外的代理設定。例如在port 8890還有jupyter lab,則在`frpc.toml`的尾部再加上
```
[[proxies]]
name = "jupyter"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8890
remotePort = 34567
```
Step 4, Good to go!
當frps與frpc都完成設定後,便可以直接透過[工作站A IP]:12345連線到[工作站B]:22。
```
ssh -p 12345 [your username]@140.114.***.***
```
或者在瀏覽器中打開"140.114.***.***:34567"到jupyter。
## Appendix 1, config helper script
若不確定如何選擇bind port和auth_token,可以透過底下的python script協助。
```
import secrets
import random
bind_port = random.randint(30000, 60000)
auth_token = secrets.token_hex(16)
print("bind_port", bind_port)
print("auth_token", auth_token)
```
## Appendix 2, 什麼是外網IP,什麼是內網IP?
外網IP和內網IP是網絡中的兩個基本概念,它們區分了互聯網上的公共空間和局部網絡中的私有空間。
外網IP是由ISP分配給連接至網路設備的唯一地址,用於在全球範圍(WAN)識別和定位該設備。任何時候當你的設備(如路由器)向網路發送請求時,都是使用這個外網IP作為識別,沒有IP,就不能夠發送請求。因為其唯一性,外網IP使得來自互聯網的數據能夠準確地送達到特定設備。
相對於外網IP,內網IP則是在LAN(如家庭或辦公室網絡)內部使用的IP地址,它由網絡管理員或路由器自動分配給連接到該網絡的每一台設備。內網IP確保了局部網絡內部設備之間的通信,而無需占用全球唯一的IP地址資源(詳見[NAT](https://zh.wikipedia.org/zh-tw/%E7%BD%91%E7%BB%9C%E5%9C%B0%E5%9D%80%E8%BD%AC%E6%8D%A2)、[IPv4耗盡](https://zh.wikipedia.org/zh-tw/IPv4%E4%BD%8D%E5%9D%80%E6%9E%AF%E7%AB%AD))。常見的內網IP範圍有192.168.x.x、10.x.x.x等。
為了更直觀地解釋外網IP與內網IP之間的連線關係,我們可以用一個簡單的圖例介紹。下面的圖例展示了一個典型的家庭網絡設置,其中包括了WAN(外網)、路由器(Gateway)、以及多個LAN中的設備。
```
WAN ─────────> [其他外網IP]
|
| ISP所提供的外網IP 123.123.123.123
|
v
[Router] Gateway有對外的 123.123.123.123 與對內的 192.168.0.1
|\
| \ 內網IP 192.168.0.10
| \
| [PC]
|
| 內網IP 192.168.0.101
v
[iPhone]
```
WAN(外網):通過ISP連接到你的路由器。
[ISP]:互聯網服務提供商,負責分配外網IP給你的路由器。
[路由器]:家庭網絡的核心,它持有一個外網IP用於在互聯網上識別,並分配內網IP給家庭內的所有設備。
[PC]/[iPhone]:這些是家庭內部的設備,每個設備都會從路由器獲得一個內網IP,用LAN內的通信。
這個示意圖展示了外網IP和內網IP如何共同工作來達成家庭內部設備與外界WAN之間的連接。當家庭內的設備試圖取用WAN上的資源時,它們會首先通過內網IP與家庭路由器通訊,然後由路由器透過其外網IP與WAN上的服務進行交互。這樣的設計有效地隔離了LAN與WAN,避免內網設備直接暴露在WAN中,增加了網路的安全性,同時也緩減了IPv4耗盡的問題。