Skip to content

frp

官方文档 https://gofrp.org

为什么使用 frp ?

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:

  • 客户端服务端通信支持 TCP、QUIC、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 支持 P2P 通信,流量不经过服务器中转,充分利用带宽资源。
  • 多个原生支持的客户端插件(静态文件查看,HTTPS/HTTP 协议转换,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,易于结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

下载 frp

下载 frp 并解压后,在目录下有如下文件

bash
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 服务器用于接收客户端连接的端口:

toml
bindPort = 7000

TIP

如果需要防止未授权客户端接入,可以可选地启用 token 认证:

toml
bindPort = 7000

auth.method = "token"
auth.token = "<your-secure-token>"

客户端对应配置:

toml
serverAddr = "x.x.x.x"
serverPort = 7000

auth.method = "token"
auth.token = "<your-secure-token>"

需要开放对应的端口

bash
# 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 服务

bash
frps -c frps.toml

客户端配置

NOTE

假设客户端是一台没有公网IP的内网机器,将在内网机器上部署 frp 客户端 (frpc)

修改 frpc.toml 配置文件,配置 frpc 服务端

toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

启动 frpc 服务,查看是否连接成功

bash
frpc -c frpc.toml

连接成功后会输出日志,出现 start proxy success 的信息表示代理启动成功。

bash
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 命令访问内网机器

bash
ssh -p 6000 <user>@x.x.x.x

SSH 代理原理

FRP SSH Connection

  • 服务端 frps 启动时,会持续监听 7000 端口
  • 当客户端 frpc 启动时,会通过监听端口 7000 进行注册(告诉服务端内网机器的被代理端口 22 和服务器上监听转发端口 6000),并建立一个长连接,如果连接失败,则会尝试重新建立连接
  • 当用户外部访问服务端指定端口 6000 的时候,服务端会将流量转发至内网机器的被代理端口 22

端到端 SSH 隧道(tcpmux)

NOTE

基础 TCP 代理需要为每台机器单独开放 remotePort,多台机器时管理成本高。

在具有公网 IP 的机器上部署 frps,在内网机器上部署 frpc。tcpmux + httpconnect 可以将多个 SSH 服务复用到同一个端口,通过域名区分目标,客户端侧用 ProxyCommand 直连,无需在服务器上开额外端口。

端到端 SSH 隧道

服务端 frps.toml — 需要配置 tcpmuxHTTPConnectPort 让 frps 监听 HTTP CONNECT 请求:

toml
bindPort = 7000
tcpmuxHTTPConnectPort = <proxy-port>

并开放对应端口:

bash
sudo ufw allow <proxy-port>/tcp

客户端 frpc.toml — 用 customDomains 声明域名标识,localPort = 22 指向本地 SSH:

toml
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,需安装)

bash
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 ubuntu

nc(macOS / Linux,零依赖)

nc 在 macOS 和主流 Linux 发行版(含 Ubuntu Server)上系统内置,无需安装:

bash
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 ubuntu

socatnc 效果相同,区别仅在于:

socatnc
macOSbrew install socat系统内置
Linux多数发行版预装 netcat-openbsd,和 macOS BSD nc 用法一致需额外安装
本质专门协议中继,PROXY: 语义清晰通用网络工具,-X connect 通用代理

Windows

socat 和 BSD nc 在 Windows 上不可用,可用以下替代方案:

  1. WSL(推荐)— 在 WSL 中配置 ~/.ssh/config,直接用 Linux 版 ssh + socat,和上面完全一致。

  2. 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 ubuntu
  3. PowerShell — 同Git Bash

  4. 图形化终端 — Xshell、MobaXterm 等自带跳板代理功能,在连接设置中选择 HTTP 代理,填入 frp.example.com:<proxy-port> 即可。

多台机器只需各自配置对应的 customDomains,共用同一个 proxyport,无需为每台机器单独开防火墙端口。

使用 systemd 来管理 frp 服务

在 Linux 系统下,使用 systemd 可以方便地控制服务的启动、停止、配置后台运行以及开机自启动。

配置 frps 服务

将 frps 移动到 /usr/local/bin 目录下,配置文件移动到 /etc/frp 目录下

bash
mv frps /usr/local/bin/
mkdir -p /etc/frp
mv frps.toml /etc/frp/

/etc/systemd/system 下创建 frps.service 用于配置 frps 服务

bash
vim /etc/systemd/system/frps.service

写入内容

ini
[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 服务

bash
systemctl start   frps                             # 启动服务
systemctl stop    frps                             # 停止服务
systemctl restart frps                             # 重启服务
systemctl status  frps                             # 查看状态
journalctl -u frps -f                              # 查看日志
journalctl -u frps --since "10min ago"             # 查看最近的日志

设置 frps 开机自启动

bash
systemctl enable frps

配置 frpc 服务

将 frpc 移动到 /usr/local/bin 目录下,配置文件移动到 /etc/frp 目录下

bash
mv frpc /usr/local/bin/
mkdir -p /etc/frp
mv frpc.toml /etc/frp/

启动 frpc 服务,查看是否启动成功(日志输出 start proxy success

bash
/usr/local/bin/frpc -c /etc/frp/frpc.toml

确定连接成功后,可以将 frpc 配置为系统服务。在 /etc/systemd/system 下创建 frpc.service 用于配置 frpc 服务

bash
vim /etc/systemd/system/frpc.service

写入内容

ini
[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 服务

bash
systemctl start   frpc # 启动服务
systemctl stop    frpc # 停止服务
systemctl restart frpc # 重启服务
systemctl status  frpc # 查看状态
journalctl -u frpc -f  # 查看日志

设置 frpc 开机自启动

bash
systemctl enable frpc

⏰ 最后更新于: