什么是 frp

一句话概括

frp(Fast Reverse Proxy)是一个开源的内网穿透工具,让你把藏在内网(家里、公司)的服务暴露到公网,外面的人也能访问。

解决什么问题

你在家里的 Mac 上跑了一个 AI 服务,想让朋友通过网址访问。但问题是:

markdown 复制代码
你的 Mac(内网 IP: 192.168.1.100)
  → 路由器(NAT)
    → 运营商(大概率没有公网 IP)
      → 互联网

朋友根本没法直接连到你的 Mac

frp 的作用就是在中间架一座桥:

markdown 复制代码
你的 Mac ──frpc──→ 公网服务器(frps) ←── 朋友访问
          主动连出        被动接入

frpc(客户端)从内网主动连接到公网服务器上的 frps(服务端),建立一条隧道。外部用户访问公网服务器的某个端口,流量就通过隧道转发到你的内网服务。

核心概念

frps(服务端)

运行在有公网 IP 的服务器上,负责:

  • 监听端口,等待 frpc 连接
  • 接收外部用户的请求
  • 通过隧道转发到 frpc

frpc(客户端)

运行在你的内网机器上,负责:

  • 主动连接 frps,建立隧道
  • 接收 frps 转发过来的请求
  • 把请求转发给本地服务

关键:是 frpc 主动连出去

这就是为什么 frp 能穿透内网 ------ 内网机器无法被外部访问,但可以主动向外发起连接。frpc 主动连接 frps,建立一条长连接隧道,后续流量就通过这条隧道双向传输。

安装

服务端(公网服务器,Linux)

bash 复制代码
# 下载最新版 (以 v0.61.1 为例)
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
tar -xzf frp_0.61.1_linux_amd64.tar.gz
cd frp_0.61.1_linux_amd64

# 里面有两个二进制文件:
# frps - 服务端
# frpc - 客户端

客户端(Mac)

bash 复制代码
brew install frpc

或者直接下载 macOS 版本解压使用。

配置与使用

最简配置:暴露一个 TCP 端口

服务端 frps.toml

toml 复制代码
bindPort = 7000              # frps 监听的端口,frpc 连这个

auth.method = "token"
auth.token = "your-password" # 认证密码,两端必须一致

启动:

bash 复制代码
./frps -c frps.toml

客户端 frpc.toml

toml 复制代码
serverAddr = "45.207.210.130"  # 公网服务器 IP
serverPort = 7000

auth.method = "token"
auth.token = "your-password"

[[proxies]]
name = "my-web"          # 代理名称,随便起
type = "tcp"             # 协议类型
localIP = "127.0.0.1"   # 本地服务地址
localPort = 3000         # 本地服务端口
remotePort = 6100        # 公网暴露的端口

启动:

bash 复制代码
frpc -c frpc.toml

效果 :访问 45.207.210.130:6100 = 访问你本地的 127.0.0.1:3000

多个服务同时穿透

一个 frpc 可以同时穿透多个服务,添加多个 [[proxies]] 即可:

toml 复制代码
serverAddr = "45.207.210.130"
serverPort = 7000
auth.method = "token"
auth.token = "your-password"

[[proxies]]
name = "ai-chat"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3000
remotePort = 6100

[[proxies]]
name = "my-blog"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 8080

[[proxies]]
name = "ssh-access"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6022

这样公网服务器上就有三个端口分别映射到你本地的三个服务。

HTTP 类型代理(支持域名)

除了 TCP 直接转发,frp 还支持 HTTP 类型,可以通过域名区分不同服务,共用 80 端口:

服务端额外配置

toml 复制代码
bindPort = 7000
vhostHTTPPort = 80       # HTTP 代理监听的端口

客户端

toml 复制代码
[[proxies]]
name = "ai-web"
type = "http"
localPort = 3000
customDomains = ["ai.yourdomain.com"]  # 通过域名区分

[[proxies]]
name = "blog-web"
type = "http"
localPort = 8080
customDomains = ["blog.yourdomain.com"]

把这两个域名的 DNS 都指向公网服务器,frps 会根据请求的域名把流量转发到不同的本地服务。

完整数据流

以本项目为例,一个请求的完整路径:

markdown 复制代码
1. 用户发起请求
   curl http://45.207.210.130:6100/chat

2. 到达公网服务器
   frps 监听 6100 端口,收到请求

3. frps 查找映射
   端口 6100 → 隧道 "gemma4-chat" → frpc

4. 通过隧道转发
   frps ──长连接隧道──→ frpc

5. frpc 转发到本地
   frpc → host.docker.internal:3000 → chat-api 容器

6. chat-api 处理请求
   chat-api → Ollama(localhost:11434) → Gemma4 推理

7. 原路返回
   Gemma4 结果 → chat-api → frpc → frps → 用户

在 Docker 中运行 frpc

如果你用 OrbStack/Docker 管理服务,frpc 也可以容器化:

yaml 复制代码
# docker-compose.yml
services:
  frpc:
    image: snowdreamtech/frpc:latest
    container_name: frpc
    volumes:
      - ./frpc.toml:/etc/frp/frpc.toml
    restart: unless-stopped

注意 :frpc 在容器中运行时,localIP 不能写 127.0.0.1(那是容器自身),要写 host.docker.internal(指向 Mac 宿主机):

toml 复制代码
[[proxies]]
name = "my-service"
type = "tcp"
localIP = "host.docker.internal"  # 不是 127.0.0.1
localPort = 3000
remotePort = 6100

用 systemd 保持后台运行

服务端(Linux)

bash 复制代码
sudo tee /etc/systemd/system/frps.service << 'EOF'
[Unit]
Description=frp server
After=network.target

[Service]
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now frps

客户端(Mac,使用 launchd)

bash 复制代码
cat > ~/Library/LaunchAgents/com.frpc.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.frpc</string>
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/bin/frpc</string>
        <string>-c</string>
        <string>/path/to/frpc.toml</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

launchctl load ~/Library/LaunchAgents/com.frpc.plist

安全注意事项

1. 必须设置认证

没有认证的 frps 任何人都能连上来穿透,相当于把你的服务器当成公共代理:

toml 复制代码
# frps.toml 和 frpc.toml 都要配置
auth.method = "token"
auth.token = "一个足够复杂的密码"

2. 防火墙只开必要端口

bash 复制代码
# 服务器上只开放需要的端口
sudo ufw allow 7000    # frps 通信端口
sudo ufw allow 6100    # gemma4-chat 暴露端口
# 不要 ufw allow 1-65535

3. 搭配 Nginx + HTTPS

不要让用户直接访问 IP:端口,用 Nginx 套一层域名和 SSL:

scss 复制代码
用户 → Nginx(443/HTTPS) → frps(6100) → frpc → 本地服务

4. 不要暴露敏感服务

数据库(3306、5432)、SSH(22)等服务尽量不要穿透到公网,如果必须穿透 SSH,建议改端口并使用密钥登录。

常见问题

Q: frpc 连不上 frps

检查清单:

  1. 服务器防火墙是否放行了 bindPort(默认 7000)
  2. frps 是否正在运行:ps aux | grep frps
  3. 两端的 auth.token 是否一致
  4. serverAddr 是否填对
bash 复制代码
# 测试端口连通性
telnet 45.207.210.130 7000

Q: 穿透成功但访问超时

  • 检查本地服务是否真的在运行
  • 检查 localIPlocalPort 是否正确
  • 如果 frpc 在容器中,确认用了 host.docker.internal

Q: 速度慢

frp 本身只是转发,速度取决于:

  • 公网服务器的带宽
  • 你家里的上行带宽
  • 服务器和你之间的网络延迟

Q: frpc 断线后能自动重连吗

能。frpc 内置了断线重连机制,如果网络中断会自动重新连接。用 Docker 的 restart: unless-stopped 或 systemd 的 Restart=always 可以保证进程级别的持续运行。

总结

概念 说明
frp 是什么 内网穿透工具,把内网服务暴露到公网
frps 服务端,跑在有公网 IP 的服务器上
frpc 客户端,跑在你的内网机器上
原理 frpc 主动连接 frps 建立隧道,流量双向传输
前提 你需要一台有公网 IP 的服务器

一句话总结:frp 就是让你在家里跑服务,全世界都能访问。

相关推荐
两万五千个小时6 小时前
Claude Code 源码:Agent 工具 — 多 Agent 的路由与定义机制
人工智能·程序员·架构
程序员鱼皮7 小时前
SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程
ai·程序员·开源·编程·ai编程
程序员cxuan8 小时前
今天看到很多人讨论 Linux 终于要接受 AI 提交的代码了,我的第一反应是,真的吗?作为喷 AI 最狠的祖师爷到底咋看这件事儿?
后端·程序员
阿里嘎多学长11 小时前
2026-04-12 GitHub 热点项目精选
开发语言·程序员·github·代码托管
人邮异步社区12 小时前
为什么需要学习计算机组成原理?
程序员·计算机系统·计算机原理
拥抱AGI13 小时前
Qwen3.5开源矩阵震撼发布!从0.8B到397B,不同规模模型性能、显存、速度深度对比与选型指南来了!
人工智能·学习·程序员·开源·大模型·大模型训练·qwen3.5
SimonKing13 小时前
大V说’AI替代不了你’,但现实是——用AI的人正在替代你
java·后端·程序员