FRP内网穿透使用简明教程
一、定义:什么是FRP
1、frp是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务, 支持tcp, udp, http, https等协议类型,并且web服务支持根据域名进行路由转发。2、frp内网穿透主要用于没有公网IP的用户,实现远程桌面、远程控制路由器、 搭建的WEB、FTP、SMB服务器被外网访问、远程查看摄像头、调试一些远程的API(比如微信公众号,企业号的开发)等。
3、为什么要选择FRP?市面上提供内网穿透服务的公司对免费的用户是有限制的, 本站免费提供无限流量、无限域名绑定、不限制网速、不限制连接数的内网穿透服务。
简单的说,就是你的设备处于内网无法访问,通过一台有公网IP的服务器转接,让你能够在任何时间、任何地点访问你的内网设备的方法,当然你得首先有一台有公网IP的服务器,这个服务器就等于是一们中转站,通过双向连接达到访问的效果,访问速度取决于这台服务器的带宽速度。
准备工作
首先准备一台有公网IP的服务器, 也可以是自己的电脑或是路由器,比如:win10、linux、openwrt、Merlin等,如有高配置的路由器更好,毕竟路由器长期运行,更适合于做FRPS服务器。我长期使用Linux,就以Linux为例。
服务器端:frps、frps.ini、frps_full.ini
客户端:frpc、frpc.ini、frpc_full.ini
systemd文件夹下是系统服务文件
二、服务器组建(frps)
下载FRP软件,frp_0.38.0_linux_amd64.tar.gz :
wget https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_amd64.tar.gz
tar -zxvf frp_0.38.0_linux_amd64.tar.gz
只保留,frps和frps.ini,其余的删除。
rm frpc*
frps.ini是配置文件基本版,内容:
[common]
bind_port = 7000 #开放端口
可直接运行:
./frps -c ./frps.ini
即:使用frps.ini内的配置运行,如果后台运行,则在末尾加 &
./frps -c ./frps.ini &
# or
(./frps -c ./frps.ini &)
如果不允许别人进行连接,就要进行其它设置,比如token
[common]
bind_port = 7000 #开放连接端口
dashboard_port = 7500 #面板查看端口,web查看
bind_addr = 0.0.0.0
token = 123abc #连接token,客户端也要设置一样的
dashboard_user = admin #web面板用户名
dashboard_pwd = 123 #web面板密码
vhost_http_port = 7080
[SSH]
listen_port = 7022
三、客户端配置运行
客户端即是需要被外网访问的设备,可以是路由器(openwrt,梅林等),电脑等设备上运行
可执行程序是:frpc、frpc.ini
frpc.ini配置文件如下:
[common]
server_addr = serverIP #服务器地址,也可是域名地址
server_port = 7000 #服务器端口,用于客户端进行连接,要与frps.ini一致
token = 123abc #与frps.ini一致
[ssh] #连接名,随便写,但不能重复
type = tcp
local_ip = 127.0.0.1 #本地指向IP,一般是本机,可指向其他局域网机子
local_port = 22 #本机向外的端口
remote_port = 10022 #需要服务的外网地址
[http] #第2个开放端口服务,格式下同,可加入多个
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 10080
[ftp] #第3个开放端口服务
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 10021
客户端运行:
./frpc -c ./frpc.ini
后台:
(./frpc -c ./frpc.ini &)
以上事例访问22端口的SSH时:
ssh root@serverIP -p 10022
ssh -oPort=10022 test@serverIP
后台启动:
nohup /path/to/your/fprs -c /path/to/your/frps.ini
四、配置自动启动
4.1 windows
通过服务启动,参数:-c frps.ini
4.2 Linux配置自动启动
利用systemd服务配置自动启动
sudo vim /lib/systemd/system/frps.service
# 也可以是:
sudo vim /etc/systemd/system/frps.service
在frps.service里写入以下内容
[Unit]
Description=fraps service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
#启动服务的命令(此处写你的frps的实际安装目录)
ExecStart=/your/path/frps -c /your/path/frps.ini
[Install]
WantedBy=multi-user.target
或将frp目录中systemd下的frps(frpc).service复制到/linb/systemd/system/(有些是:/etc/init.d/)
然后启动:
sudo systemctl daemon-reload #系统服务重载
sudo systemctl start frpc #启动
sudo systemctl enable frpc #打开自动启动
sudo systemctl disenable frpc #关闭自动启动
sudo systemctl restart frps #重启应用
sudo systemctl stop frps #停止应用
sudo systemctl status frps #查看应用状态
4.3 OpenWrt配置开机启动
编辑/etc/rc.local,在exit 0前加入以下命令
#!/bin/bash
/root/frp/frps -c /root/frp/frps.ini
设置rc.local 的可执行权限,重启即可
chmod +x /etc/rc.local
五、功能特性
5.1配置文件
frp 目前仅支持 ini 格式的配置文件,frps 和 frpc 各自支持不同的参数。
frps 主要配置服务端的一些通用参数,frpc 则需要额外配置每一个代理的详细配置。
格式
目前仅支持 ini 格式的配置,如下的示例配置将本地 SSH 服务穿透到公网。
frps 配置:
[common]
bind_port = 7000
frpc 配置:
[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
[common]
是固定名称的段落,用于配置通用参数。
[ssh]
仅在 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
为前缀。
配置校验
通过执行 frpc verify -c ./frpc.ini
或 frps verify -c ./frps.ini
可以对配置文件中的参数进行预先校验。
frpc: the configuration file ./frpc.ini syntax is ok
如果出现此结果,则说明新的配置文件没有错误,否则会输出具体的错误信息。
配置拆分
通过 includes
参数可以在主配置中包含其他配置文件,从而实现将代理配置拆分到多个文件中管理。
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
includes = ./confd/*.ini
# ./confd/test.ini
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
上述配置在 frpc.ini 中通过 includes 额外包含了 ./confd
目录下所有的 ini 文件的代理配置内容,效果等价于将这两个文件合并成一个文件。
需要注意的是 includes 指定的文件中只能包含代理配置,common 段落的配置只能放在主配置文件中。
完整配置参数
由于 frp 目前支持的功能和配置项较多,未在文档中列出的功能参数可以在 参考 中查看。
5.2 身份认证
目前 frpc 和 frps 之间支持两种身份验证方式,token
和 oidc
,默认为 token
。
通过 frpc.ini
和 frps.ini
的 [common]
段落中配置 authentication_method
来指定要使用的身份验证方式。
只有通过身份验证的客户端(frpc)才能成功连接 frps。
Token
基于 Token 的身份验证方式比较简单,需要在 frpc 和 frps 的 [common]
段落中配置上相同的 token
参数即可。
OIDC
OIDC 是 OpenID Connect
的简称,验证流程参考 Client Credentials Grant。
启用这一验证方式,参考配置如下:
# frps.ini
[common]
authentication_method = oidc
oidc_issuer = https://example-oidc-issuer.com/
oidc_audience = https://oidc-audience.com/.default
# frpc.ini
[common]
authentication_method = oidc
oidc_client_id = 98692467-37de-409a-9fac-bb2585826f18 # Replace with OIDC client ID
oidc_client_secret = oidc_secret
oidc_audience = https://oidc-audience.com/.default
oidc_token_endpoint_url = https://example-oidc-endpoint.com/oauth2/v2.0/token
参数说明
类型 | 描述 |
---|---|
authentication_method | 身份验证方式,token 或 oidc,默认为 token。 |
authenticate_heartbeats | 在每一个心跳包中附加上身份认证信息,客户端服务端需要一致。 |
authenticate_new_work_conns | 在每次创建工作连接时附加上身份认证信息,客户端服务端需要一致。 |
5.3 Web 界面
目前 frpc 和 frps 分别内置了相应的 Web 界面方便用户使用。
服务端 Dashboard
服务端 Dashboard 使用户可以通过浏览器查看 frp 的状态以及代理统计信息。
注:Dashboard 尚未针对大量的 proxy 数据展示做优化,如果出现 Dashboard 访问较慢的情况,请不要启用此功能。
需要在 frps.ini 中指定 dashboard 服务使用的端口,即可开启此功能:
# frps.ini
[common]
dashboard_port = 7500
# dashboard 用户名密码,可选,默认为空
dashboard_user = admin
dashboard_pwd = admin
打开浏览器通过 http://[server_addr]:7500
访问 Dashboard 界面,输入用户名密码 admin
。
客户端管理界面
frpc 内置的 Admin UI 可以帮助用户通过浏览器来查询和管理客户端的 proxy 状态和配置。
需要在 frpc.ini 中指定 admin 服务使用的端口,即可开启此功能:
# frpc.ini
[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 UI,可以将 7400 端口通过 frp 映射出去即可,但需要重视安全风险。
# frpc.ini
[admin_ui]
type = tcp
local_port = 7400
remote_port = 7400
5.4 范围端口映射
在 frpc 的配置文件中可以指定映射多个端口,目前只支持 TCP 和 UDP 的代理类型。
这一功能通过 range:
段落标记来实现,客户端会解析这个标记中的配置,将其拆分成多个 proxy,每一个 proxy 以数字为后缀命名。
例如要映射本地 6000-6005, 6007 这7个端口,主要配置如下:
# frpc.ini
[range:test_tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 6000-6005,6007
remote_port = 6000-6005,6007
实际连接成功后会创建 7 个 proxy,命名为 test_tcp_0, test_tcp_1 ... test_tcp_6
。
六、通过自定义域名访问内网的 Web 服务
这个示例通过简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务。
HTTP 类型的代理相比于 TCP 类型,不仅在服务端只需要监听一个额外的端口 vhost_http_port 用于接收 HTTP 请求,还额外提供了基于 HTTP 协议的诸多功能。
修改 frps.ini 文件,设置监听 HTTP 请求端口为 8080:
[common]
bind_port = 7000
vhost_http_port = 8080
修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为 x.x.x.x,local_port 为本地机器上 Web 服务监听的端口, 绑定自定义域名为 custom_domains。
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com
[web2]
type = http
local_port = 8080
custom_domains = www.yourdomain2.com
分别启动 frps 和 frpc。
将 www.yourdomain.com 和 www.yourdomain2.com 的域名 A 记录解析到 IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME 记录解析到服务器原先的域名。或者可以通过修改 HTTP 请求的 Host 字段来实现同样的效果。
通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上 80 端口的服务,访问 http://www.yourdomain2.com:8080 则访问到内网机器上 8080 端口的服务。
七、点对点内网穿透
这个示例将会演示一种不通过服务器中转流量的方式来访问内网服务。
frp 提供了一种新的代理类型 xtcp
用于应对在希望传输大量数据且流量不经过服务器的场景。
使用方式同 stcp
类似,需要在两边都部署上 frpc 用于建立直接的连接。
目前处于开发的初级阶段,并不能穿透所有类型的 NAT 设备,所以穿透成功率较低。穿透失败时可以尝试 stcp
的方式。
frps.ini 内容如下,需要额外配置监听一个 UDP 端口用于支持该类型的客户端:
[common] bind_port = 7000 bind_udp_port = 7000
在需要暴露到内网的机器上部署 frpc,且配置如下:
[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
在想要访问内网服务的机器上也部署 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
通过 SSH 访问内网机器,假设用户名为 test:
ssh -oPort=6000 test@127.0.0.1
八、参考内容
服务端配置
frp 服务端详细配置说明。
基础配置
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
bind_addr | string | 服务端监听地址 | 0.0.0.0 | ||
bind_port | int | 服务端监听端口 | 7000 | 接收 frpc 的连接 | |
bind_udp_port | int | 服务端监听 UDP 端口 | 0 | 用于辅助创建 P2P 连接 | |
kcp_bind_port | int | 服务端监听 KCP 协议端口 | 0 | 用于接收采用 KCP 连接的 frpc | |
proxy_bind_addr | string | 代理监听地址 | 同 bind_addr | 可以使代理监听在不同的网卡地址 | |
log_file | string | 日志文件地址 | ./frps.log | 如果设置为 console,会将日志打印在标准输出中 | |
log_level | string | 日志等级 | info | trace, debug, info, warn, error | |
log_max_days | int | 日志文件保留天数 | 3 | ||
disable_log_color | bool | 禁用标准输出中的日志颜色 | false | ||
detailed_errors_to_client | bool | 服务端返回详细错误信息给客户端 | true | ||
heartbeat_timeout | int | 服务端和客户端心跳连接的超时时间 | 90 | 单位:秒 | |
user_conn_timeout | int | 用户建立连接后等待客户端响应的超时时间 | 10 | 单位:秒 | |
udp_packet_size | int | 代理 UDP 服务时支持的最大包长度 | 1500 | 服务端和客户端的值需要一致 | |
tls_cert_file | string | TLS 服务端证书文件路径 | |||
tls_key_file | string | TLS 服务端密钥文件路径 | |||
tls_trusted_ca_file | string | TLS CA 证书路径 |
权限验证
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
authentication_method | string | 鉴权方式 | token | token, oidc | |
authenticate_heartbeats | bool | 开启心跳消息鉴权 | false | ||
authenticate_new_work_conns | bool | 开启建立工作连接的鉴权 | false | ||
token | string | 鉴权使用的 token 值 | 客户端需要设置一样的值才能鉴权通过 | ||
oidc_issuer | string | oidc_issuer | |||
oidc_audience | string | oidc_audience | |||
oidc_skip_expiry_check | bool | oidc_skip_expiry_check | |||
oidc_skip_issuer_check | bool | oidc_skip_issuer_check |
管理配置
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
allow_ports | string | 允许代理绑定的服务端端口 | 格式为 1000-2000,2001,3000-4000 | ||
max_pool_count | int | 最大连接池大小 | 5 | ||
max_ports_per_client | int | 限制单个客户端最大同时存在的代理数 | 0 | 0 表示没有限制 | |
tls_only | bool | 只接受启用了 TLS 的客户端连接 | false |
Dashboard, 监控
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
dashboard_addr | string | 启用 Dashboard 监听的本地地址 | 0.0.0.0 | ||
dashboard_port | int | 启用 Dashboard 监听的本地端口 | 0 | ||
dashboard_user | string | HTTP BasicAuth 用户名 | |||
dashboard_pwd | string | HTTP BasicAuth 密码 | |||
enable_prometheus | bool | 是否提供 Prometheus 监控接口 | false | 需要同时启用了 Dashboard 才会生效 | |
asserts_dir | string | 静态资源目录 | Dashboard 使用的资源默认打包在二进制文件中,通过指定此参数使用自定义的静态资源 |
HTTP & HTTPS
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
vhost_http_port | int | 为 HTTP 类型代理监听的端口 | 0 | 启用后才支持 HTTP 类型的代理,默认不启用 | |
vhost_https_port | int | 为 HTTPS 类型代理监听的端口 | 0 | 启用后才支持 HTTPS 类型的代理,默认不启用 | |
vhost_http_timeout | int | HTTP 类型代理在服务端的 ResponseHeader 超时时间 | 60 | ||
subdomain_host | string | 二级域名后缀 | |||
custom_404_page | string | 自定义 404 错误页面地址 |
TCPMUX
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
tcpmux_httpconnect_port | int | 为 TCPMUX 类型代理监听的端口 | 0 | 启用后才支持 TCPMUX 类型的代理,默认不启用 |
客户端配置
frp 客户端的详细配置说明。
基础配置
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
server_addr | string | 连接服务端的地址 | 0.0.0.0 | ||
server_port | int | 连接服务端的端口 | 7000 | ||
http_proxy | string | 连接服务端使用的代理地址 | 格式为 {protocol}://user:passwd@192.168.1.128:8080 protocol 目前支持 http、socks5、ntlm | ||
log_file | string | 日志文件地址 | ./frpc.log | 如果设置为 console,会将日志打印在标准输出中 | |
log_level | string | 日志等级 | info | trace, debug, info, warn, error | |
log_max_days | int | 日志文件保留天数 | 3 | ||
disable_log_color | bool | 禁用标准输出中的日志颜色 | false | ||
pool_count | int | 连接池大小 | 0 | ||
user | string | 用户名 | 设置此参数后,代理名称会被修改为 {user}.{proxyName},避免代理名称和其他用户冲突 | ||
dns_server | string | 使用 DNS 服务器地址 | 默认使用系统配置的 DNS 服务器,指定此参数可以强制替换为自定义的 DNS 服务器地址 | ||
login_fail_exit | bool | 第一次登陆失败后是否退出 | true | ||
protocol | string | 连接服务端的通信协议 | tcp | tcp, kcp, websocket | |
tls_enable | bool | 启用 TLS 协议加密连接 | false | ||
tls_cert_file | string | TLS 客户端证书文件路径 | |||
tls_key_file | string | TLS 客户端密钥文件路径 | |||
tls_trusted_ca_file | string | TLS CA 证书路径 | |||
tls_server_name | string | TLS Server 名称 | 为空则使用 server_addr | ||
disable_custom_tls_first_byte | bool | TLS 不发送 0x17 | false | 当为 true 时,不能端口复用 | |
heartbeat_interval | int | 向服务端发送心跳包的间隔时间 | 30 | ||
heartbeat_timeout | int | 和服务端心跳的超时时间 | 90 | ||
udp_packet_size | int | 代理 UDP 服务时支持的最大包长度 | 1500 | 服务端和客户端的值需要一致 | |
start | string | 指定启用部分代理 | 当配置了较多代理,但是只希望启用其中部分时可以通过此参数指定,默认为全部启用 |
权限验证
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
authentication_method | string | 鉴权方式 | token | token, oidc | 需要和服务端一致 |
authenticate_heartbeats | bool | 开启心跳消息鉴权 | false | 需要和服务端一致 | |
authenticate_new_work_conns | bool | 开启建立工作连接的鉴权 | false | 需要和服务端一致 | |
token | string | 鉴权使用的 token 值 | 需要和服务端设置一样的值才能鉴权通过 | ||
oidc_client_id | string | oidc_client_id | |||
oidc_client_secret | string | oidc_client_secret | |||
oidc_audience | string | oidc_audience | |||
oidc_token_endpoint_url | string | oidc_token_endpoint_url |
UI
参数 | 类型 | 说明 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|---|
admin_addr | string | 启用 AdminUI 监听的本地地址 | 0.0.0.0 | ||
admin_port | int | 启用 AdminUI 监听的本地端口 | 0 | ||
admin_user | string | HTTP BasicAuth 用户名 | |||
admin_pwd | string | HTTP BasicAuth 密码 | |||
asserts_dir | string | 静态资源目录 | AdminUI 使用的资源默认打包在二进制文件中,通过指定此参数使用自定义的静态资源 |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 vault@coolxy.cn