一、简介
frp
全名Fast Reverse Proxy
, 是一个可用于内网穿透的高性能的反向代理应用,主要用于解决一些内网服务没有固定公网ip,但是却需要提供外网访问。使用frp可以将内网中的TCP、UDP、HTTP、HTTPS等协议类型的服务发布到公网,并且支持Web服务根据域名进行路由转发。
frp的最新版本为v0.52.3。
其在linux,windows,基于arm和risc芯片环境均可支持,兼容性非常强大

image.png
二、前置准备
外网服务器一台(必须要有公网ip的机器);
内网服务器一台;
下载frp脚本部署文件;
如果是linux环境配置,需要熟悉基本linux操作命令。
- 注意事项:
1)服务器端和内网机器端下载的版本要相同,否则可能会影响内网穿透
2)根据服务器系统选择合适的脚本
- 脚本主要分为服务端与客户端文件
1.服务器端用到的是Frps和Frps.ini
2.客户端用到的是Frpc和Frpc.ini
三、配置实例
内网穿透访问web项目
1.外网服务端配置
1.1配置Frps.ini文件
[common]
bind_addr = 0.0.0.0
bind_port = 7000
vhost_http_port = 8000
1.2启动命令
注:需要切换到文件目录
./frps -c frps.ini
后台启动:nohup ./frps -c ./frps.ini &
1.3启动日志
2020/03/23 17:27:41 [I] [service.go:136] frps tcp listen on 0.0.0.0:7000
2020/03/23 17:27:41 [I] [service.go:178] http service listen on 0.0.0.0:8000
2020/03/23 17:27:41 [I] [root.go:204] Start frps success
则说明服务器端已经启动Frp服务,监听的端口是7000。
2.内网客户端配置
2.1内网机器配置Frpc.ini
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 7000[web]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = xxx.xxxx.xxxx
启动命令
./frpc -c frpc.ini
后台启动:nohup ./frps -c ./frps.ini &
启动日志
2020/03/23 17:28:21 **[I] [service.go:221] login to server success, get run id [3435ffb8820dbcf1], server udp port [0]**2020/03/23 17:28:21 **[I] [proxy_manager.go:137] [3435ffb8820dbcf1] proxy added: [web]**2020/03/23 17:28:21 **[I] [control.go:144] [web] start proxy success**
3.访问内网http服务
custom\_domains:vhost\_http\_port
示例:http://xxx.xxx.xxx.xxx:8000
内网穿透实现ssh连接
注:一些不必要的配置已经去掉
1.外网服务端配置
1.1配置Frps.ini文件
[common]
bind_addr = 0.0.0.0
bind_port = 7000
1.2启动命令
注:需要切换到文件目录下
./frps -c frps.ini
后台启动:nohup ./frps -c ./frps.ini &
1.3启动日志
2020/03/23 16:21:57 [I] [service.go:136] frps tcp listen on 0.0.0.0:7000
2020/03/23 16:21:57 [I] [root.go:204] Start frps success
则说明服务器端已经启动Frp服务,监听的端口是7000。
2.内网客户端配置
2.1内网机器配置Frpc.ini
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 7000[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
启动命令
./frpc -c frpc.ini
后台启动:nohup ./frps -c ./frps.ini &
启动日志
2020/03/23 16:40:00 **[I] [service.go:221] login to server success, get run id [719904eea7bddc16], server udp port [0]**2020/03/23 16:40:00 **[I] [proxy_manager.go:137] [719904eea7bddc16] proxy added: [ssh]**2020/03/23 16:40:00 **[I] [control.go:144] [ssh] start proxy success**
这样我以后就可以通过服务器公网IP和6000端口来连接我的内网机器了(ssh)。连接的方式:
ssh -p 6000 xxx.xxx.xxx.xxx
上面用到的端口都需要服务器端已经开放这些端口,mac需要开启远程登录权限。
四、frp界面监控程序
1.服务端监控界面
1.1服务端添加监控界面配置
[common]
bind_addr = 0.0.0.0
bind_port = 7000
vhost_http_port = 8000
dashboard_addr = 0.0.0.0
dashboard_port = 7501
dashboard_user = admin
dashboard_pwd = admin

image.png

image.png
2.客户端添加监控界面配置
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 7000
admin_addr = 127.0.0.1
admin_port = 7401
admin_user = admin
admin_pwd = admin[web]
type = http
local_ip = 127.0.0.1
local_port = 8821
custom_domains = xxx.xxx.xxx.xxx

image.png
五、附录
1.相关启动命令
linux环境下启动服务,需要先把运行文件添加可执行权限。例如我的文件实在root文件夹中,我需要搭建frp服务端,那么待设置好服务端配置文件(frps.ini)后执行以下命令即可。
cd /root
chmod +x frps
nohup ./frps -c ./frps.ini &
执行成功后,会显示frp的进程号码。你也可以通过命令来查看frps运行的进程编号。
ps -e | grep frps在windows环境下则是以管理员身份运行cmd命令提示符。进入相应的目录后,运行命令即可。
frps -c frps.ini &
2.frps.ini(服务端)详细配置文件解释说明
[common]
bind_addr = 0.0.0.0
bind_port = 7000
bind_udp_port = 7001
kcp_bind_port = 7000
# 注意:http端口和https端口可以与bind_port相同
vhost_http_port = 80
vhost_https_port = 443# 为虚拟主机http服务器响应头超时(秒),默认是60秒
dashboard_addr = 0.0.0.0
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin
log_file = ./frps.log
log_level = info
log_max_days = 3
token = 12345678
allow_ports = 2000-3000,3001,3003,4000-50000
max_pool_count = 5
max_ports_per_client = 0#如果subdomain_host不为空,则可以设置子域时类型是HTTP或HTTPS在FRPC的配置文件
#子域名测试时,路由使用的主机是test.frps.com
subdomain_host = frps.com
tcp_mux = true
3.frpc.ini(客户端)详细配置文件解释说明
[common]
server_addr = 0.0.0.0
server_port = 7000
log_file = ./frpc.log
log_level = info
log_max_days = 3
token = 12345678
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
pool_count = 5
tcp_mux = true#您的代理名称将更改为{user}。{proxy}
user = your_name
login_fail_exit = true
protocol = tcp
tls_enable = true#指定一个dns服务器,所以frpc将使用它而不是默认值
#默认为空,意味着所有代理
heartbeat_interval = 10
heartbeat_timeout = 90
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false
remote_port = 6001[dns]
type = udp
local_ip = 114.114.114.114
local_port = 53
remote_port = 6002
use_encryption = false
use_compression = false
[web01]
type = http
local_ip = 127.0.0.1
local_port = 80
use_encryption = false
use_compression = true
http_user = admin
http_pwd = admin
subdomain = web01
custom_domains = yourdomain.com
#locations 仅适用于HTTP类型
locations = /,/pic
host_header_rewrite = example.com
header_X-From-Where = frp
health_check_type = http
# FRPC将发送GET HTTP请求“/状态”本地HTTP服务
health_check_url = / status
health_check_interval_s = 10
health_check_max_failed = 3
health_check_timeout_s = 3[web02]
type = https
local_ip = 127.0.0.1
local_port = 8000
use_encryption = false
use_compression = false
subdomain = web02
custom_domains = web02.yourdomain.com[plugin_unix_domain_socket]
type = tcp
remote_port = 6003
#如果插件被定义,local_ip和LOCAL_PORT是无用
plugin = unix_domain_socket
#前缀PARAMS“plugin_”该插件需要
plugin_unix_path = /var/run/docker.sock[plugin_http_proxy]
type = tcp
remote_port = 6004
plugin = http_proxy
plugin_http_user = abc
plugin_http_passwd = abc[plugin_socks5]
type = tcp
remote_port = 6005
plugin = socks5
plugin_user = abc
plugin_passwd = abc[plugin_static_file]
type = tcp
remote_port = 6006
plugin = static_file
plugin_local_path = / var / www / blog
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc[secret_tcp]
#如果类型是秘密tcp,则remote_port是无用的
#想要连接本地端口的人应该使用stcp代理部署另一个frpc,并且role是visitor
type = stcp
# SK用于身份验证的访客
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false# FRPC的用户应该在这两个STCP服务器和STCP游客一样
[secret_tcp_visitor]
# FRPC作用访客- >FRPC角色服务器
role = visitor
type = stcp
#您要访问的服务器名称
server_name = secret_tcp
sk = abcdefg
#将此地址连接到访问者stcp服务器
bind_addr = 127.0.0.1
bind_port = 9000
use_encryption = false
use_compression = false[p2p_tcp]
type = xtcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false[p2p_tcp_visitor]
role = visitor
type = xtcp
server_name = p2p_tcp
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 9001
use_encryption = false
use_compression = false