跳到正文

frp.sh / 使用文档

部署信令服务器 ​

0.5.0:公网监听必须有非空密码。systemd 示例需先创建仅 root 可读的 /etc/frp-sh/server.env,设置 FRPSH_SERVE_PASSWORD。信令请使用 HTTPS。

服务器在内存中保存房间注册信息、交换地址并提供兜底中继,重启会清空房间。CPU、内存和公网带宽需求取决于活跃房间、轮询频率及中继流量,应通过压测确定,不保证固定空闲内存或承载人数。

快速启动 ​

bash
./frp-sh serve --addr 0.0.0.0:8080 --relay-addr 0.0.0.0:8081 --password "$FRPSH_SERVE_PASSWORD"

永久空间与成员中继 ​

启用永久空间时,设置服务器密码、私有 SQLite 路径和用户可访问的 HTTPS 来源。--spaces-origin 必须是实际公开来源;反向代理必须透传 WebSocket Upgrade,成员才能连接 wss://…/spaces/v1/<SPACE_ID>/relay。

bash
./frp-sh serve \
  --addr 127.0.0.1:8080 \
  --relay-addr 0.0.0.0:8081 \
  --password "$FRPSH_SERVE_PASSWORD" \
  --spaces-db /var/lib/frp-sh/spaces.sqlite \
  --spaces-origin https://frp.sh \
  --invite-ttl 900 \
  --invite-max-ttl 86400

SQLite 文件及其父目录应只允许服务账户访问。动态邀请码只以摘要写入数据库;默认有效期 900 秒,服务端可在 1 秒至 24 小时之间设定默认和上限。

自定义域名入口 ​

域名控制面和 HTTP ingress 使用独立 SQLite 与 loopback 监听:

bash
./frp-sh serve \
  --addr 127.0.0.1:8080 \
  --relay-addr 0.0.0.0:8081 \
  --password "$FRPSH_SERVE_PASSWORD" \
  --domains-db /var/lib/frp-sh/domains.sqlite \
  --domains-origin https://control.test.frp.sh:18443 \
  --ingress-addr 127.0.0.1:8082 \
  --ingress-cname edge.test.frp.sh \
  --ingress-https-port 18443
参数说明
--domains-db域名所有权与验证状态数据库;设置后启用域名 API
--domains-origin客户端签名绑定的公开 HTTPS 控制面来源,必须与实际访问地址一致
--ingress-addr只供 TLS 网关访问的 HTTP ingress,建议监听 loopback
--ingress-cnamebind 返回给用户的稳定 DNS 目标
--ingress-https-portbind 返回给用户的公开 HTTPS 端口

Caddy 必须把 /domains/v1/* 仅在控制域名上转发到 8080,把用户域名流量转发到 8082。按需 TLS 必须配置 ask http://127.0.0.1:8080/domains/v1/allow;否则任意 SNI 都会消耗证书签发配额。平台通配符证书与未知用户域名要使用独立 TLS 策略,完整可复制配置见仓库 ops/caddy/Caddyfile.example。

业务访问使用 18443,但 Caddy 还必须监听公网 TCP 443,供 ACME TLS-ALPN 验证。若云安全组未开放 443,首次用户域名访问无法签发证书。HTTP 80 不是签发依赖,可以关闭;中国大陆未备案入口可能在到达服务器前被运营商拦截。

SQLite 目录只允许服务账户访问。TXT 验证令牌只保存 SHA-256 摘要;Caddy 的 ask 只对已验证绑定返回成功。入口有固定请求/响应大小、等待时间和总并发上限,但公益部署仍应在网关或云侧增加带宽预算、连接速率限制和流量监控。

参数默认值说明
--addr0.0.0.0:8080HTTP REST 监听地址(UDP 公网探测复用同一端口)
--relay-addr0.0.0.0:8081私有 TCP 中继监听地址(打洞/TURN 都失败后的兜底)
--password无服务器密码(信令 401 校验 + 中继认证加密)
--turn关闭内置 TURN 监听地址(如 0.0.0.0:3478,RFC 5766 UDP 子集)
--external-ip监听地址 IP对外公网 IP(NAT/Docker 后部署 TURN 时必填)

systemd 常驻服务(推荐) ​

创建 /etc/systemd/system/frp-sh.service:

ini
[Unit]
Description=frp-sh signaling server
After=network.target

[Service]
EnvironmentFile=/etc/frp-sh/server.env
ExecStart=/opt/frpsh/target/release/frp-sh serve --addr 0.0.0.0:8080 --relay-addr 0.0.0.0:8081 --password ${FRPSH_SERVE_PASSWORD}
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

启用并启动:

bash
systemctl daemon-reload
systemctl enable frp-sh
systemctl start frp-sh
systemctl status frp-sh

验证监听:

bash
ss -lntup | grep -E ':8080|:8081'
# 应看到 8080/tcp、8080/udp、8081/tcp 三个监听

防火墙放行 ​

需要放行三个端口:

端口协议用途
8080TCPHTTP REST
8080UDP公网地址探测
8081TCP中继转发
bash
# ufw
ufw allow 8080/tcp
ufw allow 8080/udp
ufw allow 8081/tcp

# 或 iptables
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
iptables -I INPUT -p udp --dport 8080 -j ACCEPT
iptables -I INPUT -p tcp --dport 8081 -j ACCEPT

云厂商(腾讯云/阿里云等)的安全组也需要放行,且必须包含 UDP 8080——漏掉 UDP 会导致客户端公网探测失败,表现为 UDP echo timed out。

内置 TURN 中继(可选) ​

打洞失败时,默认走服务器私有 TCP 中继。也可以启用内置 TURN 服务器(RFC 5766), 让客户端经 UDP 中继而不是 TCP 中继,穿透性更好、与标准 STUN/TURN 生态兼容:

bash
./frp-sh serve --addr 0.0.0.0:8080 --relay-addr 0.0.0.0:8081 \
  --password 你的密码 --turn 0.0.0.0:3478 --external-ip 你的公网IP
说明值
TURN 用户名frp-sh(固定)
TURN 密码与 --password 一致
Realmfrp.sh
客户端配置在 turn_providers 中填写私有 TURN 地址

为什么需要 --external-ip:TURN 服务器通告的 relay 地址取自监听地址的 IP; 在 NAT / Docker 后面(如监听 0.0.0.0 时自动取到 172.17.0.x 这类内网地址), 必须显式指定公网 IP,客户端才能连到 relay 端口。

防火墙/安全组:TURN 需要额外放行 3478/udp(STUN/TURN 控制端口), 以及分配给客户端的 relay 端口段。relay 端口是每个客户端随机分配的(高位端口), 建议放行一段 UDP(如 50000-50100/udp)或直接放行全部 UDP 入站。

bash
ufw allow 3478/udp
ufw allow 50000:50100/udp

systemd 常驻示例(含 TURN):

ini
ExecStart=/opt/frpsh/target/release/frp-sh serve --addr 0.0.0.0:8080 --relay-addr 0.0.0.0:8081 --password 你的密码 --turn 0.0.0.0:3478 --external-ip 你的公网IP

客户端验证(配置了 turn_providers 后):

text
>>> UDP hole punching failed, trying TURN relay     # 打洞失败自动切 TURN

也可以用任意标准 TURN 客户端(coturn turnutils_uclient 等)直接连通性测试。

从本机验证服务可用 ​

bash
# HTTP
curl http://服务器IP:8080/health
# → ok

# UDP 探测(Linux 下可用 nc 或任意 UDP 客户端)
# 期望返回 ADDR <token> <你的公网IP>:<端口>

日志与排障 ​

使用 frp-sh logs path 查找当前账户的日志目录,frp-sh logs tail --follow 查看 JSONL 诊断记录。每个进程独立文件,单文件 5 MiB,保留三份轮转;清理时跳过存活进程。没有 HTTP 日志接口。服务部署应为运行账户设置固定 HOME。

与既有服务共存 ​

服务器上的其他服务(如 8000/8765 等端口)不受影响;如需换端口,改 --addr/--relay-addr 并在客户端配置中对应修改即可。

多服务器(可选) ​

兼容实现必须遵循协议 v3 的认证、帧格式和资源限制,见协议。可部署多个实例,让客户端分别配置对应服务器。

安全建议 ​

  • 信令 HTTP 未内置 TLS:公网部署建议置于 Nginx/Caddy 反向代理之后(HTTPS 终结)
  • 中继传输加密使用服务器或房间凭据,不代表对中继运营者保密。服务房间可通过共同的 --key 增加端到端负载加密。
  • 房间号是标识符,不是访问凭证。保护房间邀请和服务器凭据,按需限制监听端口的来源。

公益服务器容量限制(0.5.4 起) ​

在原有 serve 启动参数后追加,例如:

bash
--max-rooms 20 --max-members 8 --max-total-members 100
参数默认值范围 / 含义
--max-rooms10241–1024 个未到期房间
--max-members33每房间 2–33 台登记设备,包含房主
--max-total-members33792全服 1–33792 个成员名额,包含所有房主

三个限制同时生效,由服务器强制校验,客户端不能提高上限。满额后创建或加入返回 HTTP 429;已登记设备使用相同 UUID 重连不增加计数,满员时仍可重连。同一设备加入不同房间分别占用名额。

这是登记容量,不是实时在线人数:暂时断线不释放名额,房间删除或过期后释放。修改 systemd 的 ExecStart 后执行 systemctl daemon-reload 和 systemctl restart frp-sh 生效;重启会清空内存房间,已有连接需要重新创建/加入。/version 的 limits 字段可核对当前设置。

容量限制不等于带宽限速或流量配额;中继带宽仍需单独管理。

frp-sh · 社交化 P2P 打洞工具