Frp是一款基于Go语言的反向代理应用, 支持多种协议包括:TCP、UDP、HTTPS、HTTP、STCP、XTCP等, 通过使用Frp我们可以很轻松的实现内网穿透。
下面介绍一下这几种协议在Frp中的用法。
通过Frp将内网的ssh服务以tcp协议的形式暴露到互联网上, 这个框架的原理图如下所示:
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
|client |<----->| frps |<---->| frpc + ssh |
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
框架中frp服务端的配置如下:
# frps.ini
[common]
bind_port = 7000
frp客户端的配置如下:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
通过frp将内网的webService以HTTP协议暴露给互联网,对应的原理如下图所示:
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
|client |<----->| frps |<---->| frpc + web |
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
服务端的配置如下:
# frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080
客户端的配置如下:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = www.example.com
通过Frp将内网的DNS请求通过UDP协议暴露给互联网, 应的原理图如下图所示:
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
|client |<----->| frps |<---->| frpc + DNS |
+-+-+-+-+ +-+-+-+-+ +-+-+-+-+-+-+-+
服务端的配置如下所示:
# frps.ini
[common]
bind_port = 7000
客户端的配置如下所示:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000
为了降低将某些服务直接暴露到公共网络带来的安全风险, Frp提供了STCP(Secret-TCP)协议, 该协议需要使用预共享密钥来从其他客户端访问该服务,从而提高访问的安全性。
STCP协议的原理如下图所示:
+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
|client + frpc(C) |<----->| frps(A) | <---->| frpc + SSH(B) |
+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
服务端的配置如下所示:
# frps.ini
[common]
bind_port = 7000
被访问端的配置如下所示:
# frpc-server.ini
## 被访问的一端(B)
[common]
server_addr = *.*.*.*
server_port = 7000
protocol = kcp
token = 12345678
[secret_tcp]
type = stcp
sk = test
local_ip = 127.0.0.1
local_port = 36900
访问端的配置如下图所示:
# frpc-client.ini
## 访问端(C)
[common]
server_addr = *.*.*.*
server_port = 7000
protocol = kcp
token = 12345678
[secret_tcp_visitor]
type = stcp
role = visitor
server_name = secret_tcp
sk = test
bind_addr = 127.0.0.1
bind_port = 36900
在这种模式下访问端和被访问端都需要安装frpc客户端, 且两边都需要配置好相同的秘钥。相较于TCP协议,它的优点如下:
1.Frps服务端只需要暴露一个端口就可以了,增强了安全性。
2.由于访问端和被访问端通过秘钥访问,且都需要安装frpc,提高了服务暴露的安全性。
xtcp是frp新推出的一种协议,用来解决客户端之间直接传输大量数据的问题。由于协议还不完善, 这种传输方式并不适用于所有的NAT设备。
xtcp协议通信的原理如下图所示:
+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
|client + frpc(C) |<----->| frps(A) | <---->| frpc + SSH(B) |
+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
frp服务端的配置如下所示:
# frps.ini
bind_udp_port = 7001
bind_port = 7000
frp被访问的客户端的配置如下:
# frpc.ini
# 被访问的SSH端(B)
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh]
type = xtcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
frp访问端的配置如下:
# frpc.ini
# ssh访问端(C)
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh_visitor]
type = xtcp
role = visitor
server_name = p2p_ssh
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 6000
访问方式如下:
ssh -oPort=6000 127.0.0.1
服务端只需要开放对应的端口就行了, 客户端对应的配置如下:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock
服务端的配置如下所示:
# frps.ini
[common]
bind_port = 7000
客户端的配置如下所示:
# frpc.ini
[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/files
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc
通过http://x.x.x.x:6000/static/ 访问frpc所在机器上的文件
frp的服务端frps提供了对应的web端控制台,通过该控制台, 我们可以监控frps的统计情况, 启动服务端控制台的配置如下所示:
http访问控制的配置如下:
[common]
# 控制台的端口号
dashboard_port = 7500
# 控制台账号和密码
dashboard_user = admin # 账号
dashboard_pwd = admin # 密码
# 访问地址
# http://[server_addr]:7500访问
https访问控制台的配置如下所示:
[common]
# 控制台的端口号
dashboard_port = 7500
# 控制的账号密码和证书
dashboard_user = admin
dashboard_pwd = admin
dashboard_tls_mode = true
dashboard_tls_cert_file = server.crt
dashboard_tls_key_file = server.key
# https控制的访问地址
# https://[server_addr]:7500
frpc客户端配置控制台访问
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
# http://127.0.0.1:7400