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 中详细讨论了证书配置问题。


九、参考来源

相关推荐
Magic-ZYJ8 小时前
HarmonyOS Release 构建安全:ArkGuard 混淆、签名配置与秘密管理
安全·华为·harmonyos·移动应用开发·心晴手记
Delite8028 小时前
开口闪点检测智能化升级:工业油品安全检测的标准化解决方案
大数据·人工智能·安全
x868 小时前
Rust 供应链投毒实录:arrayref 0.3.10 借冒名 proc-macro1 在编译期执行远程载荷
安全
DianSan_ERP10 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
数据知道10 小时前
漏洞挖掘方法论:从 Fuzz 到 0day 的思维框架
网络·安全·web安全·网络安全
BvxiE11 小时前
流量分析题目整合
安全
志栋智能11 小时前
从安全超自动化到超自动化安全的认知飞跃
运维·安全·自动化
网安小学生(兼顾数据库版)12 小时前
Mend SCA 实操指南:使用 Mend CLI 进行开源组件安全扫描
安全·开源
山东科恩光电13 小时前
穆柯密佑MKL-01光敏传感器为橡塑生产安全编织新防护网
安全
论迹复利14 小时前
蓝牙加密算法演进——E0 流密码到 AES-CCM 的迁移路径与安全对比
安全·加密·stack·bt