FRP内网穿透教程

技术教程 风为裳 7浏览 0评论 繁體

概述

内网穿透,即NAT穿透,网络连接时术语,计算机是局域网内时,外网与内网的计算机节点需要连接通信,有时就会出现不支持内网穿透。FRP 全名:Fast Reverse Proxy。FRP 是一个使用 Go 语言开发的高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务。FRP 支持 TCP、UDP、HTTP、HTTPS等协议类型,并且支持 Web 服务根据域名进行路由转发。

FRP作用与架构

  • 利用处于内网或防火墙后的机器,对外网环境提供HTTP或HTTPS服务。
  • 对于HTTP, HTTPS服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个 80 端口。
  • 利用处于内网或防火墙后的机器,对外网环境提供TCP和UDP服务,例如在家里通过SSH访问处于公司内网环境内的主机。

安装

FRP采用Go语言开发,支持 Windows、Linux、MacOS、ARM等多平台部署。FRP安装非常容易,只需下载对应系统平台的软件包,并解压即可使用。下列使用方法以Linux为例。

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

wget https://github.com/fatedier/frp/releases/download/v0.15.1/frp_0.15.1_linux_amd64.tar.gz
tar xzvf frp_0.15.1_linux_amd64.tar.gz
mv frp_0.15.1_linux_amd64 frp

配置

配置FRP服务端的前提条件是需要一台具有公网 IP 的设备,得益于FRP是 Go 语言开发的,具有良好的跨平台特性。你可以在 Windows、Linux、Macos、ARM等设备上部署。
FRP 默认给出两个服务端配置文件,一个是简版的frps.ini,另一个是完整版本frps_full.ini。
我们先来看看简版的frps.ini,通过这个配置可以快速的搭建起一个FRP服务端。

$ vim frpc.ini

[common]
# server_addr 为 FRP 服务端的公网 IP 
server_addr = 4.3.2.1
# server_port 为 FRP 服务端监听的端口 
server_port = 7000

启动

$ ./frpc -c ./frpc.ini
2018/01/25 11:15:49 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 11:15:49 [I] [proxy_manager.go:294] proxy added: []
2018/01/25 11:15:49 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 11:15:49 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 11:15:49 [I] [control.go:240] [83775d7388b8e7d9] login to server success, get run id [83775d7388b8e7d9], server udp port [0]

这样就可以成功在FRP服务端上成功建立一个客户端连接,现在还并不能对外提供任何内网机器上的服务,因为我们并还没有在FRP服务端注册任何内网服务的端口。

FRP实例

通过下面几个常用的例子来了解下FRP是如何实现内网服务穿透的。

通过TCP访问内网机器

以访问SSH服务为例,修改FRP客户端配置文件frpc.ini文件并增加如下内容:

$ cat frpc.ini

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

启动FRP客户端

$ ./frpc -c ./frpc.ini
2018/01/25 12:21:23 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 12:21:23 [I] [proxy_manager.go:294] proxy added: [ssh]
2018/01/25 12:21:23 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 12:21:23 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 12:21:23 [I] [control.go:240] [3b468a55191341cb] login to server success, get run id [3b468a55191341cb], server udp port [0]
2018/01/25 12:21:23 [I] [control.go:165] [3b468a55191341cb] [ssh] start proxy success

这样就在FRP服务端上成功注册了一个端口为6000的服务,接下来就可以通过这个端口访问内网机器上SSH服务,假设用户名为test。

ssh -oPort=6000 [email protected]

通过自定义域名访问部署于内网的Web服务

有时要在公有网络通过域名访问我们在本地环境搭建的Web服务,但是由于本地环境机器并没有公网IP,无法将域名直接解析到本地的机器。

这里以HTTP服务为例:首先修改FRP服务端配置文件,通过vhost_http_port参数来设置HTTP访问端口,这里将 HTTP 访问端口设为8080。

$ vim frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080

启动FRP服务端

$ ./frps -c ./frps.ini
2018/01/25 13:33:26 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
2018/01/25 13:33:26 [I] [service.go:125] http service listen on 0.0.0.0:8080
2018/01/25 13:33:26 [I] [main.go:112] Start frps success
2018/01/25 13:33:26 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

修改FRP客户端配置文件并增加如下内容:

$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = test.yourdomain.com

通过local_portcustom_domains参数来设置本地机器上Web服务对应的端口和自定义的域名,这里我们分别设置端口为80,对应域名为 test.yourdomain.com。

启动FRP客户端

$ ./frpc -c ./frpc.ini
2018/01/25 13:56:11 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 13:56:11 [I] [proxy_manager.go:294] proxy added: [web ssh]
2018/01/25 13:56:11 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 13:56:11 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 13:56:11 [I] [control.go:240] [296fe9e31a551e07] login to server success, get run id [296fe9e31a551e07], server udp port [0]
2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [web] start proxy success
2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [ssh] start proxy success

最后将test.yourdomain.com的域名A记录解析到FRP服务器的公网IP上,现在便可以通过http://test.yourdomain.com:8080这个URL访问到处于内网机器上对应的Web服务。HTTPS服务配置方法类似,只需将vhost_http_port替换为vhost_https_port, type设置为https即可。

通过密码保护你的Web服务

FRP 支持通过HTTP Basic Auth来保护你的Web服务,使用户需要通过用户名和密码才能访问到你的服务。需要实现此功能主要需要在FRP客户端的配置文件中添加用户名和密码的设置。该功能目前仅限于HTTP类型的代理。

$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = test.yourdomain.com
# 设置认证的用户名
http_user = abc
# 设置认证的密码
http_pwd = abc

给Web服务增加自定义二级域名

通过在FRP服务端的配置文件中配置subdomain_host参数就可以启用该特性。之后在 FRP 客户端的HTTP、HTTPS类型的代理中可以不配置 custom_domains,而是配置一个subdomain参数。

然后只需要将*.{subdomain_host}解析到FRP服务端所在服务器。之后用户可以通过subdomain自行指定自己的Web服务所需要使用的二级域名,并通过{subdomain}.{subdomain_host}来访问自己的 Web 服务。

  • 同一个 HTTP 或 HTTPS 类型的代理中 custom_domains 和 subdomain 可以同时配置。
  • 如果FPR服务端配置了subdomain_host,则custom_domains中不能是属于subdomain_host的子域名或者泛域名。

首先我们在FRP服务端配置subdomain_host参数:

$ vim frps.ini
[common]
subdomain_host = yourdomain.com

在FRP客户端配置文件配置subdomain参数:

$ vim frpc.ini
[web]
type = http
local_port = 80
subdomain = test

将泛域名*.yourdomain.com解析到 FRP 服务端所在服务器的公网IP地址。FRP服务端和FRP客户端都启动成功后,通过 test.yourdomain.com就可以访问到内网的Web服务。

修改Host Header

通常FRP不会修改转发的任何数据。但有一些后端服务会根据HTTP请求header中的host字段来展现不同的网站,例如Nginx的虚拟主机服务,启用host-header的修改功能可以动态修改HTTP请求中的host字段。

实现此功能只需要在FRP客户端配置文件中定义host_header_rewrite参数。该功能仅限于HTTP类型的代理。

$ vim frpc.ini
[web]
type = http
local_port = 80
custom_domains = test.yourdomain.com
host_header_rewrite = test2.yourdomain.com

原HTTP请求中的host字段test.yourdomain.com转发到后端服务时会被替换为test2.yourdomain.com。

URL路由

FRP支持根据请求的URL路径路由转发到不同的后端服务。要实现这个功能可通过FRP客户端配置文件中的locations字段来指定。目前仅支持最大前缀匹配。

$ vim frpc.ini

[web01]
type = http
local_port = 80
custom_domains = test.yourdomain.com
locations = /

[web02]
type = http
local_port = 81
custom_domains = test.yourdomain.com
locations = /directory,/directory2

上述示例配置说明,test.yourdomain.com这个域名下所有以/directory以及 /directory2作为前缀的URL请求都会被转发到后端web02所在的后端服务,其余的请求会被转发到web01所在的后端服务。

通过UDP访问内网机器

DNS查询请求使用UDP 协议,FRP支持对内网UDP服务的穿透,配置方式和TCP基本一致。这里以转发到谷歌的DNS查询服务器8.8.8.8 的UDP端口为例。
首先修改FRP客户端配置文件,并增加如下内容:

$ vim frpc.ini
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6001

要转发到内网DNS服务器只需把local_ip改成对应IP即可。

启动FRP客户端

$ ./frpc -c ./frpc.ini
2018/01/25 14:54:17 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 14:54:17 [I] [proxy_manager.go:294] proxy added: [ssh web dns]
2018/01/25 14:54:17 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 14:54:17 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 14:54:17 [I] [control.go:240] [33e1de8a771112a6] login to server success, get run id [33e1de8a771112a6], server udp port [0]
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [ssh] start proxy success
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [web] start proxy success
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [dns] start proxy success

通过dig命令测试UDP包转发是否成功,预期会返回www.google.com域名的解析结果:

$ dig @4.3.2.1 -p 6001 www.google.com
...

;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		79	IN	A	69.63.184.30

...

转发Unix域套接字

通过TCP端口访问内网的Unix域套接字,下列配置举例和本地机器上的Docker Daemon通信为例。

首先修改FRP客户端配置文件,并增加如下内容:

$ vim frpc.ini
[unix_domain_socket]
type = tcp
remote_port = 6002
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock

这里主要是使用plugin和plugin_unix_path两个参数启用了unix_domain_socket插件和配置对应的套接字路径。

重启FRP客户端

$ ./frpc -c ./frpc.ini

2018/01/25 15:09:33 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 15:09:33 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
2018/01/25 15:09:33 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 15:09:33 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 15:09:33 [I] [control.go:240] [f6424f0deb8b6ff7] login to server success, get run id [f6424f0deb8b6ff7], server udp port [0]
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [ssh] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [web] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [dns] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [unix_domain_socket] start proxy success

通过curl命令查看Docker版本信息进行测试:

$ curl http://4.3.2.1:6002/version

{"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"17.12.0-ce","Details":{"ApiVersion":"1.35","Arch":"amd64","BuildTime":"2017-12-27T20:12:29.000000000+00:00","Experimental":"true","GitCommit":"c97c6d6","GoVersion":"go1.9.2","KernelVersion":"4.9.60-linuxkit-aufs","MinAPIVersion":"1.12","Os":"linux"}}],"Version":"17.12.0-ce","ApiVersion":"1.35","MinAPIVersion":"1.12","GitCommit":"c97c6d6","GoVersion":"go1.9.2","Os":"linux","Arch":"amd64","KernelVersion":"4.9.60-linuxkit-aufs","Experimental":true,"BuildTime":"2017-12-27T20:12:29.000000000+00:00"}

需要注意的是FRP从1.5版本开始支持客户端热加载配置文件,并不用每次都重启客户端程序。

FRP进阶使用教程

FRP服务端增加一个Dashboard方法

通过Dashboard可以方便的查看FRP的状态以及代理统计信息展示,要使用这个功能首先需要在FRP服务端配置文件中指定Dashboard服务使用的端口:

$ vim frps.ini

[common]

# 指定 Dashboard 的监听的 IP 地址
dashboard_addr = 0.0.0.0

# 指定 Dashboard 的监听的端口
dashboard_port = 7500

# 指定访问 Dashboard 的用户名
dashboard_user = admin

# 指定访问 Dashboard 的端口
dashboard_pwd = admin

重新启动FRP服务端

$ ./frps -c ./frps.ini

2018/01/25 16:39:29 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
2018/01/25 16:39:29 [I] [service.go:125] http service listen on 0.0.0.0:8080
2018/01/25 16:39:29 [I] [service.go:164] Dashboard listen on 0.0.0.0:7500
2018/01/25 16:39:29 [I] [main.go:112] Start frps success
2018/01/25 16:39:29 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

通过http://[server_addr]:7500访问Dashboard界面,用户名密码默认都为admin。

FRP服务端加身份验证方法

默认情况只要知道FRP服务端开放的端口,任意FRP客户端都可以随意在服务端上注册端口映射,这样对于在公网上的FR 服务来说不太安全。FRP提供了身份验证机制用于提高FRP服务端的安全性。要启用这一特性,只需在FRP服务端和FRP客户端的common配置中启用privilege_token参数。

[common]
privilege_token = 12345678

启用后,只有FRP服务端和FRP客户端的common配置中的privilege_token参数一致身份验证才通过,FRP客户端才能成功在FRP服务端注册端口映射。否则就会失败,出现类似下面的错误:

2018/01/25 17:29:27 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 17:29:27 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
2018/01/25 17:29:27 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 17:29:27 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 17:29:27 [E] [control.go:230] authorization failed
2018/01/25 17:29:27 [W] [control.go:109] login to server failed: authorization failed
authorization failed

要注意的是FRP客户端所在机器和FRP服务端所在机器的时间相差不能超过15分钟,因为时间戳会被用于加密验证中。这个超时时间可以在配置文件中通过authentication_timeout这个参数来修改,单位为秒,默认值为900秒,即15分钟。如果修改为0,则FRP服务端将不对身份验证报文的时间戳进行超时校验。

FRP客户端热加载配置文件

当修改完FRP客户端中的配置文件后,从0.15版本开始可以通过frpc reload命令来动态加载配置文件,通常情况下会在10 秒内完成代理的更新。

启用此功能需要在FRP客户端配置文件中启用admin端口,用于提供API服务。配置示例:

$ vim frpc.ini

[common]
admin_addr = 127.0.0.1
admin_port = 7400

重启FRP客户端即可生效。需要注意的是[common]中的参数除了start外目前无法被修改。

$ ./frpc -c ./frpc.ini
2018/01/25 18:04:25 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 18:04:25 [I] [control.go:240] [3653b9a878f8acc7] login to server success, get run id [3653b9a878f8acc7], server udp port [0]
2018/01/25 18:04:25 [I] [service.go:49] admin server listen on 127.0.0.1:7400
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [ssh] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [web] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [dns] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [unix_domain_socket] start proxy success

$ ./frpc reload -c ./frpc.ini
reload success

启用admin_addr后,可以通过frpc status -c ./frpc.ini命令在FRP客户端查看当前代理状态信息。

$ ./frpc status -c ./frpc.ini

Proxy Status...
TCP
Name                Status   LocalAddr     Plugin              RemoteAddr           Error
ssh                 running  127.0.0.1:22                      4.3.2.1:6000
unix_domain_socket  running                unix_domain_socket  4.3.2.1:6002

UDP
Name  Status   LocalAddr   Plugin  RemoteAddr           Error
dns   running  8.8.8.8:53          4.3.2.1:6001

HTTP
Name  Status   LocalAddr     Plugin  RemoteAddr              Error
web   running  127.0.0.1:80          mike.hi-linux.com:8080

给FRP服务端的端口添加白名单

FRP提供了指定允许哪些端口被分配的功能。可通过FRP服务端的配置文件中privilege_allow_ports参数来指定,配置修改如下:

$ vim frps.ini

[common]
privilege_allow_ports = 2000-3000,3001,3003,4000-5000

需要注意的是privilege_allow_ports可以配置允许使用的某个指定端口或者是一个范围内的所有端口,以英文逗号,分隔,指定的范围以 – 分隔。

当出现使用不允许的端口注册时,就会注册失败。提示类似以下错误:

$ ./frpc status -c ./frpc.ini
Proxy Status...
TCP
Name                Status       LocalAddr     Plugin              RemoteAddr            Error
ssh                 start error  127.0.0.1:22                      4.3.2.1:60000  port not allowed
unix_domain_socket  start error                unix_domain_socket  4.3.2.1:60002  port not allowed

启用FRP的TCP多路复用方法

FRP从v0.10版本开始,客户端和服务器端之间的连接支持多路复用,不再需要为每一个用户请求创建一个连接,可以使连接建立的延迟降低,并且避免了被大量文件描述符的占用,使FRP可以承载更高的并发数。

此功能默认启用,如需关闭可以在FRP服务端配置文件和FRP客户端配置文件中配置,需要注意的是配置项在服务端和客户端必须一致。

# frps.ini 和 frpc.ini 
[common]
tcp_mux = false

FRP启动KCP协议底层通信的方法

FRP从v0.12版本开始,底层通信协议支持选择KCP协议,在恶劣的网络环境下传输效率会提升明显,但是会增加流量消耗。

开启KCP协议支持,首先要在FRP服务端配置文件中启用。配置如下:

$ vim frps.ini
[common]
bind_port = 7000
# 指定一个 UDP 端口用于接收客户端请求 KCP 绑定的是 UDP 端口,可以和 bind_port 一样
kcp_bind_port = 7000

FRP客户端配置文件指定需要使用的协议类型,目前只支持TCP和KCP。其它代理配置不需要修改:

$ vim  frpc.ini
[common]
server_addr = 4.3.2.1
# server_port 指定为 FRP 服务端里 kcp_bind_port 指定的端口
server_port = 7000
# 指定需要使用的协议类型,默认类型为 TCP
protocol = kcp

注意:需要开放相关机器上的UDP端口的访问权限。

FRP服务端配置连接池方法

默认当用户请求建立连接后,FRP服务端才会请求FRP客户端主动与后端服务建立一个连接。

指定的FRP服务端启用连接池功能后,FRP会预先和后端服务建立起指定数量的连接,每次接收到用户请求后,会从连接池中取出一个连接和用户连接关联起来,避免了等待与后端服务建立连接以及FRP客户端和FRP服务端之间传递控制信息的时间。

首先要在FRP服务端配置文件中设置每个代理可以创建的连接池上限,避免大量资源占用,客户端设置超过此配置后会被调整到当前值。配置如下:

$ vim frps.ini
[common]
max_pool_count = 5

在FRP客户端配置文件中为客户端启用连接池时,需要指定预创建连接的数量。

$ vim frpc.ini
[common]
pool_count = 1

开启此功能比较适合有大量短连接请求时开启。

通信流量的加密与压缩

如果遇到公司内网防火墙对外网访问进行了流量识别与屏蔽的情况,例如禁止了SSH协议等,可通过设置use_encryption= true,将FRP客户端与FRP服务端之间的通信内容加密传输,将会有效防止通信流量被拦截。

在传输的报文长度较长的情况下,设置use_compression = true对传输内容进行压缩,可以有效减小FRP客户端与FRP服务端之间的网络流量,来加快流量转发速度,但是会增加CPU资源。

这两个功能默认是关闭的,如果需要开启,在FRP客户端配置文件中通过配置来为指定的代理启用加密与压缩的功能,压缩算法使用的是snappy。

$ vim frpc.ini

[ssh]
type = tcp
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true

FRP客户端代理其它内网机器访问外网的使用方法

要知道FRP客户端内置了http_proxy和socks5插件,通过这两个插件可以使其它内网机器通过FPR客户端的的网络访问互联网。
如果需要启用此功能,只需要在FRP客户端配置文件中启用相关插件,这里以http_proxy插件为例。

$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000

[http_proxy]
type = tcp
remote_port = 6000
plugin = http_proxy

然后只需要通过这个代理访问外网的内部机器的代理地址设置为4.3.2.1:6000,这样就可以通过FRP客户端机器的网络访问互联网。

FRP的http_proxy插件也支持认证机制,如果需要启用认证可通过配置参数将plugin_http_user和plugin_http_passwd这两个参数启用。
如果需要启动Socks5代理,只需将plugin的值更换为socks5。

通过代理连接FRP服务端的方法

如遇到只能通过代理访问外网的环境内,FRP客户端支持通过HTTP_PROXY参数来配置代理和FRP服务端进行通信。要使此功能可以通过设置系统环境变量HTTP_PROXY或者通过在FRP客户端的配置文件中设置http_proxy参数来使用此功能。需要注意的是仅在protocol = tcp时生效,暂时不支持kcp协议。

$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000
protocol = tcp
http_proxy = http://user:[email protected]:8080

FRP点对点内网穿透教程

在传输大量数据的情况下如果都经过服务器中转的话,这样会对服务器端带宽压力比较大。FRP提供了一种新的代理类型XTCP来解决这个问题,XTCP模式下可以在传输大量数据时让流量不经过服务器中转。使用方式同STCP类似,需要在传输数据的客户端和服务端都部署上FRP客户端上用于建立直接的连接。

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

$ vim frps.ini
bind_udp_port = 7001

然后配置FRP客户端,与常规TCP转发不同的是这里不需要指定远程端口。

$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000

[p2p_ssh]
type = xtcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

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

$ vim frpc.ini
[common]
server_addr = 4.3.2.1
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 = 6006

最后需要在在本机启动一个FRP客户端,就可以通过本机6006端口对内网机器SSH服务进行访问,假设用户名为test:

$ ./frpc -c ./frpc.ini

2018/01/26 16:01:52 [I] [proxy_manager.go:326] visitor added: [p2p_ssh_visitor secret_ssh_visitor]
2018/01/26 16:01:52 [I] [control.go:240] [7c7e06878e11cc3c] login to server success, get run id [7c7e06878e11cc3c], server udp port [7001]
2018/01/26 16:01:52 [I] [proxy_manager.go:235] [7c7e06878e11cc3c] try to start visitor [p2p_ssh_visitor]
2018/01/26 16:01:52 [I] [proxy_manager.go:243] [p2p_ssh_visitor] start visitor success
2018/01/26 16:01:52 [I] [proxy_manager.go:235] [7c7e06878e11cc3c] try to start visitor [secret_ssh_visitor]
2018/01/26 16:01:52 [I] [proxy_manager.go:243] [secret_ssh_visitor] start visitor success

$ ssh -oPort=6006 [email protected]

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

使用STCP服务

FRP也提供了一种安全的转发方式STCP。使用STCP (secret tcp) 类型的代理可以避免让任何人都能访问到穿透到公网的内网服务,如果要使用STCP模式,访问者需要单独运行另外一个FRP客户端。下面以创建一个只有自己能访问到的SSH服务代理为例,FRP服务端和其它的部署步骤相同,主要区别是在FRP客户端上。

配置FRP客户端,和常规TCP转发不同的是这里不需要指定远程端口。

$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000

[secret_ssh]
type = stcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

然后在要访问这个服务的机器上启动另外一个FRP客户端。

$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000

[secret_ssh_visitor]
type = stcp
# STCP 的访问者
role = visitor
# 要访问的 STCP 代理的名字,和前面定义的相同。
server_name = secret_ssh
# 和前面定义的要一致
sk = abcdefg
# 绑定本地端口用于访问 ssh 服务
bind_addr = 127.0.0.1
bind_port = 6005

最后只需在本机启动一个FRP客户端,就可以通过本机6005端口对内网机器SSH服务进行访问,用户名为test:

$ ./frpc -c ./frpc.ini
2018/01/26 15:03:24 [I] [proxy_manager.go:284] proxy removed: []
2018/01/26 15:03:24 [I] [proxy_manager.go:294] proxy added: []
2018/01/26 15:03:24 [I] [proxy_manager.go:317] visitor removed: []
2018/01/26 15:03:24 [I] [proxy_manager.go:326] visitor added: [secret_ssh_visitor]
2018/01/26 15:03:24 [I] [control.go:240] [60d2af2f68196537] login to server success, get run id [60d2af2f68196537], server udp port [0]
2018/01/26 15:03:24 [I] [proxy_manager.go:235] [60d2af2f68196537] try to start visitor [secret_ssh_visitor]
2018/01/26 15:03:24 [I] [proxy_manager.go:243] [secret_ssh_visitor] start visitor success

$ ssh -oPort=6005 [email protected]

FRP使用一键脚本进行管理

官方并没有提供一键脚本,以下脚本由网友提供。

项目地址:https://github.com/clangcn/onekey-install-shell/

使用方法

安装

wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-install-shell/master/frps/install-frps.sh -O ./install-frps.sh
chmod 700 ./install-frps.sh
./install-frps.sh install

管理命令

./install-frps.sh config     //配置FRP服务端

./install-frps.sh update     //更新FRP服务端

./install-frps.sh uninstall  //卸载

# 其他管理命令

Usage: /etc/init.d/frps {start|stop|restart|status|config|version}
                         启动  停止  重启    状态   配置   版本

相关资料

http://koolshare.cn/thread-65379-1-1.html
http://gofrp.org/
https://github.com/fatedier/frp/blob/master/README_zh.md

转载请注明:风为裳 » FRP内网穿透教程

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址