概述
平时我们想从外网访问内网的时候,通常可以用花生壳、nat123之类的服务。
但是这些服务不是开源的,而且还收费,体验也很不稳定,使用的时候不免心理有些犯嘀咕。
对于已经购买过阿里云等服务器的人来说,其实有一个更好的选择frps/frpc.
frps/frpc的主要功能
1.通过 SSH 访问内网机器;
2.通过自定义域名访问内网的服务;
3.转发 DNS 查询请求;
4.转发 Unix 域套接字;
5.对外提供简单的文件访问服务;
6.为本地 HTTP 服务启用 HTTPS;
7.安全地暴露内网服务;
8.点对点内网穿透.
体验结果
1.涵盖了花生壳和nat123的所有功能;
2.从测试结果上,frps/frpc(golang写的)的稳定性更高(相对于花生壳和nat123的免费用户来说),
#http siege的测试结果
Transactions: 678011 hits
Availability: 100.00 %
Elapsed time: 120.00 secs
Data transferred: 6403.18 MB
Response time: 0.02 secs
Transaction rate: 5650.09 trans/sec
Throughput: 53.36 MB/sec
Concurrency: 95.81
Successful transactions: 96911
Failed transactions: 0
Longest transaction: 0.53
Shortest transaction: 0.00
3.支持dashboard和prometheus,非常方便。
4.各种平台都支持;
#支持的平台
frp_0.37.0_darwin_amd64.tar.gz
frp_0.37.0_freebsd_386.tar.gz
frp_0.37.0_freebsd_amd64.tar.gz
frp_0.37.0_linux_386.tar.gz
frp_0.37.0_linux_amd64.tar.gz
frp_0.37.0_linux_arm64.tar.gz
frp_0.37.0_linux_arm.tar.gz
frp_0.37.0_linux_mips64le.tar.gz
frp_0.37.0_linux_mips64.tar.gz
frp_0.37.0_linux_mipsle.tar.gz
frp_0.37.0_linux_mips.tar.gz
frp_0.37.0_windows_386.zip
frp_0.37.0_windows_amd64.zip
frps/frpc获取方式
源码和包:https://github.com/fatedier/frp/releases
文档:https://gofrp.org/docs/examples/xtcp/
运行方法
nohup ./frps -c /etc/frps.ini &
nohup ./frpc -c /etc/frpc.ini &
附录(文档备份)
文档可能不能访问,备份到下面
通过 SSH 访问内网机器
这个示例通过简单配置 TCP 类型的代理让用户访问到内网的服务器。
- 在具有公网 IP 的机器上部署 frps,修改 frps.ini
文件,这里使用了最简化的配置,设置了 frp
服务器用户接收客户端连接的端口:
[common]
bind_port = 7000
- 在需要被访问的内网机器上(SSH 服务通常监听在 22 端口)部署
frpc,修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.x:
[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
local_ip 和 local_port 配置为本地需要暴露到公网的服务地址和端口。remote_port 表示在
frp 服务端监听的端口,访问此端口的流量将会被转发到本地服务对应的端口。
-
分别启动 frps 和 frpc。
-
通过 SSH 访问内网机器,假设用户名为 test:
ssh -oPort=6000 test\@x.x.x.x
frp 会将请求 x.x.x.x:6000 的流量转发到内网机器的 22 端口。
通过自定义域名访问内网的 Web 服务
这个示例通过简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务。
HTTP 类型的代理相比于 TCP
类型,不仅在服务端只需要监听一个额外的端口 vhost_http_port 用于接收 HTTP
请求,还额外提供了基于 HTTP 协议的诸多功能。
- 修改 frps.ini 文件,设置监听 HTTP 请求端口为 8080:
[common]
bind_port = 7000
vhost_http_port = 8080
- 修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为
x.x.x.x,local_port 为本地机器上 Web 服务监听的端口,
绑定自定义域名为 custom_domains。
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com
[web2]
type = http
local_port = 8080
custom_domains = www.yourdomain2.com
-
分别启动 frps 和 frpc。
-
将 www.yourdomain.com 和 www.yourdomain2.com 的域名 A 记录解析到
IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME
记录解析到服务器原先的域名。或者可以通过修改 HTTP 请求的 Host
字段来实现同样的效果。 -
通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上
80
端口的服务,访问 http://www.yourdomain2.com:8080 则访问到内网机器上
8080 端口的服务。
转发 DNS 查询请求
这个示例通过简单配置 UDP 类型的代理转发 DNS 查询请求。
DNS 查询请求通常使用 UDP 协议,frp 支持对内网 UDP 服务的穿透,配置方式和
TCP 基本一致。
- 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
这里反代了 Google 的 DNS 查询服务器的地址,仅仅用于测试 UDP
代理,并无实际意义。
-
分别启动 frps 和 frpc。
-
通过 dig 测试 UDP
包转发是否成功,预期会返回 www.baidu.com 域名的解析结果。
dig @x.x.x.x -p 6000 www.baidu.com
转发 Unix 域套接字
这个示例通过配置 Unix域套接字客户端插件来通过 TCP 端口访问内网的
Unix域套接字服务,例如 Docker Daemon。
- frps.ini 内容如下:
[common]
bind_port = 7000
- 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 和 frpc。
-
通过 curl 命令查看 docker 版本信息
curl <http://x.x.x.x:6000/version
对外提供简单的文件访问服务
这个示例通过配置 static_file 客户端插件来将本地文件暴露在公网上供其他人访问。
通过 static_file 插件可以对外提供一个简单的基于 HTTP 的文件访问服务。
- 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/file
# 用户访问 URL 中会被去除的前缀,保留的内容即为要访问的文件路径
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc
-
分别启动 frps 和 frpc。
-
通过浏览器访问 http://x.x.x.x:6000/static/ 来查看位于 /tmp/file 目录下的文件,会要求输入已设置好的用户名和密码。
为本地 HTTP 服务启用 HTTPS
通过 https2http 插件可以让本地 HTTP 服务转换成 HTTPS 服务对外提供。
- frps.ini 内容如下:
[common]
bind_port = 7000
- frpc.ini 内容如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[test_htts2http]
type = https
custom_domains = test.yourdomain.com
plugin = https2http
plugin_local_addr = 127.0.0.1:80
# HTTPS 证书相关的配置
plugin_crt_path = ./server.crt
plugin_key_path = ./server.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
-
分别启动 frps 和 frpc。
-
通过浏览器访问 https://test.yourdomain.com。
点对点内网穿透
这个示例将会演示一种不通过服务器中转流量的方式来访问内网服务。
frp
提供了一种新的代理类型 xtcp 用于应对在希望传输大量数据且流量不经过服务器的场景。
使用方式同 stcp 类似,需要在两边都部署上 frpc 用于建立直接的连接。
**目前处于开发的初级阶段,并不能穿透所有类型的 NAT
设备,所以穿透成功率较低。穿透失败时可以尝试 stcp 的方式。**
- frps.ini 内容如下,需要额外配置监听一个 UDP
端口用于支持该类型的客户端:
[common]
bind_port = 7000
bind_udp_port = 7000
- 在需要暴露到内网的机器上部署 frpc,且配置如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh]
type = xtcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
- 在想要访问内网服务的机器上也部署 frpc,且配置如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh_visitor]
type = xtcp
# xtcp 的访问者
role = visitor
# 要访问的 xtcp 代理的名字
server_name = p2p_ssh
sk = abcdefg
# 绑定本地端口用于访问 ssh 服务
bind_addr = 127.0.0.1
bind_port = 6000
- 通过 SSH 访问内网机器,假设用户名为 test:
ssh -oPort=6000 test\@127.0.0.1