frp 内网穿透¶
一句话概述:frp 是开源的自建内网穿透工具(GitHub 90K+ Stars),你需要一台有公网 IP 的服务器(VPS)作为中转,然后家里/办公室的服务通过 frp 隧道暴露出去,完全自主可控,不依赖第三方。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| frps | frp 服务端,运行在有公网 IP 的 VPS 上 |
| frpc | frp 客户端,运行在你要暴露服务的内网机器上 |
| TCP 隧道 | 转发 TCP 流量(SSH、数据库、任意 TCP 服务) |
| HTTP 隧道 | 转发 HTTP 流量,支持按域名/路径路由 |
| STCP | 安全 TCP,需要密钥才能访问,不暴露在公网 |
| P2P(xtcp) | 点对点连接,流量不经过服务器(省带宽) |
| 面板 | frps 自带 Web 管理面板,查看连接状态 |
安装配置¶
下载安装¶
# 在 VPS(服务端)和内网机器(客户端)都要安装
# 从 GitHub 下载最新版
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
tar -xzf frp_0.61.0_linux_amd64.tar.gz # 解压
cd frp_0.61.0_linux_amd64 # 进入目录
# 文件说明
# frps → 服务端程序(放 VPS 上)
# frps.toml → 服务端配置
# frpc → 客户端程序(放内网机器上)
# frpc.toml → 客户端配置
服务端配置(VPS 上)¶
# frps.toml - 服务端配置
bindPort = 7000 # frp 通信端口(客户端连这个端口)
vhostHTTPPort = 80 # HTTP 虚拟主机端口
vhostHTTPSPort = 443 # HTTPS 虚拟主机端口
# Web 管理面板
webServer.addr = "0.0.0.0" # 面板监听地址
webServer.port = 7500 # 面板端口
webServer.user = "admin" # 面板用户名
webServer.password = "your_password" # 面板密码
# 认证(防止未授权连接)
auth.method = "token" # 认证方式
auth.token = "your_secret_token" # 认证令牌(客户端要配一样的)
# 启动服务端
./frps -c frps.toml # 前台运行(调试用)
# 作为 systemd 服务运行
sudo cp frps /usr/local/bin/ # 复制程序
sudo mkdir -p /etc/frp # 创建配置目录
sudo cp frps.toml /etc/frp/ # 复制配置
# /etc/systemd/system/frps.service
[Unit]
Description=frp Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload # 重新加载 systemd
sudo systemctl start frps # 启动
sudo systemctl enable frps # 开机自启
客户端配置(内网机器上)¶
# frpc.toml - 客户端配置
serverAddr = "你的VPS公网IP" # 服务端 IP
serverPort = 7000 # 服务端 frp 端口
auth.token = "your_secret_token" # 认证令牌(和服务端一致)
# 暴露 SSH
[[proxies]]
name = "ssh" # 隧道名称
type = "tcp" # TCP 类型
localIP = "127.0.0.1" # 本地 IP
localPort = 22 # 本地 SSH 端口
remotePort = 6022 # VPS 上暴露的端口(通过 VPS:6022 访问内网 SSH)
# 暴露 Web 服务
[[proxies]]
name = "web"
type = "http" # HTTP 类型
localPort = 3000 # 本地 Web 服务端口
customDomains = ["app.example.com"] # 自定义域名(需要 DNS 指向 VPS)
# 暴露 HTTPS 服务
[[proxies]]
name = "web-https"
type = "https"
localPort = 443
customDomains = ["secure.example.com"]
基本使用¶
场景一:远程 SSH¶
场景二:暴露 Web 应用¶
1. 本地启动 Web 应用(端口 3000)
2. frpc 配置 HTTP 代理,域名 app.example.com
3. DNS 将 app.example.com 指向 VPS IP
4. 访问 http://app.example.com → 自动转发到内网 3000 端口
查看管理面板¶
高级用法¶
STCP 安全隧道(不暴露端口)¶
# 服务端的 frpc.toml(提供服务的一方)
[[proxies]]
name = "secret_ssh"
type = "stcp" # 安全 TCP
secretKey = "my_secret_key" # 访问密钥
localIP = "127.0.0.1"
localPort = 22
# 客户端的 frpc.toml(访问服务的一方)
[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh" # 要访问的服务名
secretKey = "my_secret_key" # 相同的密钥
bindAddr = "127.0.0.1"
bindPort = 6022 # 本地端口
P2P 连接(xtcp)¶
# 点对点连接,流量不经过 VPS(需要 NAT 穿透成功)
[[proxies]]
name = "p2p_ssh"
type = "xtcp"
secretKey = "p2p_key"
localIP = "127.0.0.1"
localPort = 22
负载均衡¶
# 多个内网机器提供同一服务
[[proxies]]
name = "web-1"
type = "http"
localPort = 8080
customDomains = ["app.example.com"]
loadBalancer.group = "web" # 同组名实现负载均衡
loadBalancer.groupKey = "secret"
# 另一台机器的 frpc.toml
[[proxies]]
name = "web-2"
type = "http"
localPort = 8080
customDomains = ["app.example.com"]
loadBalancer.group = "web"
loadBalancer.groupKey = "secret"
常见报错¶
| 报错信息 | 原因 | 解决方案 |
|---|---|---|
login to server failed: token auth failed | Token 不匹配 | 客户端和服务端 token 要一致 |
port already used | 端口被占 | 换一个 remotePort |
connection refused | VPS 防火墙拦了 | 开放 frp 需要的端口 |
| 连上了但访问不了 | 本地服务没启动 | 确保 localPort 的服务在运行 |
| HTTP 访问 404 | 域名没配 DNS | 把域名的 DNS 指向 VPS IP |
| 断线不重连 | 客户端被杀了 | 用 systemd 管理,配置 Restart=always |
速查表¶
# 服务端
./frps -c frps.toml # 启动服务端
# 客户端
./frpc -c frpc.toml # 启动客户端
./frpc verify -c frpc.toml # 验证配置文件
./frpc reload -c frpc.toml # 热重载配置
# 代理类型
tcp # TCP 转发(SSH、数据库)
udp # UDP 转发(DNS、游戏)
http # HTTP 反向代理(Web 应用)
https # HTTPS 反向代理
stcp # 安全 TCP(需密钥,不暴露端口)
xtcp # P2P 连接(不经过服务器)
tcpmux # TCP 多路复用
# VPS 需要开放的端口
7000 # frp 通信端口
7500 # Web 面板端口
80/443 # HTTP/HTTPS(如果用 vhost)
自定义 # 各 TCP 隧道的 remotePort
参考:frp GitHub | frp 文档 | frp 最新版下载