FRP TLS 安全传输的配置指南

涵盖 默认加密、单向认证、双向认证(mTLS) 三种模式,以及证书生成方法。


一、TLS 默认行为(v0.50.0+)

v0.50.0 开始,frp 默认启用 TLS 加密:

  • frpc 默认开启 TLS 加密,但不校验 frps 证书
  • frps 若未配置证书,则使用随机生成的自签名证书加密流量

注意 :启用 TLS 后,除 xtcp 外,可以不用再设置 useEncryption 重复加密。


二、TLS 配置项对照表

配置项 作用域 类型 说明
transport.tls.force frps bool 强制只接受 TLS 连接的客户端。若 trustedCaFile 有效,会自动开启
transport.tls.certFile 双端 string TLS 证书文件路径
transport.tls.keyFile 双端 string TLS 私钥文件路径
transport.tls.trustedCaFile 双端 string 受信任的 CA 证书文件路径,用于验证对方身份
transport.tls.enable frpc bool 客户端显式启用 TLS(v0.50.0+ 默认 true)

三、三种 TLS 模式配置

3.1 模式一:默认 TLS 加密(不验证身份)

无需额外配置,frp 默认使用随机证书加密通信。适用于信任网络环境。

toml 复制代码
# frps.toml - 无需额外 TLS 配置
bindPort = 7000

# frpc.toml - 无需额外 TLS 配置
serverAddr = "x.x.x.x"
serverPort = 7000

3.2 模式二:frpc 单向校验 frps 身份

frpc 验证 frps 的服务器证书,防止中间人攻击。

toml 复制代码
# ========== frps.toml ==========
bindPort = 7000

# frps 提供 TLS 证书
transport.tls.certFile = "/etc/frp/ssl/server.crt"
transport.tls.keyFile = "/etc/frp/ssl/server.key"

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

# frpc 通过 CA 验证 frps 证书
transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"

原理 :frpc 使用 ca.crt 验证 frps 的 server.crt 是否由可信 CA 签发,且服务器域名/IP 需在证书的 SAN 中。


3.3 模式三:双向 TLS 认证(mTLS)⭐ 推荐

frpc 和 frps 互相验证对方身份,安全性最高,适合生产环境。

toml 复制代码
# ========== frps.toml ==========
bindPort = 7000

# 强制 TLS + 服务端证书
transport.tls.force = true
transport.tls.certFile = "/etc/frp/ssl/server.crt"
transport.tls.keyFile = "/etc/frp/ssl/server.key"

# 验证客户端证书
transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"

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

# 客户端证书
transport.tls.certFile = "/etc/frp/ssl/client.crt"
transport.tls.keyFile = "/etc/frp/ssl/client.key"

# 验证服务端证书
transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"

关键点:理论上 frpc 和 frps 的 CA 证书可以不同,只要能验证对方身份即可。但实际部署建议使用同一 CA 签发。


四、证书生成完整脚本(OpenSSL)

4.1 创建 OpenSSL 配置文件

bash 复制代码
cat > my-openssl.cnf << 'EOF'
[ ca ]
default_ca = CA_default

[ CA_default ]
x509_extensions = usr_cert

[ req ]
default_bits = 2048
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only

[ req_distinguished_name ]

[ req_attributes ]

[ usr_cert ]
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
EOF

4.2 生成 CA 根证书

bash 复制代码
# 生成 CA 私钥
openssl genrsa -out ca.key 2048

# 生成自签名 CA 证书(有效期约13年)
openssl req -x509 -new -nodes -key ca.key \
  -subj "/CN=example.ca.com" \
  -days 5000 -out ca.crt

4.3 生成服务端证书

⚠️ 服务端证书必须包含 SAN(Subject Alternative Name),否则客户端校验会失败。

bash 复制代码
# 1. 生成服务端私钥
openssl genrsa -out server.key 2048

# 2. 生成证书签名请求(CSR),替换为你的服务器 IP 和域名
openssl req -new -sha256 -key server.key \
  -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=server.com" \
  -reqexts SAN \
  -config <(cat my-openssl.cnf \
    <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:你的服务器公网IP,DNS:example.server.com")) \
  -out server.csr

# 3. 使用 CA 签发服务端证书
openssl x509 -req -days 3650 -sha256 \
  -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -extfile <(printf "subjectAltName=DNS:localhost,IP:你的服务器公网IP,DNS:example.server.com") \
  -out server.crt

4.4 生成客户端证书

bash 复制代码
# 1. 生成客户端私钥
openssl genrsa -out client.key 2048

# 2. 生成 CSR
openssl req -new -sha256 -key client.key \
  -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=client.com" \
  -reqexts SAN \
  -config <(cat my-openssl.cnf \
    <(printf "\n[SAN]\nsubjectAltName=DNS:client.com,DNS:example.client.com")) \
  -out client.csr

# 3. 使用 CA 签发客户端证书
openssl x509 -req -days 365 -sha256 \
  -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \
  -out client.crt

4.5 最终文件清单

文件 用途 部署位置
ca.crt 根证书 frps + frpc 的 trustedCaFile
ca.key CA 私钥 仅用于签发,不部署到任何端
server.crt + server.key 服务端证书 frps 的 certFile / keyFile
client.crt + client.key 客户端证书 frpc 的 certFile / keyFile

重要ca.key 是 CA 私钥,绝对不能放到 frps 或 frpc 上,仅用于签发证书。


五、Dashboard HTTPS 证书(独立配置)

Dashboard 的 HTTPS 与传输层 TLS 是两套独立配置:

bash 复制代码
# frps.toml - Dashboard 启用 HTTPS
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"

# Dashboard 专用 TLS 证书(可以是 Let's Encrypt 等公网证书)
webServer.tls.certFile = "/path/to/dashboard.crt"
webServer.tls.keyFile = "/path/to/dashboard.key"

六、Windows 路径注意事项

Windows 系统配置证书路径时,反斜杠需转义:

bash 复制代码
# ❌ 错误
transport.tls.certFile = "C:\Users\test\server.crt"

# ✅ 正确
transport.tls.certFile = "C:\\Users\\test\\server.crt"

七、完整生产环境配置示例

frps.toml(服务端)

bash 复制代码
bindAddr = "0.0.0.0"
bindPort = 7000

# 认证
auth.method = "token"
auth.token = "your-strong-token-here"

# 强制 TLS + 双向认证
transport.tls.force = true
transport.tls.certFile = "/etc/frp/ssl/server.crt"
transport.tls.keyFile = "/etc/frp/ssl/server.key"
transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"

# Dashboard
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your-dashboard-password"

# 日志
log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7

frpc.toml(客户端)

bash 复制代码
serverAddr = "your-server-ip"
serverPort = 7000

# 认证
auth.method = "token"
auth.token = "your-strong-token-here"

# TLS 双向认证
transport.tls.enable = true
transport.tls.certFile = "/etc/frp/ssl/client.crt"
transport.tls.keyFile = "/etc/frp/ssl/client.key"
transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"

# 代理示例
[[proxies]]
name = "web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 8080

八、常见问题排查

错误 原因 解决
certificate signed by unknown authority CA 证书不匹配或未被信任 确认 trustedCaFile 指向正确的 ca.crt
ERR_SSL_UNRECOGNIZED_NAME_ALERT 服务端证书 SAN 不包含连接地址 确保证书 SAN 包含服务器 IP 或域名
open /path/ca.key: no such file 误将 ca.key 配置为 trustedCaFile trustedCaFile 应配置 ca.crt,不是 ca.key
session shutdown 证书验证失败或 TLS 配置不匹配 检查双端 TLS 配置是否对应,证书是否过期

参考:GitHub Issue #4463 和 #4812 中详细讨论了证书配置问题。


九、参考来源

相关推荐
科力锐品牌君13 小时前
医院数据存储“乱象”:如何兼顾兼容、高效与合规?
大数据·安全·备份·存储·存储方案
长风23014 小时前
Day 17: 突破 AOB 框架霸权 —— 插件界面重构与大屏呈现
人工智能·安全
chenyulin454515 小时前
企业微信API:海量会话存档数据的高性能检索与Elasticsearch索引设计
大数据·人工智能·安全·企业微信
启雀AI1 天前
生物医疗行业如何建设合规、安全、可复用的知识库?
人工智能·安全·软件构建·知识图谱·知识库
Sirius Wu1 天前
OpenClaw Skill:Matplotlib 可视化技能 + 沙箱双层隔离完整详解
服务器·网络·人工智能·安全·ai·架构·aigc
冬奇Lab1 天前
每日一个开源项目(第160篇):Destructive Command Guard - 在 AI Agent 运行 rm -rf 之前拦截它
人工智能·安全·开源
ChainSafeAI0021 天前
Summer.fi 遭600万美元漏洞攻击,安全警报拉响
安全
一勺菠萝丶1 天前
生产环境平滑升级实战-Nginx维护页数据库迁移与安全回滚
数据库·nginx·安全
味悲1 天前
搭建WAF+宝塔反向代理
安全
BenSmith1 天前
RTOS漏洞分析:CVE-2026-10641和CVE-2026-9263
安全