frp
官方文档 https://gofrp.org
为什么使用 frp ?
通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:
- 客户端服务端通信支持 TCP、QUIC、KCP 以及 Websocket 等多种协议。
- 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟。
- 代理组间的负载均衡。
- 端口复用,多个服务通过同一个服务端端口暴露。
- 支持 P2P 通信,流量不经过服务器中转,充分利用带宽资源。
- 多个原生支持的客户端插件(静态文件查看,HTTPS/HTTP 协议转换,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
- 高度扩展性的服务端插件系统,易于结合自身需求进行功能扩展。
- 服务端和客户端 UI 页面。
下载 frp
下载 frp 并解压后,在目录下有如下文件
frp_<version>_<platform>_<arch>
├── frpc # frp client 客户端
├── frpc.toml # frp client 配置文件
├── frps # frp server 服务端
├── frps.toml # frp server 配置文件
└── LICENSE通过 SSH 访问内网机器
服务端配置
NOTE
假设服务端是一台具有公网IP的机器,将在公网机器上部署 frp 服务端 (frps)。
部署 frps 并编辑 frps.toml 文件。以下是简化的配置,其中设置了 frp 服务器用于接收客户端连接的端口:
bindPort = 7000TIP
如果需要防止未授权客户端接入,可以可选地启用 token 认证:
bindPort = 7000
auth.method = "token"
auth.token = "<your-secure-token>"客户端对应配置:
serverAddr = "x.x.x.x"
serverPort = 7000
auth.method = "token"
auth.token = "<your-secure-token>"需要开放对应的端口
# ufw(Ubuntu / Debian)
sudo ufw allow 7000/tcp
sudo ufw reload
# firewalld(CentOS / RHEL)
PORT=7000
firewall-cmd --permanent --zone=public --add-port=${PORT}/tcp # 添加 frps 端口
firewall-cmd --reload # 更新防火墙规则
firewall-cmd --list-ports # 查看已开放的端口
# 如果后续不再使用
sudo ufw delete allow 7000/tcp # ufw
firewall-cmd --permanent --zone=public --remove-port=$PORT/tcp # firewalld 移除端口IMPORTANT
- 如果是云服务器,还需在云控制台的安全组中开放对应端口,仅开放系统防火墙端口无效
- 建议找不限流量、按带宽计费的云服务器
firewalld可能需要安装
启动 frps 服务
frps -c frps.toml客户端配置
NOTE
假设客户端是一台没有公网IP的内网机器,将在内网机器上部署 frp 客户端 (frpc)
修改 frpc.toml 配置文件,配置 frpc 服务端
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000启动 frpc 服务,查看是否连接成功
frpc -c frpc.toml连接成功后会输出日志,出现 start proxy success 的信息表示代理启动成功。
YYYY-MM-DD HH:MM:SS [I] start frpc service for config file [./frpc.toml]
YYYY-MM-DD HH:MM:SS [I] try to connect to server...
YYYY-MM-DD HH:MM:SS [I] [<run_id>] login to server success, get run id [<run_id>]
YYYY-MM-DD HH:MM:SS [I] [<run_id>] proxy added: [web]
YYYY-MM-DD HH:MM:SS [I][<run_id>] [web] start proxy success就可以使用 ssh 命令访问内网机器
ssh -p 6000 <user>@x.x.x.xSSH 代理原理
- 服务端 frps 启动时,会持续监听
7000端口 - 当客户端 frpc 启动时,会通过监听端口
7000进行注册(告诉服务端内网机器的被代理端口22和服务器上监听转发端口6000),并建立一个长连接,如果连接失败,则会尝试重新建立连接 - 当用户外部访问服务端指定端口
6000的时候,服务端会将流量转发至内网机器的被代理端口22上
端到端 SSH 隧道(tcpmux)
NOTE
基础 TCP 代理需要为每台机器单独开放 remotePort,多台机器时管理成本高。
在具有公网 IP 的机器上部署 frps,在内网机器上部署 frpc。tcpmux + httpconnect 可以将多个 SSH 服务复用到同一个端口,通过域名区分目标,客户端侧用 ProxyCommand 直连,无需在服务器上开额外端口。
服务端 frps.toml — 需要配置 tcpmuxHTTPConnectPort 让 frps 监听 HTTP CONNECT 请求:
bindPort = 7000
tcpmuxHTTPConnectPort = <proxy-port>并开放对应端口:
sudo ufw allow <proxy-port>/tcp客户端 frpc.toml — 用 customDomains 声明域名标识,localPort = 22 指向本地 SSH:
serverAddr = "frp.example.com"
serverPort = 7000
[[proxies]]
name = "ssh-device"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["device.frp.example.com"]
localIP = "127.0.0.1"
localPort = 22用户端 — 几种连接方式任选:
socat(Linux / macOS,需安装)
ssh -o 'proxycommand socat - PROXY:frp.example.com:%h:%p,proxyport=<proxy-port>' user@device.frp.example.com或写入 ~/.ssh/config:
Host device-tunnel
HostName device.frp.example.com
ProxyCommand socat - PROXY:frp.example.com:%h:%p,proxyport=<proxy-port>
User ubuntunc(macOS / Linux,零依赖)
nc 在 macOS 和主流 Linux 发行版(含 Ubuntu Server)上系统内置,无需安装:
ssh -o 'proxycommand nc -X connect -x frp.example.com:<proxy-port> %h %p' user@device.frp.example.com~/.ssh/config 写法:
Host device-tunnel
HostName device.frp.example.com
ProxyCommand nc -X connect -x frp.example.com:<proxy-port> %h %p
User ubuntusocat 和 nc 效果相同,区别仅在于:
| socat | nc | |
|---|---|---|
| macOS | 需 brew install socat | 系统内置 |
| Linux | 多数发行版预装 netcat-openbsd,和 macOS BSD nc 用法一致 | 需额外安装 |
| 本质 | 专门协议中继,PROXY: 语义清晰 | 通用网络工具,-X connect 通用代理 |
Windows
socat 和 BSD nc 在 Windows 上不可用,可用以下替代方案:
WSL(推荐)— 在 WSL 中配置
~/.ssh/config,直接用 Linux 版 ssh + socat,和上面完全一致。Git for Windows(Git Bash)— 自带的
ssh支持 ProxyCommand,需额外安装ncat:Host device-tunnel HostName device.frp.example.com ProxyCommand ncat --proxy-type http --proxy frp.example.com:<proxy-port> %h %p User ubuntuPowerShell — 同Git Bash
图形化终端 — Xshell、MobaXterm 等自带跳板代理功能,在连接设置中选择 HTTP 代理,填入
frp.example.com:<proxy-port>即可。
多台机器只需各自配置对应的
customDomains,共用同一个proxyport,无需为每台机器单独开防火墙端口。
使用 systemd 来管理 frp 服务
在 Linux 系统下,使用 systemd 可以方便地控制服务的启动、停止、配置后台运行以及开机自启动。
配置 frps 服务
将 frps 移动到 /usr/local/bin 目录下,配置文件移动到 /etc/frp 目录下
mv frps /usr/local/bin/
mkdir -p /etc/frp
mv frps.toml /etc/frp/在 /etc/systemd/system 下创建 frps.service 用于配置 frps 服务
vim /etc/systemd/system/frps.service写入内容
[Unit]
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动 frps 的命令, 需修改为您的 frps 的安装路径
ExecStart = /usr/local/bin/frps -c /etc/frp/frps.toml
ExecStop = /bin/kill $MAINPID
# 自动重启服务
# always = 无论什么原因退出都重启;on-failure = 仅异常退出时重启(异常退出够用,更保守)
Restart = always
# 重启间隔时间
RestartSec = 10
# 禁用启动限制,允许服务无限次重启
StartLimitInterval = 0
[Install]
WantedBy = multi-user.target使用 systemd 命令管理 frps 服务
systemctl start frps # 启动服务
systemctl stop frps # 停止服务
systemctl restart frps # 重启服务
systemctl status frps # 查看状态
journalctl -u frps -f # 查看日志
journalctl -u frps --since "10min ago" # 查看最近的日志设置 frps 开机自启动
systemctl enable frps配置 frpc 服务
将 frpc 移动到 /usr/local/bin 目录下,配置文件移动到 /etc/frp 目录下
mv frpc /usr/local/bin/
mkdir -p /etc/frp
mv frpc.toml /etc/frp/启动 frpc 服务,查看是否启动成功(日志输出 start proxy success)
/usr/local/bin/frpc -c /etc/frp/frpc.toml确定连接成功后,可以将 frpc 配置为系统服务。在 /etc/systemd/system 下创建 frpc.service 用于配置 frpc 服务
vim /etc/systemd/system/frpc.service写入内容
[Unit]
Description = frp client
After=network.target network-online.target
Wants=network-online.target
# 确保只有在网络可用的情况下,服务才会运行
Requires=network-online.target
[Service]
Type = simple
# 启动 frpc 的命令, 修改为您的 frpc的安装路径
ExecStart = /usr/local/bin/frpc -c /etc/frp/frpc.toml
ExecStop=/bin/kill $MAINPID
# 自动重启服务
# always = 无论什么原因退出都重启;on-failure = 仅异常退出时重启
Restart = always
# 重启间隔
RestartSec = 10
# 禁用启动限制,允许服务无限次重启
StartLimitInterval = 0
[Install]
WantedBy = multi-user.target使用 systemd 命令管理 frpc 服务
systemctl start frpc # 启动服务
systemctl stop frpc # 停止服务
systemctl restart frpc # 重启服务
systemctl status frpc # 查看状态
journalctl -u frpc -f # 查看日志设置 frpc 开机自启动
systemctl enable frpc