Skip to content
OpenInfoHub
Go back

frp 内网穿透完整部署指南:服务端与客户端配置教程

本教程将指导你完整部署 frp(fast reverse proxy)内网穿透工具,包括服务端和客户端的安装与配置。内容基于 frp 官方项目整理,涵盖多种实用场景和最佳实践。

Table of contents

Open Table of contents

frp 简介

frp 是一个高性能的反向代理应用,可以帮助你将位于 NAT 或防火墙后的本地服务暴露到公网。它支持 TCP、UDP、HTTP 和 HTTPS 等多种协议,还提供了 P2P 连接模式。

主要特性

应用场景

架构说明

frp 采用 C/S 架构,主要包含两个组件:

工作流程:

  1. frpc 连接到 frps 并建立控制连接
  2. 用户访问 frps 的公网地址
  3. frps 通过控制连接通知 frpc 建立新的工作连接
  4. frpc 建立工作连接并转发流量到本地服务
  5. 流量在 frps 和 frpc 之间双向传输

第一步:下载 frp

获取最新版本

访问 frp Releases 页面下载适合你操作系统和架构的版本。

Linux 系统下载示例

# 下载最新版本(以 v0.62.0 为例,请根据实际情况调整版本号)
wget https://github.com/fatedier/frp/releases/download/v0.62.0/frp_0.62.0_linux_amd64.tar.gz

# 解压
tar -xzf frp_0.62.0_linux_amd64.tar.gz

# 进入目录
cd frp_0.62.0_linux_amd64

Windows 系统下载

下载对应的 Windows 版本(如 frp_0.62.0_windows_amd64.zip),解压后即可使用。

文件说明

解压后的目录包含以下主要文件:

注意:部分杀毒软件可能会误报 frpc 为恶意软件并删除。这是因为 frp 作为网络工具具有创建反向代理的能力,可能被误判。如果遇到此问题,请在杀毒软件中将 frpc 添加到白名单。

第二步:部署服务端(frps)

服务端需要部署在具有公网 IP 的服务器上(如云服务器)。

基础配置

创建服务端配置文件 frps.toml

# frps.toml
# 客户端连接端口
bindPort = 7000

这是最简单的配置,frps 将在 7000 端口监听客户端连接。

启动服务端

./frps -c ./frps.toml

完整配置示例

# frps.toml
# 客户端连接端口
bindPort = 7000

# HTTP 虚拟主机端口
vhostHTTPPort = 8080

# HTTPS 虚拟主机端口
vhostHTTPSPort = 8443

# TCP 多路复用 HTTP CONNECT 端口
tcpmuxHTTPConnectPort = 5002

# KCP 协议绑定端口(可选)
kcpBindPort = 7000

# QUIC 协议绑定端口(可选)
quicBindPort = 7000

# SSH 隧道网关端口(可选)
sshTunnelGateway.bindPort = 2200

# 限制允许的端口范围
allowPorts = [
  { start = 2000, end = 3000 },
  { single = 3001 },
  { single = 3003 },
  { start = 4000, end = 50000 }
]

# 子域名配置
subDomainHost = "frps.com"

# Web 管理界面
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"

# 启用 Prometheus 监控
enablePrometheus = true

# 身份验证
auth.method = "token"
auth.token = "your_secure_token_here"

# TLS 配置
transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"

配置说明

配置 systemd 服务(Linux)

创建服务文件 /etc/systemd/system/frps.service

[Unit]
Description=frp server
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml

[Install]
WantedBy=multi-user.target

安装并启动服务:

# 复制文件到系统目录
sudo mkdir -p /etc/frp
sudo cp frps.toml /etc/frp/
sudo cp frps /usr/local/bin/

# 启动服务
sudo systemctl daemon-reload
sudo systemctl start frps
sudo systemctl enable frps

# 查看状态
sudo systemctl status frps

使用 Docker 部署(可选)

docker run -d \
  --name frps \
  --restart=always \
  -p 7000:7000 \
  -p 8080:8080 \
  -p 7500:7500 \
  -v /path/to/frps.toml:/etc/frp/frps.toml \
  fatedier/frp:latest \
  frps -c /etc/frp/frps.toml

第三步:部署客户端(frpc)

客户端部署在需要暴露服务的内网机器上。

基础配置

创建客户端配置文件 frpc.toml

# frpc.toml
# 服务端地址(替换为你的服务器公网 IP)
serverAddr = "x.x.x.x"
serverPort = 7000

# 身份验证(需与服务端配置一致)
auth.method = "token"
auth.token = "your_secure_token_here"

# SSH 代理示例
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

启动客户端

./frpc -c ./frpc.toml

配置 systemd 服务(Linux)

创建服务文件 /etc/systemd/system/frpc.service

[Unit]
Description=frp client
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml

[Install]
WantedBy=multi-user.target

安装并启动服务:

# 复制文件到系统目录
sudo mkdir -p /etc/frp
sudo cp frpc.toml /etc/frp/
sudo cp frpc /usr/local/bin/

# 启动服务
sudo systemctl daemon-reload
sudo systemctl start frpc
sudo systemctl enable frpc

# 查看状态
sudo systemctl status frpc

常见使用场景

场景一:SSH 远程访问

通过 frp 实现远程 SSH 访问内网机器。

客户端配置:

serverAddr = "x.x.x.x"
serverPort = 7000
auth.method = "token"
auth.token = "your_secure_token_here"

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

连接方式:

ssh -p 6000 user@x.x.x.x

场景二:Web 服务访问

将内网 Web 服务通过域名暴露到公网。

服务端配置:

bindPort = 7000
vhostHTTPPort = 8080
subDomainHost = "example.com"

客户端配置:

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

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]
# 或使用子域名
# subdomain = "myapp"

DNS 配置:

访问方式:

http://www.example.com:8080

场景三:HTTPS 服务

为本地 HTTP 服务启用 HTTPS。

客户端配置:

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

[[proxies]]
name = "web_https"
type = "https"
customDomains = ["secure.example.com"]

[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:80"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"

场景四:远程桌面(RDP)

暴露 Windows 远程桌面服务。

客户端配置:

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

[[proxies]]
name = "rdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 7001

连接方式:使用远程桌面客户端连接到 x.x.x.x:7001

场景五:文件服务器

快速搭建一个简单的文件服务器。

客户端配置:

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

[[proxies]]
name = "file_server"
type = "tcp"
remotePort = 6001

[proxies.plugin]
type = "static_file"
localPath = "/path/to/files"
stripPrefix = "static"
httpUser = "admin"
httpPassword = "admin"

访问方式:

http://x.x.x.x:6001/static/

场景六:私密服务(STCP)

使用预共享密钥保护服务,只有知道密钥的客户端才能访问。

服务提供方(机器 A)配置:

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

[[proxies]]
name = "secret_ssh"
type = "stcp"
secretKey = "your_secret_key"
localIP = "127.0.0.1"
localPort = 22

访问方(机器 B)配置:

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

[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh"
secretKey = "your_secret_key"
bindAddr = "127.0.0.1"
bindPort = 6000

在机器 B 上连接:

ssh -p 6000 127.0.0.1

场景七:P2P 模式(XTCP)

实现客户端之间的 P2P 直连,减少服务器流量消耗。

服务提供方配置:

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

[[proxies]]
name = "p2p_ssh"
type = "xtcp"
secretKey = "p2p_secret"
localIP = "127.0.0.1"
localPort = 22

访问方配置:

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

[[visitors]]
name = "p2p_ssh_visitor"
type = "xtcp"
serverName = "p2p_ssh"
secretKey = "p2p_secret"
bindAddr = "127.0.0.1"
bindPort = 6000
keepTunnelOpen = false

注意:P2P 模式可能不适用于所有类型的 NAT 设备。如果 XTCP 不工作,可以回退到 STCP 模式。

高级功能

负载均衡

多个客户端共享同一个端口,实现负载均衡。

客户端 1 配置:

[[proxies]]
name = "web1"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "your_group_key"

客户端 2 配置:

[[proxies]]
name = "web2"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "your_group_key"

健康检查

自动检测服务健康状态,故障时自动移除代理。

TCP 健康检查:

[[proxies]]
name = "web"
type = "tcp"
localPort = 8080
remotePort = 80
healthCheck.type = "tcp"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10

HTTP 健康检查:

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]
healthCheck.type = "http"
healthCheck.path = "/health"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10

带宽限制

限制单个代理的带宽使用。

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.bandwidthLimit = "1MB"
transport.bandwidthLimitMode = "client"

加密和压缩

启用传输加密和压缩。

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.useEncryption = true
transport.useCompression = true

URL 路由

根据 URL 路径将请求转发到不同的后端服务。

[[proxies]]
name = "web01"
type = "http"
localPort = 80
customDomains = ["web.example.com"]
locations = ["/"]

[[proxies]]
name = "web02"
type = "http"
localPort = 81
customDomains = ["web.example.com"]
locations = ["/api", "/admin"]

访问 /api/admin 的请求会转发到 web02,其他请求转发到 web01。

环境变量

在配置文件中使用环境变量。

serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}"
serverPort = 7000

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = {{ .Envs.FRP_SSH_REMOTE_PORT }}

使用方式:

export FRP_SERVER_ADDR=x.x.x.x
export FRP_SSH_REMOTE_PORT=6000
./frpc -c ./frpc.toml

热重载配置

frpc 支持热重载配置,无需重启进程。

首先在配置文件中启用 Web 服务器:

webServer.addr = "127.0.0.1"
webServer.port = 7400

修改配置后执行:

./frpc reload -c ./frpc.toml

验证配置:

./frpc verify -c ./frpc.toml

查看代理状态:

./frpc status -c ./frpc.toml

安全建议

1. 使用强认证令牌

auth.method = "token"
auth.token = "use_a_very_strong_random_token_here"

生成强随机令牌:

openssl rand -base64 32

2. 启用 TLS 加密

服务端配置:

transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"

客户端配置:

transport.tls.enable = true
transport.tls.trustedCaFile = "ca.crt"

3. 限制端口范围

在服务端限制客户端可以使用的端口:

allowPorts = [
  { start = 6000, end = 6100 }
]

4. 使用防火墙

在服务器上配置防火墙,只开放必要的端口:

# 允许 frps 端口
sudo ufw allow 7000/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 7500/tcp
sudo ufw enable

5. 定期更新

定期检查并更新到最新版本,以获得安全修复和新功能。

6. 监控和日志

启用日志记录,定期检查异常访问:

# 服务端日志配置
log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7

故障排查

客户端无法连接到服务端

  1. 检查服务端是否正常运行:

    sudo systemctl status frps
  2. 检查防火墙是否开放端口:

    sudo ufw status
  3. 检查认证令牌是否一致

  4. 查看日志:

    sudo journalctl -u frps -f
    sudo journalctl -u frpc -f

代理无法访问

  1. 检查端口是否被占用:

    netstat -tuln | grep 端口号
  2. 检查本地服务是否正常运行

  3. 检查 DNS 解析是否正确(HTTP/HTTPS 代理)

  4. 检查防火墙规则

连接不稳定

  1. 启用 KCP 或 QUIC 协议:

    transport.protocol = "kcp"
  2. 启用连接池:

    transport.poolCount = 5
  3. 调整心跳参数:

    transport.heartbeatInterval = 30
    transport.heartbeatTimeout = 90

性能问题

  1. 启用 TCP 多路复用:

    transport.tcpMux = true
  2. 禁用加密和压缩(如果不需要):

    transport.useEncryption = false
    transport.useCompression = false
  3. 使用 P2P 模式减少服务器负载

Web 管理界面

服务端 Dashboard

访问 http://服务器IP:7500,使用配置的用户名和密码登录。

Dashboard 功能:

客户端 Admin UI

在客户端配置中启用:

webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"

访问 http://127.0.0.1:7400 查看客户端状态。

Prometheus 监控

在服务端启用 Prometheus:

enablePrometheus = true

访问 http://服务器IP:7500/metrics 获取监控数据。

配置文件格式

frp 从 v0.52.0 开始支持 TOML、YAML 和 JSON 格式的配置文件。INI 格式已被弃用。

TOML 格式(推荐)

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

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

YAML 格式

serverAddr: x.x.x.x
serverPort: 7000

proxies:
  - name: ssh
    type: tcp
    localPort: 22
    remotePort: 6000

JSON 格式

{
  "serverAddr": "x.x.x.x",
  "serverPort": 7000,
  "proxies": [
    {
      "name": "ssh",
      "type": "tcp",
      "localPort": 22,
      "remotePort": 6000
    }
  ]
}

总结

frp 是一个功能强大且易于使用的内网穿透工具,适用于各种场景。本教程涵盖了从基础安装到高级配置的完整流程。建议根据实际需求选择合适的配置,并注意安全防护。

关键要点:

更多信息请参考:


内容基于 frp 官方文档改编,遵循 Apache License, Version 2.0。


Share this post on:

Previous Post
工作中常用的 Git 工作流完整指南
Next Post
Ubuntu 系统下 Docker 和 Docker Compose 完整安装指南