frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

为什么使用 frp ?

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:

  • 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

简单来说:简洁好用,配置方便,只要有一台公网服务器就可以使你的电脑实现内网穿透,将特定的端口映射到公网上去。

测试设备

下面是我的环境:

  • 服务器 ubuntu 20.04 LTS x86_64
  • 本地PC windows 11 22000.376
  • frp v0.38.0

Frps服务端配置

首先我们需要的是一个能够公网访问的服务器,用来将流量转发到内网的机器上面。比如有一个腾讯云/阿里云的服务器,当访问服务器的某个端口,例如50022,然后服务器将访问这个端口的流量转发到内网的服务器上面,例如内网的22端口。

frp项目的github链接:https://github.com/fatedier/frp

1.首先下载一个最新的Release,比如我的服务器是下载AMD64版本

1
wget https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_amd64.tar.gz

使用wget命令下载文件到当前目录下。

2.解压下载后的文件

1
2
tar -zxvf frp_0.38.0_linux_amd64.tar.gz
mv frp_0.38.0_linux_amd64.tar.gz frps

使用tar命令解压文件,并且重命名。

3.打开frps文件夹,编辑frps.ini文件。

1
2
cd frps
vim ./frps.ini

服务端主要用到的就是frps和frps.ini文件,而frpc和frpc.ini则是客户端用的。所以一般服务端可以只保留frps相关,客户端只保留frpc相关。
vim的插入是i,退出保存是先按esc退出插入模式,然后输入:wq保存并退出。

4.输入内容如下所示。

1
2
3
[common]
bind_addr = 0.0.0.0
bind_port = 7000

frp-2022-01-14-22-40-14

5.启动

1
./frps -c frps.ini

若是提示permission denied之类的,可以修改文件夹属性为777。命令sudo chmod 777 -R ./

6.正常情况下是可以看到启动成功日志。

1
2
3
2022/01/14 17:27:41 [I] [service.go:136] frps tcp listen on 0.0.0.0:7001
2022/01/14 17:27:41 [I] [service.go:178] http service listen on 0.0.0.0:8006
2022/01/14 17:27:41 [I] [root.go:204] Start frps success

frpc客户端配置

客户端需要连接服务端,而且需要下载对应操作系统的Release。

1.Windows端的下载和解压安装不再赘述,接下来只需要用记事本打开frpc.ini,修改配置如下所示。

1
2
3
4
5
6
7
8
9
[common]
server_addr = xx.xx.xx.xx
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 9999
remote_port = 9999

[common]下面的是连接服务器的配置
server_addr是服务器端的IP地址。
server_port是服务器端的bind_port端口。

[ssh]这个是示例连接的名字,当然你也可以换个名字,叫啥都行,比如[someConnect]、[video]都可以。
type是指当前这个连接的协议类型。
local_ip是指内网主机的IP,一般用127.0.0.1代表本机回环地址。
local_port是指本地需要映射的端口。
remote_port是指远程服务端的端口。

如果需要映射多个端口,只需要将上面部分(不是common)再复制一遍即可。例如

1
2
3
4
5
6
7
8
9
10
11
[example1]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 50022

[example1]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 53389

2.使用命令启动。
./frpc.exe -c frpc.ini

3.输出日志。

1
2
3
2022/01/14 17:28:21 **[I] [service.go:221] login to server success, get run id [3435ffb8820dbcf1], server udp port [0]**
2022/01/14 17:27:41 **[I] [proxy_manager.go:137] [3435ffb8820dbcf1] proxy added: [web]**
2022/01/14 17:27:41 **[I] [control.go:144] [web] start proxy success**

访问

最后就可以通过http://xx.xx.xx.xx:9999来访问windows的9999端口了。

当然,我希望随着ipv6的普及,内网穿透会有无用武之地的一天吧。但是至少近几年还不行。