通过FRP进行内网穿透

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

下载

FRP官方文档

Release页面

客户端与服务端都在压缩包中,只需要选择自己所使用的平台下载即可

部署

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_addrstring服务端监听地址0.0.0.0
bind_portint服务端监听端口7000 接收 frpc 的连接
bind_udp_portint服务端监听 UDP 端口0 用于辅助创建 P2P 连接
kcp_bind_portint服务端监听 KCP 协议端口0 用于接收采用 KCP 连接的 frpc
proxy_bind_addrstring代理监听地址同 bind_addr 可以使代理监听在不同的网卡地址
log_filestring日志文件地址./frps.log 如果设置为 console,会将日志打印在标准输出中
log_levelstring日志等级infotrace, debug, info, warn, error
log_max_daysint日志文件保留天数3
disable_log_colorbool禁用标准输出中的日志颜色false
detailed_errors_to_clientbool服务端返回详细错误信息给客户端true
tcp_mux_keepalive_intervalinttcp_mux 的心跳检查间隔时间60 单位:秒
tcp_keepaliveint和客户端底层 TCP 连接的 keepalive 间隔时间,单位秒7200 负数不启用
heartbeat_timeoutint服务端和客户端心跳连接的超时时间90 单位:秒
user_conn_timeoutint用户建立连接后等待客户端响应的超时时间10 单位:秒
udp_packet_sizeint代理 UDP 服务时支持的最大包长度1500 服务端和客户端的值需要一致
tls_cert_filestringTLS 服务端证书文件路径
tls_key_filestringTLS 服务端密钥文件路径
tls_trusted_ca_filestringTLS 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

Release页面

它只有一个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服务了

image-20221112105426326

P2P点对点穿透

frp 提供了一种新的代理类型 xtcp 用于应对在希望传输大量数据且流量不经过服务器的场景。

使用方式同 stcp 类似,需要在两边都部署上 frpc 用于建立直接的连接。

  1. 首先需要在服务器上额外配置一个UDP端口用于支持该类型的客户端

    [common]
    bind_port = 7000
    bind_udp_port = 7000
  2. 在需要暴露到外网的机器上部署frpc,并增加如下配置

    [p2p_ssh]
    type = xtcp
    # 只有 sk 一致的用户才能访问到此服务
    sk = abcdefg
    local_ip = 127.0.0.1
    local_port = 22
  3. 在另一台需要访问到内网服务的设备上也部署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
  4. 配置成功后,就可以在需要访问内网的机器上通过127.0.0.1:6000来点对点地访问内网的ssh服务了
最后修改:2023 年 07 月 14 日
如果觉得我的文章对你有用,能不能v我50参加疯狂星期四