## 准备
有公网 IP 的服务器 1 台(阿里云、腾讯云等)
本地可以联网的机器 1 台
[frp 中文文档](https://gofrp.org/docs/)
## 下载和安装
目前版本为 frp_0.38.0 进入 github [下载列表](https://github.com/fatedier/frp/releases)

参考图中,根据不同的操作系统下载对应压缩包,其中 amd、arm、386 等表示不同的处理器架构,amd64、arm64 等后缀为 64 则表示 64 位操作系统,当前大部分机器都是 Intel 处理器,根据我自己机器情况下载 amd64 的压缩包。
## 公网访问本地 Web 服务
通过 frp 内网穿透实现公网访问本地的 Web 服务,以 Java 项目为例。
### 服务端配置
云服务器系统为 CentOS ,所以将 frp_0.38.0_linux_amd64.tar.gz 上传至服务器并解压
```shell
$ tar -zxvf frp_0.38.0_linux_amd64.tar.gz
```
查看解压之后的目录列表
```shell
$ cd frp_0.38.0_linux_amd64
$ ll
总用量 23176
frpc
frpc_full.ini
frpc.ini
frps
frps_full.ini
frps.ini
LICENSE
systemd
```
修改服务端配置文件 frps.ini
```ini
[common]
bind_port = 7077
token = 123456abcde
dashboard_port = 10001
dashboard_user = admin
dashboard_pwd = admin.12345
vhost_http_port = 10002
```
- bind_port 表示客户端与服务端连接的端口,默认 7000
- token 客户端和服务端连接的口令
- vhost_http_port 代理 HTTP 服务的端口,也就是通过公网访问本地服务 web 服务时的端口
- dashboard_port、dashboard_user、dashboard_pwd 打开服务端仪表盘的端口、用户名和密码,可以不配置,关于仪表盘说明在更多配置-Web界面中有说明
运行服务端
```shell
$ ./frps -c frps.ini
2021/12/16 15:21:11 [I] [root.go:200] frps uses config file: frps.ini
2021/12/16 15:21:11 [I] [service.go:192] frps tcp listen on 0.0.0.0:7077
2021/12/16 15:21:11 [I] [service.go:235] http service listen on 0.0.0.0:10002
2021/12/16 15:21:11 [I] [service.go:291] Dashboard listen on 0.0.0.0:10001
2021/12/16 15:21:11 [I] [root.go:209] frps started successfully
```
### 客户端配置
本地机器为 Mac OS,所以下载 frp_0.38.0_darwin_amd64.tar.gz 并解压,解压之后的目录列表与服务端相同,直接修改客户端配置文件 frpc.ini
```ini
[common]
server_addr = xx.xx.xx.xx
server_port = 7077
token = 123456abcde
[web]
type = http
local_ip = 127.0.0.1
local_port = 10004
remote_port = 10002
custom_domains = xx.xx.xx.xx
```
- server_addr 服务端 ip
- server_port 服务端端口
- token 服务端配置的连接口令
- [web] 表示一个单个代理参数,这里代理名称是 web,表示代理本地的 web 服务,客户端可以配置多个代理,代理名称不能重复
- type 转发协议类型,可以是 tcp、udp、http、https 等
- local_port 本地应用的端口,这里本地启动一个端口为 10004 的 java 应用,所以填 10004
- remote_port 服务端开放的端口 10002
- custom_domains 配置服务端域名,如果没有域名填写服务端 ip 即可
运行客户端
```shell
$ ./frpc -c frpc.ini
2021/12/16 15:29:57 [I] [service.go:301] [5cd1e0d4257f0670] login to server success, get run id [5cd1e0d4257f0670], server udp port [0]
2021/12/16 15:29:57 [I] [proxy_manager.go:144] [5cd1e0d4257f0670] proxy added: [web]
2021/12/16 15:29:57 [I] [control.go:180] [5cd1e0d4257f0670] [web] start proxy success
```
启动 java 应用,端口 10004,暴露访问地址 /test/frp
```java
@RestController
public class TestController {
@GetMapping("/test/frp")
public String testFrp(){
//System.out.println("------");
return "ok";
}
}
```
```tex
2021-12-16 16:42:58.942 INFO 23855 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 10004 (http)
2021-12-16 16:42:58.950 INFO 23855 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-12-16 16:42:58.950 INFO 23855 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.43]
2021-12-16 16:42:59.017 INFO 23855 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/haoke] : Initializing Spring embedded WebApplicationContext
```
### 测试
在浏览器输入
```tex
http://云服务器域名:10002/test/frp
http://云服务器ip:10002/test/frp
```
成功时页面显示 ok
### systemctl 命令启动
通过 `./frps -c frps.ini` 启动服务端时,服务端仅运行在前台,如果 Ctrl+C 停止或者关闭 SSH 窗口后,服务端均会停止运行。因此使用 systemctl 命令启动。
进入解压后的目录,将 systemd/frps.service 复制到系统 /usr/lib/systemd/system/ 目录下,然后修改文件中内容,将 ExecStart=/usr/bin/frps -c /etc/frp/frps.ini 行修改为 ExecStart=/home/frp/frps -c /home/frp/frps.ini (/home/frp 为 frp 的安装目录)
```ini
[Unit]
Description=Frp Server Service
After=network.target syslog.target
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/frps -c /etc/frp/frps.ini
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
```
systemctl 命令
```shell
$ systemctl start frps #启动
$ systemctl stop frps #停止
$ systemctl enable frps #自启动
$ systemctl restart frps #重启
```
## 远程桌面
### Mac OS
客户端增加配置
```ini
#frpc.ini
[vnc]
type = tcp
local_ip = 127.0.0.1
local_port = 5900
remote_port = 10003
use_encryption = true
use_compression = true
```
5900 是 Mac 屏幕共享端口,另外开启了加密和压缩。
Mac 上开启屏幕共享,在 "系统偏好设置 - 共享" 中勾选屏幕共享,并选择允许访问的用户(建议新建一个用户)。

Mac OS 远程访问时,通过快捷键 `command + k` 唤出连接服务器页面,输入公网服务器 ip 和 remote_port 配置的端口连接(vnc 协议),例:vnc://云服务器ip:10003。
Window 远程访问时,通过 VNC Viewer 访问,[下载地址](https://www.realvnc.com/en/connect/download/viewer/windows/)。
## 更多配置
以下内容摘录自文档,[查看更多](https://gofrp.org/docs/features/common/configure)。
### HTTP Basic Auth 鉴权
HTTP 类型的代理,在 frpc 的代理配置中添加用户名和密码来保护内网服务。
```ini
# frpc.ini
[web]
type = http
local_port = 80
custom_domains = test.yourdomain.com
http_user = abc
http_pwd = abc
```
### URL 路由
frp 支持根据请求的 URL 路径路由转发到不同的后端服务。
```ini
# frpc.ini
[web01]
type = http
local_port = 80
custom_domains = web.yourdomain.com
locations = /
[web02]
type = http
local_port = 81
custom_domains = web.yourdomain.com
locations = /news,/about
```
按照上述的示例配置后,`web.yourdomain.com` 这个域名下所有以 `/news` 以及 `/about` 作为前缀的 URL 请求都会被转发到 web02,其余的请求会被转发到 web01。
### 服务端端口白名单
为了防止端口被滥用,可以手动指定允许哪些端口被使用,在服务端配置中通过 `allow_ports` 来指定:
```ini
# frps.ini
[common]
allow_ports = 2000-3000,3001,3003,4000-50000
```
`allow_ports` 可以配置允许使用的某个指定端口或者是一个范围内的所有端口,以 `,` 分隔,指定的范围以 `-` 分隔。
### Web 界面
服务端需要在 frps.ini 中指定 dashboard 服务使用的端口,打开浏览器通过 `http://[server_addr]:7500` 访问 Dashboard 界面,输入用户名密码 `admin`。
```ini
# frps.ini
[common]
dashboard_port = 7500
# dashboard 用户名密码,可选,默认为空
dashboard_user = admin
dashboard_pwd = admin
```
客户端需要在 frpc.ini 中指定 admin 服务使用的端口,打开浏览器通过 `http://127.0.0.1:7400` 访问 Admin UI。
```ini
# frpc.ini
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
```
### 加密与压缩
每一个代理都可以选择是否启用加密和压缩的功能。
加密算法采用 aes-128-cfb,压缩算法采用 snappy。
在每一个代理的配置中使用如下参数指定:
```ini
# frpc.ini
[ssh]
type = tcp
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true
```
通过设置 `use_encryption = true`,将 frpc 与 frps 之间的通信内容加密传输,将会有效防止传输内容被截取。
如果传输的报文长度较长,通过设置 `use_compression = true` 对传输内容进行压缩,可以有效减小 frpc 与 frps 之间的网络流量,加快流量转发速度,但是会额外消耗一些 CPU 资源。
## 常见问题
### 1、客户端启动提示无法连接或者连接超时
检查客户端配置文件 frpc.ini 配置的服务器 ip 和端口是否正确。
检查阿里云、腾讯云等云服务器的安全组中是否对外开放配置文件中的端口。
### 2、服务端自动关闭
使用 systemctl 命令启动服务端。

frp 内网穿透