如何用frp实现内网穿透
写在前面
众所周知的原因,运营商一般不会为每个接入用户单独分配IPv4公网地址。而大多数本地服务都有公网访问的需求,像是RDP、个人流媒体服务、家庭网盘。
我所在学校网络拓扑大致如下,AP隔离的情况使得校园局域网内设备之间无法直接访问,通过内网穿透能基本解决这一痛点。

frp 是什么?
frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
架构
frp架构如下,只需在用户端和服务端分别配置frp。

为什么选择 frp?
通过在具有公网 IP 的节点上部署 frp 服务端,您可以轻松地将内网服务穿透到公网,并享受以下专业特性:
多种协议支持:客户端服务端通信支持 TCP、QUIC、KCP 和 Websocket 等多种协议。
TCP 连接流式复用:在单个连接上承载多个请求,减少连接建立时间,降低请求延迟。
代理组间的负载均衡。
端口复用:多个服务可以通过同一个服务端端口暴露。
P2P 通信:流量不必经过服务器中转,充分利用带宽资源。
客户端插件:提供多个原生支持的客户端插件,如静态文件查看、HTTPS/HTTP 协议转换、HTTP、SOCKS5 代理等,以便满足各种需求。
服务端插件系统:高度可扩展的服务端插件系统,便于根据自身需求进行功能扩展。
用户友好的 UI 页面:提供服务端和客户端的用户界面,使配置和监控变得更加方便。
二、配置要求
一台带公网的服务器(或者是frp服务提供商)
需要内网穿透的设备
三、服务端frps配置
frp分为服务端和客户端部分。本部分先讲如何配置frps(即frp的服务端部分)
如果使用frp服务商则可以略过这一步。
以下示例均为个人使用实际需求,并未涵盖全部场景。
确保云服务器安全组中开放了对应端口
Linux服务实现
以Ubuntu系统(Debian系)为例。
从github上根据自己的系统和架构选择合适的文件下载
下载地址:https://github.com/fatedier/frp/releases
新建配置文件
新建一个文件夹用来存放配置文件
mkdir frps用vim新建一个文件frps.toml用来存放配置
vim frps.toml键入入下列配置
# frps.toml
bindPort = 7000 # 此处填写你监听的端口保存配置
启动frps
启动frps用frps.toml作为配置文件
./frps -c ./frps.toml可以看到输出日志为
2024-06-01 22:45:51.214 [I] [frps/root.go:105] frps uses config file: frps.toml
2024-06-01 22:45:51.331 [I] [server/service.go:237] frps tcp listen on 0.0.0.0:7000
2024-06-01 22:45:51.331 [I] [frps/root.go:114] frps started successfully表示启动成功,frps使用frps.toml作为配置文件并监听7000端口
将frps作为服务启动
将frps作为服务启动,使得其在后台仍能继续执行并随系统启动。
1.创建Unit配置文件
vim /usr/lib/systemd/system/frps.service编写配置文件
[Unit]
# 服务名称,可自定义
Description= frps
After = network.target syslog.target
Wants = network.target
[Service]
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart=/opt/frps/frps.sh
Type=simple
[Install]
WantedBy=multi-user.target
Alias=frp2.创建并编写sh脚本文件
vim /opt/frps/frps.sh#!/bin/sh
/opt/frps/frps -c /opt/frps/frps.toml3.服务配置
设置服务开机启动
systemctl enable frps启动服务
systemctl start frps查看服务状态
systemctl status frps日志如下
frps.service - frps
Loaded: loaded (/lib/systemd/system/frps.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2024-06-01 23:16:07 CST; 4s ago
Main PID: 19697 (frps.sh)
Tasks: 7 (limit: 1989)
Memory: 8.2M
CPU: 401ms
CGroup: /system.slice/frps.service
├─19697 /bin/sh /opt/frps/frps.sh
└─19698 /opt/frps/frps -c /opt/frps/frps.toml
Jun 01 23:16:07 hcss-ecs-f19a systemd[1]: Started frps.
Jun 01 23:16:07 hcss-ecs-f19a frps.sh[19698]: 2024-06-01 23:16:07.889 [I] [frps/root.go:105] frps uses config file: /opt/frps/frps.toml
Jun 01 23:16:08 hcss-ecs-f19a frps.sh[19698]: 2024-06-01 23:16:08.280 [I] [server/service.go:237] frps tcp listen on 0.0.0.0:7000
Jun 01 23:16:08 hcss-ecs-f19a frps.sh[19698]: 2024-06-01 23:16:08.281 [I] [frps/root.go:114] frps started successfully服务正常启动且配置完成
通过docker实现
前提
确保服务器环境安装有docker
liunx终端中输入
docker若出现
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Common Commands:
run Create and run a new container from an image
exec Execute a command in a running container
ps List containers
build Build an image from a Dockerfile
pull Download an image from a registry
push Upload an image to a registry
images List images
login Log in to a registry
logout Log out from a registry
search Search Docker Hub for images
version Show the Docker version information
info Display system-wide information
Management Commands:
builder Manage builds
...则表明docker环境正常
拉取docker镜像
docker pull snowdreamtech/frps启动容器
docker run --restart=always --network host -d -v /opt/frps/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps启动容器前确保创建好了frp配置文件
查看容器日志
docker logs frps输出log
2024-06-01 15:36:19.334 [I] [frps/root.go:105] frps uses config file: /etc/frp/frps.toml
2024-06-01 15:36:19.472 [I] [server/service.go:237] frps tcp listen on 0.0.0.0:7000
2024-06-01 15:36:19.472 [I] [frps/root.go:114] frps started successfully表明容器创建成功
1Panel面板创建frp 服务端
1Panel只是一个Linux服务器面板,本质还是通过docker创建frps,故若通过docker创建frps 亦可在面板容器菜单找到并管理frp。下面使用gui面板创建frps.
在应用商场里检索frp并安装frp 服务端

打开frp管理面板
管理面板默认端口为7500,在浏览器中键入http://serverIP:5700进入管理面板

用户名和密码在参数中查看
管理面板

四、客户端配置
配置文件规则
serverAddr = "x.x.x.x" # 暴露在公网的服务器地址
serverPort = 7000 # 公网服务监听端口与服务端保持一致
[[proxies]]
name = "ssh" # 隧道名称
type = "tcp" # 穿透类型
localIP = "127.0.0.1" # 本地地址
localPort = 22 # 本地端口
remotePort = 6000 # 远程端口
[[proxies]]
name = "web2"
type = "http"
localPort = 8080
customDomains = ["www.yourdomain2.com"] # 自定义端口名
[[proxies]]
name = "test_htts2http"
type = "https"
customDomains = ["test.yourdomain.com"]
[proxies.plugin] # 插件
type = "https2http"
localAddr = "127.0.0.1:80"
# HTTPS 证书相关的配置
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"一个文件可以配置多个代理
Linux服务部署
此处以Debian为例
下载对应服务端
配置frpc文件
以https连接为例
serverAddr = "xxx.xxx.xxx.xxx" # 服务器地址
serverPort = 7000
user = "填写从服务提供商获取的密钥" # 用户密钥
[auth]
method = "token"
token = "OpenFrpToken"
[transport]
protocol = "tcp"
[transport.tls]
enable = true
disableCustomTLSFirstByte = false
[[proxies]]
name = "alist"
type = "https"
localIP = "127.0.0.1"
localPort = 5244
customDomains = ["www.yourdomain.com"]
[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1"
# HTTPS 证书相关的配置
crtPath = "/opt/frpc/server.crt"
keyPath = "/opt/frpc/server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"保存为frpc.toml文件
新建服务文件
[Unit]
# 服务名称,可自定义
Description = frp client
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动frpc的命令,需修改为您的frpc的安装路径
ExecStart = /path/to/frpc -c /path/to/frpc.toml
[Install]
WantedBy = multi-user.target保存到/usr/lib/systemd/system/路径下
开机自启动
systemctl enable frpc使用docker安装
拉取镜像snowdreamtech/frpc
docker pull snowdreamtech/frpc启动容器
docker run --restart=always --network host -d -v /opt/frpc/frpc.toml:/etc/frp/frpc.toml -v /opt/frpc/server.crt:/etc/frpc/server.crt -v /opt/frpc/server.key:/etc/frpc/server.key --name frpc snowdreamtech/frpc五、最后
frp官方完整文档:https://github.com/fatedier/frp
frp docker文档:https://hub.docker.com/r/snowdreamtech/frpc