FRP教程(一):基本反向代理

还是很久以前对树莓派做内网穿透的时候用了一下FRP,最近又想了起来。我觉得FRP作为一个重要而方便的反向代理网络工具,值得去学习使用。

FRP简介

FRP (Fast Reverse Proxy,快速反向代理),是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透。

下载FRP

FRP的Github Release里找到对应的版本,这里以常见Linux云服务器(x86)进行演示。

首先获取.tar.gz包(此时的最新版本是0.33)

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

然后解压

1
tar -xzf frp_0.33.0_linux_amd64.tar.gz

再进入FRP目录

1
cd frp_0.33.0_linux_amd64

使用(一):反向代理TCP服务

先界定术语:

  • 服务端:具有公网IP,运行FRP服务端,即frps
  • 客户端:一般是没有公网IP的内网设备,需要进行内网穿透,运行FRP客户端,即frpc

假设,在家庭内网有一个内网服务器,需要可以在公网对其进行SSH连接。同时,我们拥有一台具有公网IP的Linux云服务器。

对于服务端,也即Linux云服务器,要设置服务端配置,编辑frps.ini

1
vim frps.ini

可以看到里面已经有一个[common]配置区域,有bind_port = 7000的配置。

1
2
[common]
bind_port = 7000

在此应用场景下,这个配置可以不需要变动。如果你发现7000端口已经被占用,或者基于其他原因,也是可以修改的。

bind_port端口定义了FRP服务端的进程位置,是客户端对服务端通信的端口。

当然,需要你打开服务端防火墙的对应端口。

对于客户端,也即家庭内网服务器,编辑frpc.ini

1
vim frpc.ini

修改配置为

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

[ssh]
type = tcp
local_port = 22
remote_port = 6000

客户端的common配置区域指定了要连接的服务器地址和端口,ssh配置区域指定了传输协议为TCP,需要被反代的本地端口为22,且希望将本地端口映射在服务器的6000端口。

完成配置之后,进行运行:

  1. 先运行服务端./frps -c ./frps.ini,这段命令的意思是,运行本目录可执行文件frps,指定配置文件为本目录下文件frps.ini
  2. 再运行客户端./frpc -c ./frpc.ini,意义同理

详解工作流程

  1. 先运行服务端,服务端开始监听本地的7000端口
  2. 再运行客户端,客户端阅读frpc.ini中的common设置的服务端地址和端口与服务端进行通信
  3. 客户端告诉服务端其ssh的设置,客户端说:协议是TCP,本地需被代理的端口是22,希望你 (服务器) 能监听6000端口
  4. 用户向服务端的6000端口发起SSH连接,服务端将TCP流量转发给客户端,客户端22端口收到TCP流量,与用户成功建立SSH连接

使用(二):反代内网HTTP服务

经过使用(一)的讲解,使用(二)将直接放配置文件

服务端配置:

1
2
3
[common]
bind_port = 7000
vhost_http_port = 8080

客户端配置:

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

[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com

www.yourdomain.com解析到服务端上,则访问http://www.yourdomain.com:8080即可访问内网HTTP服务

使用(三):简单文件访问

这个功能可以对内网服务器做一个简单的HTTP文件服务,但其实只要反代了SSH,也可以通过FTP over SSH的方法传输文件。

客户端设置(启用static_file插件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[common]
server_addr = x.x.x.x
server_port = 7000

[test_static_file]
type = tcp
remote_port = 6000
plugin = static_file
# 要对外暴露的文件目录
plugin_local_path = /tmp/file
# 访问 url 中会被去除的前缀,保留的内容即为要访问的文件路径
plugin_strip_prefix = static
plugin_http_user = user
# web验证的用户名密码
plugin_http_passwd = passwd

通过浏览器访问http://x.x.x.x:6000/static/就能查看位于/tmp/file/目录的文件。