FRP(Fast Reverse Proxy)快速反向代理
官方介绍:“frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。frp 采用go语言开发。更多的人使用 frp 是为了进行反向代理,满足通过公网服务器访问处于内网的服务,如访问内网web服务,远程ssh内网服务器,远程控制内网NAS等,实现类似花生壳、ngrok等功能。而对于内网渗透来讲,这种功能恰好能够满足我们进行内网渗透的流量转发。FRP最大的一个特点是使用SOCKS代理,而SOCKS是加密通信的,类似于做了一个加密的隧道,可以把外网的流量,通过加密隧道穿透到内网。效果有些类似于VPN。”太啰嗦一句话总结:将内网机映射到公网上,使其可以被任何人访问。
在很多情况下我们的物理主机、家庭服务器、NAS等都处于路由器下的局域网内网环境中,这些设备没有公网ip,我们无法通过互联网直接远程访问到。如下情况:你在公司想要远程访问你家里的电脑。你的破群晖虽然好几十个t容量,没有公网ip只能在家里访问,无奈却只能放在家里存“小电影”。在做内网渗透的时候某些情况下需使用沦陷主机作为跳板机让内网机出网,渗透环境多变情况复杂极多时候都需要将内网主机映射到公网。如上所说的几种情况大致如下图所示(局域网A、局域网B中的主机都可以访问外网,但是不可以相互访问):
管方给出的:通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:
客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。
采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
代理组间的负载均衡。
端口复用,多个服务通过同一个服务端端口暴露。
多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
服务端和客户端 UI 页面。
效果好不好当然谁用谁知道,亲测使用过程中的感悟:
客户端和服务端配置简单,运行简单,简单易用,文档丰富
可通过自定义域名访问内网服务
可通过设置点对点的方式实现安全地内网服务访问,避免任何人都能访问穿透的服务
部署示意图:
工作过程:1.服务端运行监听一个主端口等待客户端连接。2.客户端连接到服务端并发送监听端口和服务类型。3.服务端收到客户端指令后,将客户端需要转发的端口映射在新的端口上。4.我们访问服务端ip+映射后的端口,服务端将流量请求转发到内网地址映射端口上。
软件下载:https://github.com/fatedier/frp/releases/tag/v0.34.3
根据实际应用场景进行下载,每个压缩包中包含客户端和服务端两个程序,部署在服务端使用时运行服务端frps程序即可,部署在客户端使用时运行frpc程序即可。
# [common] 是必需的
[common]
# ipv6的文本地址或主机名必须括在方括号中
# 如"[::1]:80", "[ipv6-host]:http" 或 "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 7000
# udp nat 穿透端口
bind_udp_port = 7001
# 用于 kcp 协议 的 udp 端口,可以与 "bind_port" 相同
# 如果此项不配置, 服务端的 kcp 将不会启用
kcp_bind_port = 7000
# 指定代理将侦听哪个地址,默认值与 bind_addr 相同
# proxy_bind_addr = 127.0.0.1
# 如果要支持虚拟主机,必须设置用于侦听的 http 端口(非必需项)
# 提示:http端口和https端口可以与 bind_port 相同
vhost_http_port = 80
vhost_https_port = 443
# 虚拟 http 服务器的响应头超时时间(秒),默认值为60s
# vhost_http_timeout = 60
# 设置 dashboard_addr 和 dashboard_port 用于查看 frps 仪表盘
# dashboard_addr 默认值与 bind_addr 相同
# 只有 dashboard_port 被设定,仪表盘才能生效
dashboard_addr = 0.0.0.0
dashboard_port = 7500
# 设置仪表盘用户密码,用于基础认证保护,默认为 admin/admin
dashboard_user = admin
dashboard_pwd = admin
# 仪表板资产目录(仅用于 debug 模式下)
# assets_dir = ./static
# 控制台或真实日志文件路径,如./frps.log
log_file = ./frps.log
# 日志级别,分为trace(跟踪)、debug(调试)、info(信息)、warn(警告)、error(错误)
log_level = info
# 最大日志记录天数
log_max_days = 3
# 认证 token
token = 12345678
# 心跳配置, 不建议对默认值进行修改
# heartbeat_timeout 默认值为 90
# heartbeat_timeout = 90
# 允许 frpc(客户端) 绑定的端口,不设置的情况下没有限制
allow_ports = 2000-3000,3001,3003,4000-50000
# 如果超过最大值,每个代理中的 pool_count 将更改为
max_pool_count max_pool_count = 5
# 每个客户端可以使用最大端口数,默认值为0,表示没有限制
max_ports_per_client = 0
# 如果 subdomain_host 不为空, 可以在客户端配置文件中设置 子域名类型为 http 还是 https
# 当子域名为 test 时, 用于路由的主机为 test.frps.com
subdomain_host = frps.com
# 是否使用 tcp 流多路复用,默认值为
true tcp_mux = true
# 对 http 请求设置自定义 404 页面
# custom_404_page = /path/to/404.html
客户端详细配置
# [common] 是必需的
[common]
# ipv6的文本地址或主机名必须括在方括号中
# 如"[::1]:80", "[ipv6-host]:http" 或 "[ipv6-host%zone]:80"
server_addr = 0.0.0.0
server_port = 7000
# 如果要通过 http 代理或 socks5 代理连接 frps,可以在此处或全局代理中设置 http_proxy
# 只支持 tcp协议
# http_proxy = http://user:[email protected]:8080
# http_proxy = socks5://user:[email protected]:1080
# 控制台或真实日志文件路径,如./frps.log
log_file = ./frpc.log
# 日志级别,分为trace(跟踪)、debug(调试)、info(信息)、warn(警告)、error(错误)
log_level = info
# 最大日志记录天数
log_max_days = 3
# 认证 token
token = 12345678
# 设置能够通过 http api 控制客户端操作的管理地址
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
# 将提前建立连接,默认值为 0
pool_count = 5
# 是否使用 tcp 流多路复用,默认值为 true,必需与服务端相同
tcp_mux = true
# 在此处设置用户名后,代理名称将设置为 {用户名}.{代理名}
user = your_name
# 决定第一次登录失败时是否退出程序,否则继续重新登录到 frps
# 默认为 true
login_fail_exit = true
# 用于连接到服务器的通信协议
# 目前支持 tcp/kcp/websocket, 默认 tcp
protocol = tcp
# 如果 tls_enable 为 true, frpc 将会通过 tls 连接 frps
tls_enable = true
# 指定 DNS 服务器
# dns_server = 8.8.8.8
# 代理名, 使用 ',' 分隔
# 默认为空, 表示全部代理
# start = ssh,dns
# 心跳配置, 不建议对默认值进行修改
# heartbeat_interval 默认为 10 heartbeat_timeout 默认为 90
# heartbeat_interval = 30
# heartbeat_timeout = 90
# 'ssh' 是一个特殊代理名称 [ssh]
# 协议 tcp | udp | http | https | stcp | xtcp, 默认 tcp type = tcp
local_ip = 127.0.0.1
local_port = 22
# 是否加密, 默认为 false
use_encryption = false
# 是否压缩
use_compression = false
# 服务端端口
remote_port = 6001
# frps 将为同一组中的代理进行负载平衡连接
group = test_group
# 组应该有相同的组密钥
group_key = 123456
# 为后端服务开启健康检查, 目前支持 'tcp' 和 'http'
# frpc 将连接本地服务的端口以检测其健康状态
health_check_type = tcp
# 健康检查连接超时
health_check_timeout_s = 3
# 连续 3 次失败, 代理将会从服务端中被移除
health_check_max_failed = 3
# 健康检查时间间隔
health_check_interval_s = 10
[ssh_random]
type = tcp
local_ip = 127.0.0.1
local_port = 22
# 如果 remote_port 为 0 ,frps 将为您分配一个随机端口
remote_port = 0
# 如果要暴露多个端口, 在区块名称前添加 'range:' 前缀
# frpc 将会生成多个代理,如 'tcp_port_6010', 'tcp_port_6011'
[range:tcp_port]
type = tcp
local_ip = 127.0.0.1
local_port = 6010-6020,6022,6024-6028
remote_port = 6010-6020,6022,6024-6028
use_encryption = false
use_compression = false
[dns]
type = udp
local_ip = 114.114.114.114
local_port = 53 remote_port = 6002
use_encryption = false
use_compression = false
[range:udp_port]
type = udp
local_ip = 127.0.0.1
local_port = 6010-6020
remote_port = 6010-6020
use_encryption = false
use_compression = false
# 将域名解析到 [server_addr] 可以使用 http://web01.yourdomain.com 访问 web01
[web01]
type = http local_ip = 127.0.0.1
local_port = 80
use_encryption = false
use_compression = true
# http 协议认证
http_user = admin
http_pwd = admin
# 如果服务端域名为 frps.com, 可以通过 http://test.frps.com 来访问 [web01]
subdomain = web01
custom_domains = web02.yourdomain.com
# locations 仅可用于HTTP类型
locations = /,/pic
host_header_rewrite = example.com
# params with prefix "header_" will be used to update http request headers
header_X-From-Where = frp
health_check_type = http
# frpc 将会发送一个 GET http 请求 '/status' 来定位http服务
# http 服务返回 2xx 状态码时即为存活
health_check_url = /status
health_check_interval_s = 10
health_check_max_failed = 3
health_check_timeout_s = 3
[web02]
type = https
local_ip = 127.0.0.1
local_port = 8000
use_encryption = false
use_compression = false
subdomain = web01
custom_domains = web02.yourdomain.com
# v1 或 v2 或 空
proxy_protocol_version = v2
[plugin_unix_domain_socket]
type = tcp remote_port = 6003
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock
[plugin_http_proxy]
type = tcp
remote_port = 6004
plugin = http_proxy
plugin_http_user = abc
plugin_http_passwd = abc
[plugin_socks5]
type = tcp
remote_port = 6005
plugin = socks5
plugin_user = abc
plugin_passwd = abc
[plugin_static_file]
type = tcp
remote_port = 6006
plugin = static_file
plugin_local_path = /var/www/blog
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc
[plugin_https2http]
type = https
custom_domains = test.yourdomain.com
plugin = https2http
plugin_local_addr = 127.0.0.1:80
plugin_crt_path = ./server.crt
plugin_key_path = ./server.key
plugin_host_header_rewrite = 127.0.0.1
[secret_tcp]
# 如果类型为 secret tcp, remote_port 将失效
type = stcp
# sk 用来进行访客认证
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false
# 访客端及服务端的用户名应该相同
[secret_tcp_visitor]
# frpc role visitor -> frps -> frpc role server
role = visitor
type = stcp
# 要访问的服务器名称
server_name = secret_tcp
sk = abcdefg
# 将此地址连接到访客 stcp 服务器
bind_addr = 127.0.0.1
bind_port = 9000
use_encryption = false
use_compression = false
[p2p_tcp]
type = xtcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false
[p2p_tcp_visitor]
role = visitor
type = xtcp
server_name = p2p_tcp
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 9001
use_encryption = false
use_compression = false
根据实际使用环境进行服务配置(可参考下一节示例列举)配置好服务端和客户端后,在配置文件根目录下使用命令行分别运行服务端和客户端。
# 服务端
./frps -c frps.ini
# 客户端
frpc -c frpc.ini
在对某内网的web网站进行渗透,无法直接接入用户内网。只有一台可访问外网的内网主机,通过内网主机代理转发内网web服务,使内网不出网web服务器服务经过可访问公网的内网主机映射到公网。
frps服务端配置(公网vps):
[common]
bind_port = 7000 #与客户端建立连接使用的端口
frpc服务端配置(内网主机ip129):
[common]
server_addr = x.x.x.x # 服务端VPS的ip
server_port = 7000 #服务端建立连接使用的端口,配置需同客户端bind_port一致
[web] #服务名
type = tcp #连接协议
local_ip = 192.168.183.128 #需要穿透出去的内网ip,这里是内网web服务器的ip
local_port = 80 #本地端口,这里指内网web服务的原端口
remote_port = 8080 #映射后使用的端口,指映射后公网访问时使用的端口
配置完成后分别启动服务端和客户端进行服务连接(注意:使用VPS注意防火墙、宝塔、安全策略等放行端口)
尝试访问
在很多时候我们想要访问不同局域网下的主机,除了使用各种远控工具也可以使用frp实现,可将局域网内的主机3389映射在公网后使用远程桌面进行连接,此功能更多的用在家庭nas服务器中
frps服务端配置:
[common]
bind_port = 7000
frpc客户端配置:
[common]
server_addr = 81.70.154.135
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 8080
配置完成后分别启动服务端和客户端进行服务连接(注意:使用VPS注意防火墙、宝塔、安全策略等放行端口)
在客户端新建测试账户进行测试。
通过frp搭建socks5反向代理,让自己的电脑走内网流量。
frps服务端配置:
[common]
bind_port = 7000
dashboard_port = 46075
dashboard_user = admin
dashboard_pwd = password
token = 123qwe
heartbeat_timeout = 90
max_pool_count = 5
frpc客户端配置:
[common]
server_addr = 81.70.154.135server_port = 7000
token = 123qwe
pool_count = 5
protocol = tcp
health_check_type = tcp
health_check_interval_s = 100
[socks_test]
remote_port = 10000
plugin = socks5
plugin_user = admin
plugin_passwd = password
use_encryption = true
use_compression = true
配置完成后分别启动服务端和客户端进行服务连接(注意:使用VPS注意防火墙、宝塔、安全策略等放行端口)
登录proxifier:
参考连接:https://blog.csdn.net/qq_34801745/article/details/111146475
https://gofrp.org/docs/examples/ssh/
E
N
D
关
于
我
们
Tide安全团队正式成立于2019年1月,是新潮信息旗下以互联网攻防技术研究为目标的安全团队,团队致力于分享高质量原创文章、开源安全工具、交流安全技术,研究方向覆盖网络攻防、系统安全、Web安全、移动终端、安全开发、物联网/工控安全/AI安全等多个领域。
团队作为“省级等保关键技术实验室”先后与哈工大、齐鲁银行、聊城大学、交通学院等多个高校名企建立联合技术实验室。团队公众号自创建以来,共发布原创文章400余篇,自研平台达到31个,目有18个平台已开源。此外积极参加各类线上、线下CTF比赛并取得了优异的成绩。如有对安全行业感兴趣的小伙伴可以踊跃加入或关注我们。