通过FRP进行内网穿透
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
下载
客户端与服务端都在压缩包中,只需要选择自己所使用的平台下载即可
部署
frp 主要由 客户端(frpc) 和 服务端(frps) 组成,服务端通常部署在具有公网 IP 的机器上,客户端通常部署在需要穿透的内网服务所在的机器上。
内网服务由于没有公网 IP,不能被非局域网内的其他用户访问。
用户通过访问服务端的 frps,由 frp 负责根据请求的端口或其他信息将请求路由到对应的内网机器,从而实现通信。
服务器端部署
要在服务器端上部署FRP,首先要确保你的服务器拥有一个公网ip,才能通过公网地址来进行访问
下面通过在ubuntu20.04上进行安装来演示
创建文件夹并下载linux版本的frp
mkdir frp && cd frp
wget https://github.com/fatedier/frp/releases/download/v0.45.0/frp_0.45.0_linux_arm64.tar.gz
解压
tar -zxvf frp_0.45.0_linux_arm64.tar.gz
mv ./frp_0.45.0_linux_arm64/* ./ && rm -rf ./frp_0.45.0_linux_arm64
rm -f frp_0.45.0_linux_arm64.tar.gz
可以看到其中包含frps和frpc的程序以及配置文件。由于是配置服务器端,这里只需要用到frps,可以将frpc的相关文件删除
接下来对服务器端的配置文件进行修改
vim frps.ini
默认的配置只绑定了一个7000端口,这里需要按需添加自己的配置
基础配置参数
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
bind_addr | string | 服务端监听地址 | 0.0.0.0 | ||
bind_port | int | 服务端监听端口 | 7000 | 接收 frpc 的连接 | |
bind_udp_port | int | 服务端监听 UDP 端口 | 0 | 用于辅助创建 P2P 连接 | |
kcp_bind_port | int | 服务端监听 KCP 协议端口 | 0 | 用于接收采用 KCP 连接的 frpc | |
proxy_bind_addr | string | 代理监听地址 | 同 bind_addr | 可以使代理监听在不同的网卡地址 | |
log_file | string | 日志文件地址 | ./frps.log | 如果设置为 console,会将日志打印在标准输出中 | |
log_level | string | 日志等级 | info | trace, debug, info, warn, error | |
log_max_days | int | 日志文件保留天数 | 3 | ||
disable_log_color | bool | 禁用标准输出中的日志颜色 | false | ||
detailed_errors_to_client | bool | 服务端返回详细错误信息给客户端 | true | ||
tcp_mux_keepalive_interval | int | tcp_mux 的心跳检查间隔时间 | 60 | 单位:秒 | |
tcp_keepalive | int | 和客户端底层 TCP 连接的 keepalive 间隔时间,单位秒 | 7200 | 负数不启用 | |
heartbeat_timeout | int | 服务端和客户端心跳连接的超时时间 | 90 | 单位:秒 | |
user_conn_timeout | int | 用户建立连接后等待客户端响应的超时时间 | 10 | 单位:秒 | |
udp_packet_size | int | 代理 UDP 服务时支持的最大包长度 | 1500 | 服务端和客户端的值需要一致 | |
tls_cert_file | string | TLS 服务端证书文件路径 | |||
tls_key_file | string | TLS 服务端密钥文件路径 | |||
tls_trusted_ca_file | string | TLS CA 证书路径 |
这里简单地进行配置
[common]
bind_port = 7000
bind_addr = 0.0.0.0
;验证超时时间
authentication_timeout = 900
;这里是配置仪表板选项
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin
;通过token进行身份校验
;需要在frpc和frps的[common]段落中配置上相同的token参数即可
token = 114514
配置完成后,引入配置文件进行启动即可
./frps -c ./frps.ini
如果这里执行的时候出现bash: ./frps: cannot execute binary file:
的报错,说明没有选对平台或架构,上文安装是基于arm架构的linux,需要下载其他的请前往前文的release页面下载。
客户端部署
前往Release页面下载windows版
同理,客户端只需要保留fprc的相关文件即可
直接编辑相关的配置文件frpc.ini
[common]
server_addr = 公网ip
server_port = 7000
token = 114514
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
在common配置了相关的连接信息后,我们就可以添加自己需要的穿透端口。
如上代码,我配置了一个tcp协议的穿透,映射本地的22端口到服务器上的6000端口
同理,如果要配置Windows自带的远程连接,只需要把3389端口映射到服务器即可
[RDP]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 3389
配置完成后,同服务端一样通过命令行的方式引入配置文件
frpc.exe -c frpc.ini
如果连接成功,会提示start proxy success
持久化
服务器端持久化
服务器端持久化有许多方式,最简单的用nohup来使程序在后台运行
nohup ./frps -c ./frps.ini > frps-common.log 2>&1 &
也可以通过创建screen的方式来进行持久化部署
yum install screen
创建一个screen窗口名为frps
screen -S frps
在窗口中按上文的方法运行
后续要进入这个窗口,使用screen -ls
查看frp窗口的id,然后用screen -r {id}
来进入
客户端持久化
在Windows下开启客户端需要一直保持开启一个CMD窗口,这样既不方便也不美观。而且也有可能导致误关窗口
这里我的解决方案是:将命令封装为Windows的服务,来实现开机自启动以及后台无窗运行
这里需要使用一个封装工具:WinSW
它只有一个exe程序。使用方法也很简单,首先将下载好的winsw放到frp目录中,然后新建一个winsw.xml
文件,写入以下信息
<service>
<!--id名:必须唯一-->
<id>FrpClient</id>
<!--服务名-->
<name>frpc</name>
<!--服务描述-->
<description>frpc服务</description>
<!--执行程序-->
<executable>frpc</executable>
<!--参数-->
<arguments>-c frpc.ini</arguments>
<!--程序出错时操作-->
<onfailure action="restart" delay="60 sec"/>
<onfailure action="restart" delay="120 sec"/>
<logmode>reset</logmode>
</service>
配置完成后,需要以管理员身份在cmd中执行以下命令来进行封装服务
winsw.exe install
成功后,就可以在服务中看到你封装后的frpc服务了
P2P点对点穿透
frp 提供了一种新的代理类型 xtcp
用于应对在希望传输大量数据且流量不经过服务器的场景。
使用方式同 stcp
类似,需要在两边都部署上 frpc 用于建立直接的连接。
首先需要在服务器上额外配置一个UDP端口用于支持该类型的客户端
[common] bind_port = 7000 bind_udp_port = 7000
在需要暴露到外网的机器上部署frpc,并增加如下配置
[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
- 配置成功后,就可以在需要访问内网的机器上通过
127.0.0.1:6000
来点对点地访问内网的ssh服务了