前言

随着全球IPv4地址耗尽,新装电信宽带一般也只给分配内网IP,不开放外网IP了,但是随时智能设备的越来越普及,像电脑、NAS、树莓派、摄像头等网络设备需要远程控制时较为麻烦,幸好有大佬开发了这款FRP软件,简单易用开源。

因为你需要在外网访问这些应用,你就需要一款内网穿透工具来让外网与你家内网建立起连接,实现无公网 IP 的远程访问了。「Frp」是一款流行的跨平台开源免费内网穿透工具,支持 Windows、macOS 与 Linux。你只需一台快速稳定的 VPS 服务器即可愉快地进行内网穿透,实现家中设备公网直接访问了。

Frp基本信息

frp全名Fast Reverse Proxy,是用于提供内网穿透服务的工具,主要用于解决一些内网服务没有公网ip但是却需要提供外网访问的问题。使用frp你可以将内网中的TCP、UDP、HTTP、HTTPS等协议类型的服务发布到公网,并且支持Web服务根据域名进行路由转发。

frp已经将项目开源至github,想深入了解的朋友可以点击跳转地址,进行深入了解:github项目地址(frp)

Frp使用要求

如上图的frp架构图所示:(必须)想要使用frp服务,将内网中的服务发布到公网。

你需要先拥有一台拥有公网ip的网络设置搭建frp服务端,再在内网需要穿透的设置中搭建frp客户端服务才能进行穿透;

(非必需)你需要拥有一个域名解析到公网的ip地址,才能够实现web服务的通过域名进行路由转发的功能。

Frp服务的搭建

搭建frp很简单,关键的步骤只有三步:第一步:获取frp文件;

第二步:设置frp配置文件;

第三步:启动frp服务。

注意:frp搭建的的这三步是分为客户端和服务端的,但是操作基本是一致的。本教程frp服务的搭建主要介绍frp搭建的主要三步,以及frp服务端和客户端配置文件内容的解释说明,以及如何将frp在linux系统中创建systemd服务,进行服务管理。

第一步:获取frp文件

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

frp支持linux平台和windows平台。参照你的设置的运行平台下载linux版本的文件或者是windows的。

下载地址:https://github.com/fatedier/frp/releases

一般linux平台下载的版本为:frp_版本号_linux_amd64.tar.gz

windows平台下载的版本为:frp_版本号_windows_amd64.zip

FRP软件下载

截止本文发布时间最新版为v0.33.0,请尽量使用最新版本。

一、Linux系统:export FRP_VERSION=0.33.0

mkdir -p /etc/frp

cd /etc/frp

wget "https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_amd64.tar.gz"

tar xzvf frp_${FRP_VERSION}_linux_amd64.tar.gz

mv frp_${FRP_VERSION}_linux_amd64/* /etc/frp其中,第一行等号后面的0.33.0是 frp 的版本号 (截稿为止最新版本)。你安装的时候可以到官网查看下有没更新的版本,只需将新版本的号码替换掉0.33.0即可。

FRP 默认提供了2个服务端配置文件,一个是简化版的frps.ini,另一个是完整版的frps_full.ini。初学者只需用简版配置即可,在简版frps.ini配置文件里,默认设置了监听端口为7000,你可以按需修改它。

二、windows系统

文件直接右键解压即可。

文件解压后,一般都含有frps(frp服务端运行文件)、frpc(frp客户端运行文件)、frps.ini(frp服务端配置文件)、frpc.ini(frp客户端配置文件),以及frp_full.ini(frp全部配置文件解释说明和参考。)

防火墙和安全组开放指定的端口:

请一定要记住,你需要将服务器的系统防火墙,以及阿里云、腾讯云后台里找到“安全组策略”的相关配置,设置7000或你修改过的对应端口的「允许入站和出站」,否则会一直连接不上的哦!!!这个切记!!

第二步:frp配置文件设置

frp配置文件分为服务端和客户端,想要正常只用frp工具,我们需要对服务端和客户端的配置文件分别进行设置。

官方中文文档:https://github.com/fatedier/frp/blob/master/README_zh.md

frps.ini(服务端)配置文件解释说明:# [common] is integral section

[common]

# A literal address or host name for IPv6 must be enclosed

# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"

bind_addr = 0.0.0.0

bind_port = 7000

# udp port to help make udp hole to penetrate nat

bind_udp_port = 7001

# udp port used for kcp protocol, it can be same with 'bind_port'

# if not set, kcp is disabled in frps

kcp_bind_port = 7000

# specify which address proxy will listen for, default value is same with bind_addr

# proxy_bind_addr = 127.0.0.1

# if you want to support virtual host, you must set the http port for listening (optional)

# Note: http port and https port can be same with bind_port

vhost_http_port = 80

vhost_https_port = 443

# response header timeout(seconds) for vhost http server, default is 60s

# vhost_http_timeout = 60

# set dashboard_addr and dashboard_port to view dashboard of frps

# dashboard_addr's default value is same with bind_addr

# dashboard is available only if dashboard_port is set

dashboard_addr = 0.0.0.0

dashboard_port = 7500

# dashboard user and passwd for basic auth protect, if not set, both default value is admin

dashboard_user = admin

dashboard_pwd = admin

# dashboard assets directory(only for debug mode)

# assets_dir = ./static

# console or real logFile path like ./frps.log

log_file = ./frps.log

# trace, debug, info, warn, error

log_level = info

log_max_days = 3

# auth token

token = 12345678

# heartbeat configure, it's not recommended to modify the default value

# the default value of heartbeat_timeout is 90

# heartbeat_timeout = 90

# only allow frpc to bind ports you list, if you set nothing, there won't be any limit

allow_ports = 2000-3000,3001,3003,4000-50000

# pool_count in each proxy will change to max_pool_count if they exceed the maximum value

max_pool_count = 5

# max ports can be used for each client, default value is 0 means no limit

max_ports_per_client = 0

# authentication_timeout means the timeout interval (seconds) when the frpc connects frps

# if authentication_timeout is zero, the time is not verified, default is 900s

authentication_timeout = 900

# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file

# when subdomain is test, the host used by routing is test.frps.com

subdomain_host = frps.com

# if tcp stream multiplexing is used, default is true

tcp_mux = true //TCP多路复用,默认启用

frpc.ini(客户端)配置文件解释说明:# [common] is integral section

[common]

# A literal address or host name for IPv6 must be enclosed

# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"

server_addr = 0.0.0.0

server_port = 7000

# if you want to connect frps by http proxy or socks5 proxy, you can set http_proxy here or in global environment variables

# it only works when protocol is tcp

# http_proxy = http://user:passwd@192.168.1.128:8080

# http_proxy = socks5://user:passwd@192.168.1.128:1080

# console or real logFile path like ./frpc.log

log_file = ./frpc.log

# trace, debug, info, warn, error

log_level = info

log_max_days = 3

# for authentication

token = 12345678

# set admin address for control frpc's action by http api such as reload

admin_addr = 127.0.0.1

admin_port = 7400

admin_user = admin

admin_pwd = admin

# connections will be established in advance, default value is zero

pool_count = 5

# if tcp stream multiplexing is used, default is true, it must be same with frps

tcp_mux = true

# your proxy name will be changed to {user}.{proxy}

user = your_name

# decide if exit program when first login failed, otherwise continuous relogin to frps

# default is true

login_fail_exit = true

# communication protocol used to connect to server

# now it supports tcp and kcp and websocket, default is tcp

protocol = tcp

# specify a dns server, so frpc will use this instead of default one

# dns_server = 8.8.8.8

# proxy names you want to start divided by ','

# default is empty, means all proxies

# start = ssh,dns

# heartbeat configure, it's not recommended to modify the default value

# the default value of heartbeat_interval is 10 and heartbeat_timeout is 90

# heartbeat_interval = 30

# heartbeat_timeout = 90

# 'ssh' is the unique proxy name

# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh'

[ssh]

# tcp | udp | http | https | stcp | xtcp, default is tcp

type = tcp

local_ip = 127.0.0.1

local_port = 22

# true or false, if true, messages between frps and frpc will be encrypted, default is false

use_encryption = false

# if true, message will be compressed

use_compression = false

# remote port listen by frps

remote_port = 6001

# frps will load balancing connections for proxies in same group

group = test_group

# group should have same group key

group_key = 123456

# enable health check for the backend service, it support 'tcp' and 'http' now

# frpc will connect local service's port to detect it's healthy status

health_check_type = tcp

health_check_interval_s = 10

health_check_max_failed = 1

health_check_timeout_s = 3

[ssh_random]

type = tcp

local_ip = 127.0.0.1

local_port = 22

# if remote_port is 0, frps will assign a random port for you

remote_port = 0

# if you want to expose multiple ports, add 'range:' prefix to the section name

# frpc will generate multiple proxies such as 'tcp_port_6010', 'tcp_port_6011' and so on.

[range:tcp_port]

type = tcp

local_ip = 127.0.0.1

local_port = 6010-6020,6022,6024-6028

remote_port = 6010-6020,6022,6024-6028

use_encryption = false

use_compression = false

[dns]

type = udp

local_ip = 114.114.114.114

local_port = 53

remote_port = 6002

use_encryption = false

use_compression = false

[range:udp_port]

type = udp

local_ip = 127.0.0.1

local_port = 6010-6020

remote_port = 6010-6020

use_encryption = false

use_compression = false

# Resolve your domain names to [server_addr] so you can use http://web01.yourdomain.com to browse web01 and http://web02.yourdomain.com to browse web02

[web01]

type = http

local_ip = 127.0.0.1

local_port = 80

use_encryption = false

use_compression = true

# http username and password are safety certification for http protocol

# if not set, you can access this custom_domains without certification

http_user = admin

http_pwd = admin

# if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com

subdomain = web01

custom_domains = web02.yourdomain.com

# locations is only available for http type

locations = /,/pic

host_header_rewrite = example.com

# params with prefix "header_" will be used to update http request headers

header_X-From-Where = frp

health_check_type = http

# frpc will send a GET http request '/status' to local http service

# http service is alive when it return 2xx http response code

health_check_url = /status

health_check_interval_s = 10

[web02]

type = https

local_ip = 127.0.0.1

local_port = 8000

use_encryption = false

use_compression = false

subdomain = web01

custom_domains = web02.yourdomain.com

[plugin_unix_domain_socket]

type = tcp

remote_port = 6003

# if plugin is defined, local_ip and local_port is useless

# plugin will handle connections got from frps

plugin = unix_domain_socket

# params with prefix "plugin_" that plugin needed

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]

# If the type is secret tcp, remote_port is useless

# Who want to connect local port should deploy another frpc with stcp proxy and role is visitor

type = stcp

# sk used for authentication for visitors

sk = abcdefg

local_ip = 127.0.0.1

local_port = 22

use_encryption = false

use_compression = false

# user of frpc should be same in both stcp server and stcp visitor

[secret_tcp_visitor]

# frpc role visitor -> frps -> frpc role server

role = visitor

type = stcp

# the server name you want to visitor

server_name = secret_tcp

sk = abcdefg

# connect this address to visitor stcp server

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

第三步:启动服务

启动FRP服务端

Linux启动Frp服务端命令:

linux环境下启动服务,需要先把运行文件添加可执行权限。

一、服务端

例如我的文件在/etc/frp/文件夹中,我需要搭建frp服务端,那么待设置好服务端配置文件(frps.ini)后执行以下命令即可:cd /etc/frp/

chmod +x frps

./frps -c ./frps.ini

执行成功后,会显示frp的进程号码。你也可以通过命令来查看frps运行的进程编号:ps -e | grep frps

二、客户端

例如我的文件在/etc/frp/文件夹中,我需要搭建frp服务端,那么待设置好服务端配置文件(frpc.ini)后执行以下命令即可:cd /etc/frp/

chmod +x frpc

./frpc -c ./frpc.ini

执行成功后,会显示frp的进程号码。你也可以通过命令来查看frps运行的进程编号:ps -e | grep frpc

windows启动Frp服务端命令:

在windows环境下则是以管理员身份运行cmd命令提示符。进入相应的目录后,运行命令即可,假设解压到c:\frp文件夹,那么只需这样启动:c:\frp\frps.exe -c c:\frp\frps.ini

启动FRP客户端:

windows启动Frp客户端命令:

在windows环境下则是以管理员身份运行cmd命令提示符。进入相应的目录后,运行命令即可,假设你已将Frp的客户端解压缩到c:\frp目录中,那么启动Frp客户端的命令就是:c:\frp\frpc.exe -c c:\frp\frpc.ini

Linux启动Frp客户端命令:./frpc -c ./frpc.ini

启动之后看到 “start proxy success”字样就表示启动成功了。

注意放行端口

每个服务的 remote_port 是远程访问时要用到的端口号,注意这些端口号也要在服务器的防火墙和安全组里放行才能顺利访问的,如上面的 7001、7002。

进行远程访问:

前面搞了这么多,我们终于可以正式使用 Frp 内网穿透来进行远程访问内网里的设备了!按照上面的配置,我们想要访问群晖 NAS 的界面,只需打开浏览器,在地址栏输入 服务器公网IP:7001 即可访问到群晖后台管理界面。

而如果需要远程桌面连接到家里的 Windows 电脑,那么打开“微软远程桌面客户端”后,在地址栏里填入 服务器公网IP:7002 即可连接。

由此,借助 Frp,你就能轻松地为本地局域网内网的设备提供公网直接访问的能力了,你可以用 Frp 来转发包括但不限于 ssh、http、https、转发 Unix 域套接字等服务。

上面只是最基础的教程,Frp 还有很多很多高级功能,比如给 Web 增加密码保护、点对点内网穿透、设置端口白名单等等,Frp 官网上也提供了很详细的文档,感兴趣的朋友可以去研究一下。

关于frp管理的优化设置

debian8.0,或者是centos7.0以上的版本,服务都是基于systemd的方式进行管理的。frp通过设置后也可以实现systemd的方式进行管理,这样我们就可以通过systemctl命令来进行服务的统一管理,同时通过这样的设置也可以将frp服务加入开机自启动。

将frp设置成linux系统的服务,基于systemd方式管理

一、服务端

编写frps.service文件,以centos7为例:vim /usr/lib/systemd/system/frps.service

内容如下:[Unit]

Description=frps daemon

After=syslog.target network.target

Wants=network.target

[Service]

Type=simple

ExecStart=/etc/frp/frps -c /etc/frp/frps.ini

Restart=always

RestartSec=1min

[Install]

WantedBy=multi-user.target

将frp设置成开机自启动systemctl enable frps

systemctl start frps

二、客户端

编写frpc.service文件,以centos7为例:vi /usr/lib/systemd/system/frpc.service

内容如下:[Unit]

Description=frpc daemon

After=syslog.target network.target

Wants=network.target

[Service]

Type=simple

ExecStart=/etc/frp/frpc -c /etc/frp/frpc.ini

Restart=always

RestartSec=1min

[Install]

WantedBy=multi-user.target

将frp设置成开机自启动systemctl enable frpc

systemctl start frpc

Frp到此就配置完了。

附:个人参考配置一

服务端(frps.ini):[common]

bind_addr = 0.0.0.0

bind_port = 7000

token = jTf4sW6PkQ12331

dashboard_port = 6443

dashboard_user = 用户名

dashboard_pwd = 密码

vhost_http_port = 8080

vhost_https_port = 4430

访问仪表盘地址:http://服务器公网IP:6443,账号密码为如上设置。

客户端一(frpc.ini):[common]

server_addr = 服务器公网IP

server_port = 7000

token = jTf4sW6PkQ12331

[RDP1]

type = tcp

local_ip = 192.168.1.144

local_port = 3389

remote_port = 33891

[TCP1]

type = tcp

local_ip = 192.168.1.144

local_port = 10900

remote_port = 10900

[web1]

type = http

local_ip = 127.0.0.1

local_port = 80

custom_domains = XXX1.baidu.com

远程本机3389端口:服务器公网IP:33891,本机登录账号密码

访问本机80端口的web的网址:http://XXX1.baidu.com:8080

客户端二(frpc.ini):[common]

server_addr = 服务器公网IP

server_port = 7000

token = jTf4sW6PkQ12331

[RDP2]

type = tcp

local_ip = 192.168.1.143

local_port = 3389

remote_port = 33892

[web2]

type = http

local_port = 8080

custom_domains = XXX2.baidu.com

远程本机3389端口:服务器公网IP:33892,本机登录账号密码

访问本机8080端口的web的网址:http://XXX2.baidu.com:8080

特别说明:

教程很详细是因供大家查阅理解功能,其实大部分都用不到反到把人看晕,参考以上配置案例更方便。

这套配置是自己当前在Windows系统下使用的,因为连接了两台内网机器,两台机器的[]中命名除了common项其他的都不能重复。

附:个人参考配置二

服务端:[common]

bind_addr = 0.0.0.0 //绑定地址

bind_port = 8888 //TCP绑定端口

bind_udp_port = 8888 //UDP绑定端口

kcp_bind_port = 8888 //KCP绑定端口

vhost_http_port = 80 //HTTP代理端口

vhost_https_port = 443 //HTTPS代理端口

dashboard_addr = 0.0.0.0 //仪表盘地址

dashboard_port = 10000 //仪表盘端口

dashboard_user = admin //仪表盘用户名

dashboard_pwd = admin //仪表盘密码

token = 123456 //连接密码

subdomain_host = test.com //子域名使用的主机名

客户端:[common]

server_addr = 172.16.100.100 //服务器地址

server_port = 8888 //服务器绑定端口

token = 123456 //特权模式密码

[web] //服务名称(自定义)

local_ip = 192.168.10.50 //本机ip

type = http //链路类型

local_port = 80 //本机端口

subdomain = web //服务端为test.com,故此处子域名为web.test.com

custom_domains = demo.com //自定义访问域名,多个使用,分割

use_compression = true //使用压缩

use_encryption = true //使用加密

[ssh] //服务名称(自定义)

local_ip = 192.168.10.50 //本机ip

type = tcp //链路类型

local_port = 22 //本机端口

remote_port = 9000 //远程访问端口

use_compression = true //使用压缩

use_encryption = true //使用加密

注:具体参数请根据需要配置。

附:其他优化配置

#开启FTP[ftp20]

type = tcp

local_ip = 127.0.0.1

local_port = 20

remote_port = 2120

[ftp21]

type = tcp

local_ip = 127.0.0.1

local_port = 21

remote_port = 2121

[ftp1]

type = tcp

local_ip = 127.0.0.1

local_port = 39000

remote_port = 39000

[ftp2]

type = tcp

local_ip = 127.0.0.1

local_port = 39001

remote_port = 39001

[ftp3]

type = tcp

local_ip = 127.0.0.1

local_port = 39002

remote_port = 39002

如果是用宝塔面板,在面板设置FTP端口,

操作:软件商店 - Pure-Ftpd - 设置 - 配置修改,搜索 PassivePortRange 修改被动连接端口PassivePortRange 39000 39002

另附一篇frp使用教程

使用示例

根据对应的操作系统及架构,从 Release 页面下载最新版本的程序。将 frps 及 frps.ini 放到具有公网 IP 的机器上。

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

通过 ssh 访问公司内网机器

1、修改 frps.ini 文件,这里使用了最简化的配置:# frps.ini

[common]

bind_port = 7000

2、启动 frps:./frps -c ./frps.ini

3、修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.x;# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[ssh]

type = tcp

local_ip = 127.0.0.1

local_port = 22

remote_port = 6000

4、启动 frpc:./frpc -c ./frpc.ini

5、通过 ssh 访问内网机器,假设用户名为 test:ssh -oPort=6000 test@x.x.x.x

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

有时想要让其他人通过域名访问或者测试我们在本地搭建的 web 服务,但是由于本地机器没有公网 IP,无法将域名解析到本地的机器,通过 frp 就可以实现这一功能,以下示例为 http 服务,https 服务配置方法相同, vhost_http_port 替换为 vhost_https_port, type 设置为 https 即可。

1、修改 frps.ini 文件,设置 http 访问端口为 8080:# frps.ini

[common]

bind_port = 7000

vhost_http_port = 8080

2、启动 frps;./frps -c ./frps.ini

3、修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为 x.x.x.x,local_port 为本地机器上 web 服务对应的端口, 绑定自定义域名 www.yourdomain.com:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[web]

type = http

local_port = 80

custom_domains = www.yourdomain.com

4、启动 frpc:./frpc -c ./frpc.ini

5、将 www.yourdomain.com 的域名 A 记录解析到 IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME 记录解析到服务器原先的域名。

6、通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上的 web 服务。

转发 DNS 查询请求

DNS 查询请求通常使用 UDP 协议,frp 支持对内网 UDP 服务的穿透,配置方式和 TCP 基本一致。

1、修改 frps.ini 文件:# frps.ini

[common]

bind_port = 7000

2、启动 frps:./frps -c ./frps.ini

3、修改 frpc.ini 文件,设置 frps 所在服务器的 IP 为 x.x.x.x,转发到 Google 的 DNS 查询服务器 8.8.8.8 的 udp 53 端口:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[dns]

type = udp

local_ip = 8.8.8.8

local_port = 53

remote_port = 6000

4、启动 frpc:./frpc -c ./frpc.ini

5、通过 dig 测试 UDP 包转发是否成功,预期会返回 www.google.com 域名的解析结果:dig @x.x.x.x -p 6000 www.google.com

转发 Unix域套接字

通过 tcp 端口访问内网的 unix域套接字(例如和 docker daemon 通信)。

frps 的部署步骤同上。

1、启动 frpc,启用 unix_domain_socket 插件,配置如下:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[unix_domain_socket]

type = tcp

remote_port = 6000

plugin = unix_domain_socket

plugin_unix_path = /var/run/docker.sock

2、通过 curl 命令查看 docker 版本信息curl http://x.x.x.x:6000/version

对外提供简单的文件访问服务

通过 static_file 插件可以对外提供一个简单的基于 HTTP 的文件访问服务。

frps 的部署步骤同上。

1、启动 frpc,启用 static_file 插件,配置如下:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[test_static_file]

type = tcp

remote_port = 6000

plugin = static_file

# 要对外暴露的文件目录

plugin_local_path = /tmp/file

# 访问 url 中会被去除的前缀,保留的内容即为要访问的文件路径

plugin_strip_prefix = static

plugin_http_user = abc

plugin_http_passwd = abc

2、通过浏览器访问 http://x.x.x.x:6000/static/ 来查看位于 /tmp/file 目录下的文件,会要求输入已设置好的用户名和密码。

为本地 HTTP 服务启用 HTTPS

通过 https2http 插件可以让本地 HTTP 服务转换成 HTTPS 服务对外提供。

1、启用 frpc,启用 https2http 插件,配置如下:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[test_htts2http]

type = https

custom_domains = test.yourdomain.com

plugin = https2http

plugin_local_addr = 127.0.0.1:80

# HTTPS 证书相关的配置

plugin_crt_path = ./server.crt

plugin_key_path = ./server.key

plugin_host_header_rewrite = 127.0.0.1

2、通过浏览器访问 https://test.yourdomain.com 即可。

安全地暴露内网服务

对于某些服务来说如果直接暴露于公网上将会存在安全隐患。

使用 stcp(secret tcp) 类型的代理可以避免让任何人都能访问到要穿透的服务,但是访问者也需要运行另外一个 frpc。

以下示例将会创建一个只有自己能访问到的 ssh 服务代理。

frps 的部署步骤同上。

1、启动 frpc,转发内网的 ssh 服务,配置如下,不需要指定远程端口:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[secret_ssh]

type = stcp

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

sk = abcdefg

local_ip = 127.0.0.1

local_port = 22

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

[common]

server_addr = x.x.x.x

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 = 6000

3、通过 ssh 访问内网机器,假设用户名为 test:ssh -oPort=6000 test@127.0.0.1

点对点内网穿透

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

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

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

1、frps 除正常配置外需要额外配置一个 udp 端口用于支持该类型的客户端:bind_udp_port = 7001

2、启动 frpc,转发内网的 ssh 服务,配置如下,不需要指定远程端口:# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

[p2p_ssh]

type = xtcp

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

sk = abcdefg

local_ip = 127.0.0.1

local_port = 22

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

[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、通过 ssh 访问内网机器,假设用户名为 test:ssh -oPort=6000 test@127.0.0.1

功能说明

配置文件

由于 frp 目前支持的功能和配置项较多,未在文档中列出的功能可以从完整的示例配置文件中发现。

frps 完整配置文件

frpc 完整配置文件

配置文件模版渲染

配置文件支持使用系统环境变量进行模版渲染,模版格式采用 Go 的标准格式。

示例配置如下:# frpc.ini

[common]

server_addr = {{ .Envs.FRP_SERVER_ADDR }}

server_port = 7000

[ssh]

type = tcp

local_ip = 127.0.0.1

local_port = 22

remote_port = {{ .Envs.FRP_SSH_REMOTE_PORT }}

启动 frpc 程序:export FRP_SERVER_ADDR="x.x.x.x"

export FRP_SSH_REMOTE_PORT="6000"

./frpc -c ./frpc.ini

frpc 会自动使用环境变量渲染配置文件模版,所有环境变量需要以 .Envs 为前缀。

Dashboard

通过浏览器查看 frp 的状态以及代理统计信息展示。

注:Dashboard 尚未针对大量的 proxy 数据展示做优化,如果出现 Dashboard 访问较慢的情况,请不要启用此功能。

需要在 frps.ini 中指定 dashboard 服务使用的端口,即可开启此功能:[common]

dashboard_port = 7500

# dashboard 用户名密码,默认都为 admin

dashboard_user = admin

dashboard_pwd = admin

打开浏览器通过 http://[server_addr]:7500 访问 dashboard 界面,用户名密码默认为 admin。

[图片上传失败...(image-1164e2-1562577679203)]

Admin UI

Admin UI 可以帮助用户通过浏览器来查询和管理客户端的 proxy 状态和配置。

需要在 frpc.ini 中指定 admin 服务使用的端口,即可开启此功能:[common]

admin_addr = 127.0.0.1

admin_port = 7400

admin_user = admin

admin_pwd = admin

打开浏览器通过 http://127.0.0.1:7400 访问 Admin UI,用户名密码默认为 admin。

如果想要在外网环境访问 Admin UI,将 7400 端口映射出去即可,但需要重视安全风险。

身份验证

服务端和客户端的 common 配置中的 token 参数一致则身份验证通过。

加密与压缩

这两个功能默认是不开启的,需要在 frpc.ini 中通过配置来为指定的代理启用加密与压缩的功能,压缩算法使用 snappy:# frpc.ini

[ssh]

type = tcp

local_port = 22

remote_port = 6000

use_encryption = true

use_compression = true

如果公司内网防火墙对外网访问进行了流量识别与屏蔽,例如禁止了 ssh 协议等,通过设置 use_encryption = true,将 frpc 与 frps 之间的通信内容加密传输,将会有效防止流量被拦截。

如果传输的报文长度较长,通过设置 use_compression = true 对传输内容进行压缩,可以有效减小 frpc 与 frps 之间的网络流量,加快流量转发速度,但是会额外消耗一些 cpu 资源。

TLS

从 v0.25.0 版本开始 frpc 和 frps 之间支持通过 TLS 协议加密传输。通过在 frpc.ini 的 common 中配置 tls_enable = true 来启用此功能,安全性更高。

为了端口复用,frp 建立 TLS 连接的第一个字节为 0x17。

注意: 启用此功能后除 xtcp 外,不需要再设置 use_encryption。

客户端热加载配置文件

当修改了 frpc 中的代理配置,可以通过 frpc reload 命令来动态加载配置文件,通常会在 10 秒内完成代理的更新。

启用此功能需要在 frpc 中启用 admin 端口,用于提供 API 服务。配置如下:# frpc.ini

[common]

admin_addr = 127.0.0.1

admin_port = 7400

之后执行重启命令:frpc reload -c ./frpc.ini

等待一段时间后客户端会根据新的配置文件创建、更新、删除代理。

需要注意的是,[common] 中的参数除了 start 外目前无法被修改。

客户端查看代理状态

frpc 支持通过 frpc status -c ./frpc.ini 命令查看代理的状态信息,此功能需要在 frpc 中配置 admin 端口。

端口白名单

为了防止端口被滥用,可以手动指定允许哪些端口被使用,在 frps.ini 中通过 allow_ports 来指定:# frps.ini

[common]

allow_ports = 2000-3000,3001,3003,4000-50000

allow_ports 可以配置允许使用的某个指定端口或者是一个范围内的所有端口,以 , 分隔,指定的范围以 - 分隔。

端口复用

目前 frps 中的 vhost_http_port 和 vhost_https_port 支持配置成和 bind_port 为同一个端口,frps 会对连接的协议进行分析,之后进行不同的处理。

例如在某些限制较严格的网络环境中,可以将 bind_port 和 vhost_https_port 都设置为 443。

后续会尝试允许多个 proxy 绑定同一个远端端口的不同协议。

TCP 多路复用

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

该功能默认启用,如需关闭,可以在 frps.ini 和 frpc.ini 中配置,该配置项在服务端和客户端必须一致:# frps.ini 和 frpc.ini 中

[common]

tcp_mux = false

底层通信可选 kcp 协议

底层通信协议支持选择 kcp 协议,在弱网环境下传输效率提升明显,但是会有一些额外的流量消耗。

开启 kcp 协议支持:

1、在 frps.ini 中启用 kcp 协议支持,指定一个 udp 端口用于接收客户端请求:# frps.ini

[common]

bind_port = 7000

# kcp 绑定的是 udp 端口,可以和 bind_port 一样

kcp_bind_port = 7000

2、在 frpc.ini 指定需要使用的协议类型,目前只支持 tcp 和 kcp。其他代理配置不需要变更:# frpc.ini

[common]

server_addr = x.x.x.x

# server_port 指定为 frps 的 kcp_bind_port

server_port = 7000

protocol = kcp

3、像之前一样使用 frp,需要注意开放相关机器上的 udp 的端口的访问权限。

连接池

默认情况下,当用户请求建立连接后,frps 才会请求 frpc 主动与后端服务建立一个连接。当为指定的代理启用连接池后,frp 会预先和后端服务建立起指定数量的连接,每次接收到用户请求后,会从连接池中取出一个连接和用户连接关联起来,避免了等待与后端服务建立连接以及 frpc 和 frps 之间传递控制信息的时间。

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

1、首先可以在 frps.ini 中设置每个代理可以创建的连接池上限,避免大量资源占用,客户端设置超过此配置后会被调整到当前值:# frps.ini

[common]

max_pool_count = 5

2、在 frpc.ini 中为客户端启用连接池,指定预创建连接的数量:# frpc.ini

[common]

pool_count = 1

负载均衡

可以将多个相同类型的 proxy 加入到同一个 group 中,从而实现负载均衡的功能。

目前只支持 tcp 类型的 proxy。# frpc.ini

[test1]

type = tcp

local_port = 8080

remote_port = 80

group = web

group_key = 123

[test2]

type = tcp

local_port = 8081

remote_port = 80

group = web

group_key = 123

用户连接 frps 服务器的 80 端口,frps 会将接收到的用户连接随机分发给其中一个存活的 proxy。这样可以在一台 frpc 机器挂掉后仍然有其他节点能够提供服务。

要求 group_key 相同,做权限验证,且 remote_port 相同。

健康检查

通过给 proxy 加上健康检查的功能,可以在要反向代理的服务出现故障时,将这个服务从 frps 中摘除,搭配负载均衡的功能,可以用来实现高可用的架构,避免服务单点故障。

在每一个 proxy 的配置下加上 health_check_type = {type} 来启用健康检查功能。

type 目前可选 tcp 和 http。

tcp 只要能够建立连接则认为服务正常,http 会发送一个 http 请求,服务需要返回 2xx 的状态码才会被认为正常。

tcp 示例配置如下:# frpc.ini

[test1]

type = tcp

local_port = 22

remote_port = 6000

# 启用健康检查,类型为 tcp

health_check_type = tcp

# 建立连接超时时间为 3 秒

health_check_timeout_s = 3

# 连续 3 次检查失败,此 proxy 会被摘除

health_check_max_failed = 3

# 每隔 10 秒进行一次健康检查

health_check_interval_s = 10

http 示例配置如下:# frpc.ini

[web]

type = http

local_ip = 127.0.0.1

local_port = 80

custom_domains = test.yourdomain.com

# 启用健康检查,类型为 http

health_check_type = http

# 健康检查发送 http 请求的 url,后端服务需要返回 2xx 的 http 状态码

health_check_url = /status

health_check_interval_s = 10

health_check_max_failed = 3

health_check_timeout_s = 3

修改 Host Header

通常情况下 frp 不会修改转发的任何数据。但有一些后端服务会根据 http 请求 header 中的 host 字段来展现不同的网站,例如 nginx 的虚拟主机服务,启用 host-header 的修改功能可以动态修改 http 请求中的 host 字段。该功能仅限于 http 类型的代理。# frpc.ini

[web]

type = http

local_port = 80

custom_domains = test.yourdomain.com

host_header_rewrite = dev.yourdomain.com

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

设置 HTTP 请求的 header

对于 type = http 的代理,可以设置在转发中动态添加的 header 参数。# frpc.ini

[web]

type = http

local_port = 80

custom_domains = test.yourdomain.com

host_header_rewrite = dev.yourdomain.com

header_X-From-Where = frp

对于参数配置中所有以 header_ 开头的参数(支持同时配置多个),都会被添加到 http 请求的 header 中,根据如上的配置,会在请求的 header 中加上 X-From-Where: frp。

获取用户真实 IP

HTTP X-Forwarded-For

目前只有 http 类型的代理支持这一功能,可以通过用户请求的 header 中的 X-Forwarded-For 来获取用户真实 IP,默认启用。

Proxy Protocol

frp 支持通过 Proxy Protocol 协议来传递经过 frp 代理的请求的真实 IP,此功能支持所有以 TCP 为底层协议的类型,不支持 UDP。

Proxy Protocol 功能启用后,frpc 在和本地服务建立连接后,会先发送一段 Proxy Protocol 的协议内容给本地服务,本地服务通过解析这一内容可以获得访问用户的真实 IP。所以不仅仅是 HTTP 服务,任何的 TCP 服务,只要支持这一协议,都可以获得用户的真实 IP 地址。

需要注意的是,在代理配置中如果要启用此功能,需要本地的服务能够支持 Proxy Protocol 这一协议,目前 nginx 和 haproxy 都能够很好的支持。

这里以 https 类型为例:# frpc.ini

[web]

type = https

local_port = 443

custom_domains = test.yourdomain.com

# 目前支持 v1 和 v2 两个版本的 proxy protocol 协议。

proxy_protocol_version = v2

只需要在代理配置中增加一行 proxy_protocol_version = v2 即可开启此功能。

本地的 https 服务可以通过在 nginx 的配置中启用 Proxy Protocol 的解析并将结果设置在 X-Real-IP 这个 Header 中就可以在自己的 Web 服务中通过 X-Real-IP 获取到用户的真实 IP。

通过密码保护你的 web 服务

由于所有客户端共用一个 frps 的 http 服务端口,任何知道你的域名和 url 的人都能访问到你部署在内网的 web 服务,但是在某些场景下需要确保只有限定的用户才能访问。

frp 支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需要通过用户名和密码才能访问到你的服务。

该功能目前仅限于 http 类型的代理,需要在 frpc 的代理配置中添加用户名和密码的设置。# frpc.ini

[web]

type = http

local_port = 80

custom_domains = test.yourdomain.com

http_user = abc

http_pwd = abc

通过浏览器访问 http://test.yourdomain.com,需要输入配置的用户名和密码才能访问。

自定义二级域名

在多人同时使用一个 frps 时,通过自定义二级域名的方式来使用会更加方便。

通过在 frps 的配置文件中配置 subdomain_host,就可以启用该特性。之后在 frpc 的 http、https 类型的代理中可以不配置 custom_domains,而是配置一个 subdomain 参数。

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

[common]

subdomain_host = frps.com

将泛域名 *.frps.com 解析到 frps 所在服务器的 IP 地址。# frpc.ini

[web]

type = http

local_port = 80

subdomain = test

frps 和 frpc 都启动成功后,通过 test.frps.com 就可以访问到内网的 web 服务。

注:如果 frps 配置了 subdomain_host,则 custom_domains 中不能是属于 subdomain_host 的子域名或者泛域名。

同一个 http 或 https 类型的代理中 custom_domains 和 subdomain 可以同时配置。

URL 路由

frp 支持根据请求的 URL 路径路由转发到不同的后端服务。

通过配置文件中的 locations 字段指定一个或多个 proxy 能够匹配的 URL 前缀(目前仅支持最大前缀匹配,之后会考虑正则匹配)。例如指定 locations = /news,则所有 URL 以 /news 开头的请求都会被转发到这个服务。# frpc.ini

[web01]

type = http

local_port = 80

custom_domains = web.yourdomain.com

locations = /

[web02]

type = http

local_port = 81

custom_domains = web.yourdomain.com

locations = /news,/about

按照上述的示例配置后,web.yourdomain.com 这个域名下所有以 /news 以及 /about 作为前缀的 URL 请求都会被转发到 web02,其余的请求会被转发到 web01。

通过代理连接 frps

在只能通过代理访问外网的环境内,frpc 支持通过 HTTP PROXY 和 frps 进行通信。

可以通过设置 HTTP_PROXY 系统环境变量或者通过在 frpc 的配置文件中设置 http_proxy 参数来使用此功能。

仅在 protocol = tcp 时生效。# frpc.ini

[common]

server_addr = x.x.x.x

server_port = 7000

http_proxy = http://user:pwd@192.168.1.128:8080

范围端口映射

在 frpc 的配置文件中可以指定映射多个端口,目前只支持 tcp 和 udp 的类型。

这一功能通过 range: 段落标记来实现,客户端会解析这个标记中的配置,将其拆分成多个 proxy,每一个 proxy 以数字为后缀命名。

例如要映射本地 6000-6005, 6007 这6个端口,主要配置如下:# frpc.ini

[range:test_tcp]

type = tcp

local_ip = 127.0.0.1

local_port = 6000-6006,6007

remote_port = 6000-6006,6007

实际连接成功后会创建 8 个 proxy,命名为 test_tcp_0, test_tcp_1 ... test_tcp_7。

插件

默认情况下,frpc 只会转发请求到本地 tcp 或 udp 端口。

插件模式是为了在客户端提供更加丰富的功能,目前内置的插件有 unix_domain_socket、http_proxy、socks5、static_file。具体使用方式请查看使用示例。

通过 plugin 指定需要使用的插件,插件的配置参数都以 plugin_ 开头。使用插件后 local_ip 和 local_port 不再需要配置。

使用 http_proxy 插件的示例:# frpc.ini

[http_proxy]

type = tcp

remote_port = 6000

plugin = http_proxy

plugin_http_user = abc

plugin_http_passwd = abc

plugin_http_user 和 plugin_http_passwd 即为 http_proxy 插件可选的配置参数。

frp 后台地址_FRP内网穿透配置教程及配置分享相关推荐

  1. frp 后台地址_内网穿透工具frp搭建与使用详细教程

    简介:FRP(Fast Reverse Proxy) 是一款简单,好用,稳定的隧道工具.FRP 使用 Go 语言开发,它是一款高性能的反向代理应用,可以轻松地进行内网穿透,对外网提供服务.FRP 支持 ...

  2. 使用frp端口映射实现内网穿透(SSH、HTTP服务)

    使用frp端口映射实现内网穿透(SSH.HTTP服务) 一.下载 通过内网穿透的原理和实现方式的学习我们已经明白了内网穿透的原理,想要实现内网穿透就需要让内网实现与具有公网IP的设备进行绑定. 我们这 ...

  3. 使用frp搭建自己的内网穿透

    背景 微信开发等场景需要使用公网地址,但开发者本地通常没有公网IP,需要搭建内网穿透来方便调试.通常可以使用花生壳.Ngrok.frp等.花生壳需要实名认证, 需要6块钱,且使用别人服务器有一定的安全 ...

  4. 阿里云搭建frp服务实现本地内网穿透

    如果使用我的链接购买阿里云服务器,我将免费提供帮忙搭建阿里云的frp服务. 背景 利用阿里云搭建frp服务,本地frp客户端来实现内网穿透,来达到访问没有公网ip的远程机器 frp服务端搭建 首先我们 ...

  5. (Frp第一篇)Frp内网穿透安装教程#Frps服务端一键安装脚本#

    系统:CentOS7 内存:1G CPU:单核1G 客户端安装教程:(Frp第二篇)Frp内网穿透安装教程#Frp OpenWrt客户端安装#图形化管理 注意事项:记得给使用的端口开放防火墙,开放防火 ...

  6. frp点对点udp方式内网穿透ssh,不走服务器流量

    frp点对点udp方式内网穿透ssh,不走服务器流量 (2019 年 5 月 30 日) frp ssh 安全连接和服务器安全设置 (2019 年 5 月 29 日) frp 控制台监控dashboa ...

  7. 永久免费 内网穿透工具 傻瓜式配置

    永久免费 内网穿透工具   傻瓜式配置 使用教程 配合工具:网云穿 先官网注册:点击访问注册 1.进入官网首页,点击右上方注册 2.注册后,我们在官网领取隧道 3.领取完隧道会直接让我们跳转控制台,配 ...

  8. ngrok配置信息_ngrok内网穿透服务器搭建及配置(附 frp 配置)

    12月18日更新 添加 frp 配置 前言 内网穿透,无需多言,用处多多.首先强力推荐一款Sunny大大搭建的ngrok服务好用的不行,而且有免费选项,感觉平时够用了.那么,为什么自己还要搭建一个呢? ...

  9. 为远程桌面Ubuntu配置固定的公网TCP端口地址【内网穿透】

    上篇文章,我们实现了在公网环境下,通过免费的cpolar内网穿透,远程桌面连接Ubuntu系统.不过使用免费的cpolar,带宽比较小,并且所生成的公网TCP端口地址为随机临时地址,每隔24小时就会变 ...

最新文章

  1. linux文件权限详解
  2. linux系统vim程序编译器,Linux学习:vim程序编辑器
  3. app微信支付的集成步骤
  4. {%csrf_token%}的作用
  5. wxWidgets:从互联网下载文件
  6. HihoCoder - 1591 锦标赛(最大费用最大流)
  7. Linux内存管理详解
  8. PHP笔记-平润年判断例子
  9. 攻防世界 ics-05 write up
  10. DEVC使用问题集锦
  11. java 二进制文件修改_Java读写二进制文件操作
  12. excel最常用的八个函数
  13. 读书笔记-《墨菲定律》
  14. C# 对目录中的文件名按照数字序号进行排序
  15. pictureBox用法
  16. 做人要厚道,做技术更要如此
  17. Spring Boot 开发环境热部署(HotSwap)详解
  18. iPad越狱失败 越狱恢复
  19. attribute __naked cannot be compiled without allocated auto area
  20. 三十二楼层选几层最好_一般买房买几楼比较好 1一32高楼层选最佳楼层

热门文章

  1. 自建cdn搭建_自建CDN部署平台
  2. 【HTML+CSS+JS】前端三剑客实现3D旋转照片墙
  3. a9g 开发环境搭建 windows
  4. springmvc拦截器对请求参数解密_springMvc使用拦截器自定义处理参数
  5. python中的split、rsplit、splitlines
  6. OriginBot智能机器人开源套件-Step2系统镜像安装与备份
  7. CANopen / PROFIBUS DP网关
  8. 最终为京东苏宁价格战买单的会是谁
  9. java的两种比较器
  10. mmclassification-安装使用(一)