frp 实现内网穿透

Jensen NetWorkfrp 实现内网穿透已关闭评论131阅读模式

背景

内网穿透又叫 NAT 穿透,常用工具比如 ngrok、花生壳、frp等,本篇文章的主题frp。

NAT是在IP数据包通过路由器或防火墙时重写IP地址技术。因为公网IP数量有限,不能给每个设备分配一个公网IP,通过多台计算机共用一个公网IP地址对外通讯,使用NAT对通信地址进行网络转换此。

frp内网穿透的四种模式:tcp、udp、stcp、xtcp

frp xtcp是什么,frp stcp是什么

FRP内网映射,穿透工具,FRP内网转发

系统:Windows/Linux

软件:FRP

软件下载:frp_0.34.3_windows_amd64.zip

frp_0.34.3_linux_amd64.tar.gz

项目地址:https://github.com/fatedier/frp/releases

参考文档:https://gofrp.org/docs/

新教材:https://www.zhuguodong.com/?id=558

早期介绍教材:https://www.zhuguodong.com/?id=418

其它Linux资料:http://www.nasge.com/archives/17.html

代理类型

frp 支持多种代理类型来适配不同的使用场景。

类型 描述
tcp 单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。
udp 单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。
http 针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。
https 针对 HTTPS 应用定制了一些额外的功能。
stcp 安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
sudp 安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
xtcp 点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。
tcpmux 支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。

什么是frp?

frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。frp 是一款跨平台的内网穿透工具,支持 Windows、macOS 与 Linux,它需要你有一台拥有固定公网 IP 的电脑,VPS 最好,然后就能愉快的进行内网穿透了。还支持 https,甚至可以用它进行小程序开发。

frp项目的github地址

frp 的作用

  • 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务。
  • 对于 http 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个80端口。
  • 利用处于内网或防火墙后的机器,对外网环境提供 tcp 服务,例如在家里通过 ssh 访问处于公司内网环境内的主机。
  • 可查看通过代理的所有 http 请求和响应的详细信息。(待开发)

使用示例

根据对应的操作系统及架构,从 frp的Release 页面下载最新版本的程序。

将 frps 及 frps.ini 放到具有公网 IP 的机器上。

将 frpc 及 frpc.ini 放到处于内网环境的机器上。

然后配置frps.ini或frpc.ini 文件中的内容。

服务器端用命令frps -c frps.ini来启动frp。

客户端用命令frpc -c frpc.ini来启动frp。

frp的四种模式:tcp、udp、stcp、xtcp

  • tcp和udp:就是将普通的tcp端口或者udp端口映射到公网上,相当于你的设备直接向公网暴露了一个tcp端口。任何设备都可以尝试连接这个端口。这里就会有很大的安全风险。
  • stcp:出于安全和防止攻击的考虑,frp提供了使用密钥验证的tcp,这就是frp的Secret TCP(stcp)模式。示意图如下:

frp 实现内网穿透-图片1

  • xtcp:目的是让两个客户具有直接相连。在正式运行时,其实并不需要服务端做什么事情。
    frp客户端就好比两个相亲的对象,frp服务端是媒婆。媒婆介绍完之后,就应该让两个相亲对象自己去聊天了。这个就是点对点模式(p2p)。在frp中,这个可以通过设置xtcp实现。
    这种模式的好处是不需要消耗服务器的带宽和网速,延时也较低。
    (该模式还在开发完善阶段,不太稳定,很多时候会出现连不上情况。并且与两端的路由器防火墙、DMZ、UPNP设置都有一些关系。)

frp 实现内网穿透-图片2frp 实现内网穿透-图片2

点对点内网穿透

在传输大量数据时如果都经过服务器中转的话,这样会对服务器端带宽压力比较大。

FRP 提供了一种新的代理类型 XTCP 来解决这个问题,XTCP 模式下可以在传输大量数据时让流量不经过服务器中转。实现方式是在传输数据的两端都部署上 FRP 客户端上用于建立直接的连接。

客户端 ->Internet ->服务端VPS ->FRP ->客户端

首先在 FRP 服务端 配置上增加一个 UDP 端口用于支持该类型的客户端: bind_udp_port = 7001

其中,客户端B是需要做端口映射的电脑。Visitor是访问端的电脑,只用于stcp模式和xtcp模式。

基本实现原理

frp 分为服务端与客户端,服务端运行在有公网 IP 服务器上,客户端运行在局域网内设备上,服务端默认会先开放 7000 端口,然后客户端与其相连。

frp 实现内网穿透-图片3

同时客户端可以开启用于 ssh 的端口,与服务端的某个端口做映射,这样我们在终端访问服务端的端口时,会自动转发到客户端去。

frp 实现内网穿透-图片4

除了 ssh 端口之外,frp 还支持 web 端口来接收 http 访问。

除了 ssh 端口之外,frp 还支持 web 端口来接收 http 访问。

安装使用

目前需要公网服务器、内网服务器各一台,我的内网服务器重装了 linux 系统,方便试验各类工具。

服务端安装配置

wget https://github.com/fatedier/frp/releases/download/v0.33.0/frp_0.33.0_linux_amd64.tar.gz
tar zxvf frp_0.33.0_linux_amd64.tar.gz
cd frp_0.33.0_linux_amd64/

服务端的配置文件是 frps.ini,默认绑定 7000 端口,如果购置了云服务器,注意打开 7000 端口。

[common]
bind_port = 7000

通过 fprs 二进制文件启动 frp 服务。

./frps -c ./frps.ini

如下提示即是安装成功。

2020/05/15 22:16:29 [I] [service.go:178] frps tcp listen on 0.0.0.0:7000
2020/05/15 22:16:29 [I] [root.go:209] start frps success
2020/05/15 22:16:38 [I] [service.go:432] [e3c5096bd4291972] client login info: ip [14.114.230.168:44422] version [0.24.1] hostname [] os [linux] arch [amd64]
2020/05/15 22:16:38 [I] [tcp.go:63] [e3c5096bd4291972] [ssh] tcp proxy listen port [7001]
2020/05/15 22:16:38 [I] [control.go:445] [e3c5096bd4291972] new proxy [ssh] success

客户端安装配置

把自己的破电脑拿出来,以同样的方式下载 frp。

wget https://github.com/fatedier/frp/releases/download/v0.33.0/frp_0.33.0_linux_amd64.tar.gz
tar zxvf frp_0.33.0_linux_amd64.tar.gz
cd frp_0.33.0_linux_amd64/

客户端的配置文件是 frpc.ini。

[common]
server_addr = 127.0.0.1
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

common 为通用配置

  • server_addr 为公网服务器 IP 地址
  • server_port 为公网服务器配置的 7000 端口

ssh 用于终端命令行访问

  • type 连接类型,默认为 tcp
  • local_ip 本地 IP
  • local_port 用于 ssh 的端口号,默认 22
  • remote_port 映射的服务端端口,访问该端口时默认转发到客户端的 22 端口

启动客户端进程

./frpc -c ./frpc.ini

如有以下提示则代表与服务端连接成功

2020/05/15 22:34:49 [I] [service.go:282] [9bc650122a538aab] login to server success, get run id [9bc650122a538aab], server udp port [0]
2020/05/15 22:34:49 [I] [proxy_manager.go:144] [9bc650122a538aab] proxy added: [ssh]
2020/05/15 22:34:49 [I] [control.go:179] [9bc650122a538aab] [ssh] start proxy success

测试

启动完成后就可以通过 ssh 连接到内网服务器了。

ssh -p 6000 [email protected]

https://github.com/pingyeaa/go-home

文档:

https://gofrp.org/docs/

https://github.com/fatedier/frp/blob/dev/README_zh.md

GitHub:https://github.com/fatedier/frp

_______________________________________________________________________________________

搭建

首先我们要准备 公网IP服务器一台(必要),其他机器若干台(我管你多少台),虚拟机也可以。

接着下载与机器cpu架构对应的frp

https://github.com/fatedier/frp/releases    v0.37.1

下载,解压: frp_0.37.1_linux_arm64.tar.gz

服务端配置及启动

解压之后进目录修改服务端配置文件 frps.ini

 复制代码 隐藏代码
# 必要配置,初始化服务端连接端口
[common]
bind_port = 6000
bind_udp_port = 6001

# 认证模式和秘钥
authentication_method = token
authenticate_heartbeats = true
authenticate_new_work_conns = false
token = CPu2PS5teIdM

#是否启用tcp复用,可以省略
tcp_mux = true

# 允许开启的端口,可以限制在某个范围利于云平台开端口或其他管理
allow_ports = 20000-40000

# 日志,可以省略,省略之后直接打印在终端中。
log_file = ./frps.log
log_level = info
log_max_days = 3
disable_log_color = true

配置完成之后启动

 复制代码 隐藏代码
./frps -c frps.ini
#frps服务端程序
# -c 加载配置文件

客户端连接和启动

frp releases包是包含服务端和客户端的,接着我手上是两台windows机器,所以按照x64 下载frp_0.37.1_windows_amd64.zip

解压之后,我们开始编辑客户端配置

编辑frpc.ini 文件

 复制代码 隐藏代码
# 连接服务器,核心部分。每个客户端都需要配置
[common]
server_addr = www.wspby.top
server_port = 6000
token = CPu2PS5teIdM   #这里一定要和服务端一致,否则报错。

# 日志,可以省略,省略之后直接打印在终端中。
log_file = ./frpc.log
log_level = info
log_max_days = 3

#是否启用tcp复用,可以省略
tcp_mux = true

启动命令

 复制代码 隐藏代码
frpc.exe -c frpc.ini

开始创建连接,这里科普下可以使用的连接类型type(来自https://www.zhuguodong.com/?id=560

代{过}{滤}理类型

tcp和udp:就是将普通的tcp端口或者udp端口映射到公网上,相当于你的设备直接向公网暴露了一个tcp端口,任何设备都可以尝试连接这个端口。这里就会有很大的安全风险。

 复制代码 隐藏代码
[pc_mstsc]
type = tcp
local_ip = 127.0.0.1 #这里疑似修改为其他地址并进行访问,这里不做测试
local_port = 3389
remote_port = 33999

frp 实现内网穿透-图片5

之后在防火墙开下端口就可以提供给任何人访问了。

sftp:出于安全和防止攻击的考虑,frp提供了使用密钥验证的tcp,这就是frp的Secret TCP(stcp)模式。

xtcp:stcp是使用了服务器进行中转,如果出现大流量的话会出现卡顿,所以就有了xtcp模式。在xtcp模式下,两个客户端是直接相连略过了服务端进行通信,这样就不会受服务器带宽限制。

被连接端配置如下:

 复制代码 隐藏代码
[pc_stcp_mstsc]      # stcp
type = stcp
sk = 12345678
local_ip = 127.0.0.1
local_port = 3389

#基本一致
[pc_xtcp_mstsc]    # xtcp
type = xtcp
sk = 12345678
local_ip = 127.0.0.1
local_port = 3389

连接端配置如下:

 复制代码 隐藏代码
[mstsc_vister_stcp]
type = stcp
role = visitor      #角色是访问者
sk = 12345678
bind_addr = 127.0.0.1   #可以随便写
bind_port = 33333
server_name = pc_stcp_mstsc  #这里需要对应中括号内的服务名!

[mstsc_vister_xtcp]
type = xtcp
role = visitor      #角色是访问者
sk = 12345678       #需要与被连接端一致
bind_addr = 127.0.0.1    #可以随便写
bind_port = 44444
server_name = pc_xtcp_mstsc #这里需要对应中括号内的服务名!

bind_addr可以随便写,在连接时地址为: %bind_addr%:%bind_port%

在正确配置和启动之后开始测试

RemoteDesktop:  127.0.0.1:33333   弹出用户登录窗口, 测试成功。

补充,最好带上开机启动,就是文件里的systemd,进去改个路径放到/etc/systemd/system/里面,刷新一下,enable加start,以后服务器重启了自动启动了,还有,服务器centos开着防火墙一定要允许端口通过,还有还有,阿里云和腾讯云的也需要在网页里防火墙允许一下端口,包括服务端和客户端的端口,这都是泪。。。

_______________________________________________________________________________________

实例:

服务器端的frps配置

frps.ini

案列:

[common]

bind_port = 7000

bind_udp_port = 7001

vhost_http_port = 88

token = 123456

dashboard_user = admin

dashboard_pwd = 123456

dashboard_port = 7500

说明:

[common]

bind_addr = 0.0.0.0

bind_port = 7000            # 客户端与服务端进行通信的端口,即frp服务端口,需与客户端server_port一致

privilege_token = 123456    # 特权模式密钥,需与客户端frpc.ini一致

vhost_http_port = 8080      # http服务端口,开启后服务端完成通过域名访问部署于内网的 Web 服务部署,这里将 HTTP 访问端口设为 8080

vhost_https_port = 443      # https服务端口

dashboard_port = 7500       # 控制台端口 通过 Dashboard 可以方便的查看 FRP 的状态以及代理统计信息展示 通过 http://[server_addr]:7500 访问 Dashboard 界面,用户名密码默认都为 admin。

bind_udp_port = 7001

服务器端用命令frps -c frps.ini来启动frp。
启动后输入http://[服务器ip]:7500,并输入所设置的账号(admin)和密码(admin)就可以看到以下管理界面:

frp 实现内网穿透-图片6

客户端的配置模式:stcp

 

  • 客户端1:配置需要将type改为stcp即可

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p123]

type = stcp

sk = 123456789

local_ip =  0.0.0.0

bind_port = 3390

说明

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p123]

type = stcp                 # 选择模式stcp

sk = 123456789              # 只有 sk 一致的用户才能访问到此服务

local_ip =  0.0.0.0         # 本地IP

bind_port = 3390            # 映射需要端口

然后在要访问这个服务的机器上启动另外一个 FRP 客户端,配置如下:

客户端2:配置

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p_ssh_visitor]

type = stcp

role = visitor

server_name = p2p123

sk = 123456789

bind_addr = 0.0.0.0

bind_port = 6006

说明:

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p_ssh_visitor]

type = stcp

role = visitor            # STCP 的访问者

server_name = p2p123      # 要访问的 STCP 代理的名字,客户端1名称一样

sk = 123456789            # 只有 sk 一致的用户才能访问到此服务,与客户端1,SK一致

bind_addr = 0.0.0.0       # 本地 IP

bind_port = 6006          # 访问本地端口

客户端用命令frpc -c frpc.ini来启动frp。

客户端的配置模式:xtcp

  • 客户端1:配置需要将type改为xtcp即可

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p123]

type = xtcp

sk = 123456789

local_ip = 0.0.0.0

bind_port = 3390

说明

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p123]

type = xtcp                 # 选择模式xtcp

sk = 123456789              # 只有 sk 一致的用户才能访问到此服务

local_ip =  0.0.0.0         # 本地IP

bind_port = 3390            # 映射需要端口

然后在要访问这个服务的机器上启动另外一个 FRP 客户端,配置如下:

客户端2:配置

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p_ssh_visitor]

type = xtcp

role = visitor

server_name = p2p123

sk = 123456789

bind_addr = 0.0.0.0

bind_port = 6006

说明:

[common]

server_addr = 服务器公网IP或者域名

server_port = 7000

token = 123456

[p2p_ssh_visitor]

type = xtcp

role = visitor            # XTCP 的访问者

server_name = p2p123      # 要访问的 XTCP 代理的名字,客户端1名称一样

sk = 123456789            # 只有 sk 一致的用户才能访问到此服务,与客户端1,SK一致

bind_addr = 0.0.0.0       # 本地 IP

bind_port = 6006          # 访问本地端口

客户端用命令frpc -c frpc.ini来启动frp。

客户端的配置模式:tcp

客户端的配置模式:udp

参考这个:https://www.zhuguodong.com/?id=558

参考资料

https://blog.csdn.net/deng_xj/article/details/89187944

http://nicktcl.cn/2020/03/29/908/

https://blog.csdn.net/htxhtx123/article/details/104219317

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

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

目前处于开发的初级阶段,并不能穿透所有类型的 NAT 设备,所以穿透成功率较低。穿透失败时可以尝试 stcp 的方式。

frps.ini服务端配置

[common]
bind_addr = 0.0.0.0
bind_port = 7000
bind_udp_port = 7001
privilege_token = frp888
启动 frpc,转发内网的 ssh 服务,配置如下,不需要指定远程端口:

frpc.ini客户端配置

[common]
server_addr = 服务端IP
server_port = 7000
privilege_token = frp888

[p2p_ssh]
type = xtcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

在要访问这个服务的机器上启动另外一个 frpc,配置如下:

要访问对方
frpc.ini客户端配置

[common]
server_addr = 服务端IP
server_port = 7000
privilege_token = frp888

[p2p_ssh_visitor]
type = xtcp
role = visitor
server_name = p2p_ssh #同上面[p2p_ssh]一致
sk = abcdefg #同上面一致
bind_addr = 127.0.0.1
bind_port = 2222

说明:
bind_addr = 127.0.0.1绑定监听本地IP
bind_port = 2222绑定监听本地端口,可自定义。
本地SSH工具通过 127.0.0.1:2222,既可访问到已穿透的SSH服务。
server_name = 要访问的穿透服务名称。
sk = 只有 sk 一致的用户才能访问到此服务,可自定义。
role = stcp 的访问者,可自定义。
bind_udp_port = 7001frps服务端除正常配置外需要额外配置一个 udp 端口用于支持该类型的客户端,可自定义。

注意:这是最精简使用的方法实例,如你有更多要求,请参考详细参数阅读,而进行编写

文章末尾固定信息

weinxin
我的微信
微信号已复制
我的微信
微信扫一扫
 
Jensen
  • 本文由 Jensen 发表于2021-10-22 15:06:32
  • 转载请务必保留本文链接:http://ivell.cn/frp-nat/