FRP TLS 证书配置超详细教程
前言
FRP(Fast Reverse Proxy)是一款常用的反向代理工具,而TLS 证书配置能让 FRP 的通信全程加密,避免明文传输带来的安全风险,同时也能防止数据被篡改、窃听。本教程结合实际操作场景,用通俗易懂的语言拆解证书生成和服务端 / 客户端配置全流程,跟着步骤做就能完成部署。
一、环境与准备工作
1. 必备条件
-
操作系统:Linux(服务端 / 客户端均适用,本教程以 Linux 为例)
-
工具:
openssl(Linux 系统一般自带,若未安装可执行yum install openssl或apt install openssl安装) -
网络信息:
- 服务端(FRP-Server)公网 IP:
47.106.206.xxx - 客户端(FRP-Client)内网 IP:
192.168.1.xxx
- 服务端(FRP-Server)公网 IP:
-
目录规划:统一创建证书存放目录,避免后续路径错误,执行以下命令:
bash运行
# 创建FRP主目录及证书子目录 mkdir -p /etc/frp/ssl # 赋予目录合适权限(避免权限不足导致读取失败) chmod 700 /etc/frp/ssl
2. 核心概念说明
- CA 证书:自签的根证书,用于签发服务端 / 客户端的证书,相当于 “信任的源头”。
- 服务端证书 / 私钥:FRP 服务端用于证明自身身份、加密通信的文件。
- 客户端证书 / 私钥:FRP 客户端用于身份验证、加密通信的文件。
- SAN(Subject Alternative Name):证书支持的备用域名 / IP,必须配置,否则客户端 / 服务端会因证书验证失败无法连接。
二、第一步:生成 TLS 证书(核心步骤)
我们采用自签 CA 证书的方式生成所需文件(生产环境可使用 Let's Encrypt 等第三方 CA,步骤类似),全程在 /etc/frp/ssl目录下操作。
1. 生成证书配置文件
分别创建客户端(frpc.cnf)和服务端(frps.cnf)的证书配置文件,用于指定证书的主体信息和 SAN 字段,直接复制以下命令执行即可:
(1)生成客户端配置文件(frpc.cnf)
bash
运行
cat > /etc/frp/ssl/frpc.cnf << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = Frp
CN = frp-client
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
IP.1 = 192.168.1.xxx
EOF
配置项解释:
C:国家代码,CN代表中国;ST/L:省份 / 城市,这里填北京;O:组织名称,自定义即可;CN:客户端通用名称,填frp-client;IP.1:客户端内网 IP,必须与实际客户端 IP 一致。
(2)生成服务端配置文件(frps.cnf)
bash
运行
cat > /etc/frp/ssl/frps.cnf << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = Frp
CN = frp-server
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
IP.1 = 47.106.206.xxx
EOF
配置项解释:
- 与客户端配置类似,
CN填frp-server,IP.1填服务端公网 IP。
2. 生成 CA 根证书(核心信任源)
先生成 CA 私钥,再用私钥签发 CA 证书,有效期设为 10 年(-days 3650),执行以下命令:
bash
运行
# 1. 生成CA私钥(frp_ca.key),权限设为600(仅root可读写)
openssl genrsa -out /etc/frp/ssl/frp_ca.key 2048
chmod 600 /etc/frp/ssl/frp_ca.key
# 2. 用CA私钥签发CA根证书(frp_ca.crt)
openssl req -x509 -new -nodes \
-key /etc/frp/ssl/frp_ca.key \
-subj "/CN=frp-ca" \
-days 3650 \
-out /etc/frp/ssl/frp_ca.crt
命令解释:
-x509:生成自签证书格式;-new:生成新的证书请求;-nodes:不加密私钥(生产环境可加密,需额外输入密码);-subj:直接指定证书主体信息,无需交互式输入。
3. 生成服务端证书与私钥
(1)生成服务端私钥(frps.key)
bash
运行
openssl genrsa -out /etc/frp/ssl/frps.key 2048
chmod 600 /etc/frp/ssl/frps.key
(2)生成服务端证书请求(frps.csr)
bash
运行
openssl req -new -sha256 \
-key /etc/frp/ssl/frps.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Frp/CN=frp-server" \
-config /etc/frp/ssl/frps.cnf \
-extensions v3_req \
-out /etc/frp/ssl/frps.csr
(3)用 CA 证书签发服务端证书(frps.crt)
bash
运行
openssl x509 -req -days 3650 -sha256 \
-in /etc/frp/ssl/frps.csr \
-CA /etc/frp/ssl/frp_ca.crt \
-CAkey /etc/frp/ssl/frp_ca.key \
-CAcreateserial \
-extfile /etc/frp/ssl/frps.cnf \
-extensions v3_req \
-out /etc/frp/ssl/frps.crt
关键参数:
-CAcreateserial:自动生成 CA 序列号文件,避免重复签发证书冲突;-extfile/-extensions:加载之前配置的 SAN 字段,确保证书支持服务端 IP。
4. 生成客户端证书与私钥
(1)生成客户端私钥(frpc.key)
bash
运行
openssl genrsa -out /etc/frp/ssl/frpc.key 2048
chmod 600 /etc/frp/ssl/frpc.key
(2)生成客户端证书请求(frpc.csr)
bash
运行
openssl req -new -sha256 \
-key /etc/frp/ssl/frpc.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Frp/CN=frp-client" \
-config /etc/frp/ssl/frpc.cnf \
-extensions v3_req \
-out /etc/frp/ssl/frpc.csr
(3)用 CA 证书签发客户端证书(frpc.crt)
bash
运行
openssl x509 -req -days 3650 -sha256 \
-in /etc/frp/ssl/frpc.csr \
-CA /etc/frp/ssl/frp_ca.crt \
-CAkey /etc/frp/ssl/frp_ca.key \
-CAcreateserial \
-extfile /etc/frp/ssl/frpc.cnf \
-extensions v3_req \
-out /etc/frp/ssl/frpc.crt
5. 验证证书 SAN 配置(必做!)
执行以下命令,确保证书的 SAN 字段已正确配置(显示客户端 / 服务端 IP 即成功):
bash
运行
# 验证服务端证书SAN
openssl x509 -in /etc/frp/ssl/frps.crt -text -noout | grep -A 2 "Subject Alternative Name"
# 验证客户端证书SAN
openssl x509 -in /etc/frp/ssl/frpc.crt -text -noout | grep -A 2 "Subject Alternative Name"
正常输出示例:
plaintext
X509v3 Subject Alternative Name:
IP Address:47.106.206.xxx
(客户端输出对应客户端 IP,无输出则说明 SAN 配置失败,需重新检查 frpc.cnf/frps.cnf)
三、第二步:FRP 服务端(frps)配置
服务端配置核心是开启 TLS 强制加密、配置证书路径、设置身份认证,以下是完整的 frps.toml配置(若原文件存在,可直接替换或追加内容):
1. 完整配置示例
toml
# ==================== 基础监听配置 ====================
# 服务端绑定地址(0.0.0.0表示监听所有网卡,允许公网访问)
bindAddr = "0.0.0.0"
# 服务端代理通信端口(自定义,需开放防火墙)
bindPort = 17000
# ==================== 身份认证配置 ====================
# 认证方式:token(令牌认证,简单高效)
auth.method = "token"
# 自定义令牌(需与客户端一致,建议设置复杂字符串)
auth.token = "frptoken"
# ==================== 监控面板配置(可选) ====================
# 监控面板监听地址
webServer.addr = "0.0.0.0"
# 监控面板端口(自定义,需开放防火墙)
webServer.port = 17001
# 监控面板账号密码
webServer.user = "admin"
webServer.password = "admin"
# ==================== TLS证书核心配置 ====================
# 强制开启TLS加密(客户端必须使用TLS连接,缺一不可)
transport.tls.force = true
# 服务端证书文件路径
transport.tls.certFile = "/etc/frp/ssl/frps.crt"
# 服务端私钥文件路径
transport.tls.keyFile = "/etc/frp/ssl/frps.key"
# 信任的CA证书路径(用于验证客户端证书合法性)
transport.tls.trustedCaFile = "/etc/frp/ssl/frp_ca.crt"
2. 关键配置说明
| 配置项 | 作用 | 注意事项 |
|---|---|---|
transport.tls.force = true |
强制服务端仅接受 TLS 加密连接 | 必须开启,否则客户端明文连接会被拒绝 |
transport.tls.certFile/keyFile |
指定服务端证书 / 私钥路径 | 必须与实际生成的文件路径一致 |
transport.tls.trustedCaFile |
指定 CA 证书路径 | 用于验证客户端证书,必须是之前生成的 frp_ca.crt |
auth.token |
身份认证令牌 | 必须与客户端 auth.token完全一致 |
四、第三步:FRP 客户端(frpc)配置
客户端配置核心是连接服务端、配置 TLS 证书、配置本地代理规则,以下是完整的 frpc.toml配置:
1. 完整配置示例
# ==================== 服务端连接配置 ====================
# 服务端公网IP(与服务端一致)
serverAddr = "47.106.206.xxx"
# 服务端代理通信端口(与服务端bindPort一致)
serverPort = 17000
# ==================== 身份认证配置 ====================
# 认证方式(与服务端一致)
auth.method = "token"
# 令牌(与服务端auth.token完全一致)
auth.token = "frptoken"
# ==================== TLS证书核心配置 ====================
# 开启客户端TLS加密(必须与服务端TLS配置匹配)
transport.tls.enable = true
# 客户端证书文件路径
transport.tls.certFile = "/etc/frp/ssl/frpc.crt"
# 客户端私钥文件路径
transport.tls.keyFile = "/etc/frp/ssl/frpc.key"
# 信任的CA证书路径(用于验证服务端证书合法性)
transport.tls.trustedCaFile = "/etc/frp/ssl/frp_ca.crt"
# ==================== 代理配置(示例:SSH代理) ====================
# 如需添加其他代理,可在此继续配置[[proxies]]
# [[proxies]]
# name = "ssh-local" # 代理名称(自定义)
# type = "tcp" # 代理协议(TCP/UDP/HTTP等)
# localIP = "127.0.0.1" # 客户端本地服务IP(本机填127.0.0.1)
# localPort = 22 # 客户端本地服务端口(SSH默认22)
# remotePort = 1222 # 服务端暴露的代理端口(自定义,需开放)
2.其他常用代理配置示例(按需添加)
除了SSH代理,可根据需求添加HTTP、HTTPS等代理,示例如下:
(1)HTTP代理(本地Web服务,如Nginx、Tomcat)
[[proxies]]
name = "web-http"
type = "http"
localIP = "127.0.0.1"
localPort = 80 # 本地Web服务默认80端口
customDomains = ["test.frp.com"] # 自定义域名(需解析到服务端公网IP)
访问方式:浏览器输入http://test.frp.com,即可代理到客户端本地80端口服务
(2)HTTPS代理(本地HTTPS服务)
[[proxies]]
name = "web-https"
type = "https"
localIP = "127.0.0.1"
localPort = 443 # 本地HTTPS服务默认443端口
customDomains = ["test.frp.com"]
注****意:需在客户端本地配置好HTTPS证书,FRP仅负责代理转发,不处理证书解密
四、第四步:启动FRP客户端并验证
* 客户端启动命令
确保frpc客户端程序与frpc.toml配置文件在同一目录(或指定配置文件路径),执行以下命令启动:
直接启动(前台运行,关闭终端则停止)
./frpc -c frpc.toml
后台启动(推荐,不受终端影响)
nohup ./frpc -c frpc.toml &
查看启动日志,确认是否启动成功
tail -f nohup.out
* 启动成功判断
若日志中出现以下内容,说明客户端与服务端(开启TLS加密)连接成功:
202X/XX/XX XX:XX:XX [INFO] [service] login to server success, get run id [xxxxxx], server udp port [0]
202X/XX/XX XX:XX:XX [INFO] [proxy] [ssh-local] start proxy success
* 代理连接验证(以SSH代理为例)
在外部设备(可访问公网)上执行SSH命令,验证代理是否生效:
格式:ssh 客户端用户名@服务端公网IP -p 服务端暴露的代理端口(remotePort)
ssh root@47.106.206.100 -p 1222
若能成功登录客户端SSH,说明TLS加密代理配置生效;若登录失败,查看客户端/服务端日志排查问题。
五、第五步:设置FRP客户端开机自启(可选,推荐)为避免服务器重启后FRP客户端无法自动运行,可设置开机自启(以systemd为例):
1. 创建systemd服务文件
vim /etc/systemd/system/frpc.service
2. 写入以下内容(修改frpc程序和配置文件路径为实际路径)
[Unit]
Description=FRP Client Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/frp/frpc -c /usr/local/frp/frpc.toml # 替换为实际路径
Restart=always # 服务异常退出时自动重启
RestartSec=5 # 重启间隔5秒
[Install]
WantedBy=multi-user.target
3. 生效并启动服务
systemctl daemon-reload
systemctl start frpc
systemctl enable frpc # 设置开机自启
4. 查看服务状态
systemctl status frpc
六、常见问题排查(重点!)
* 客户端启动失败,提示“certificate verify failed”
原因:TLS证书路径错误、证书过期或SAN配置不匹配。
解决方法:
- 检查frpc.toml中transport.tls.certFile、keyFile、trustedCaFile路径是否与实际证书路径一致;
- 重新执行证书验证命令,确认SAN字段正确(对应客户端内网IP);
- 若证书过期,重新生成证书(重复第二步证书生成步骤)。
* 客户端提示“login to server failed: auth token mismatch”
原因:客户端与服务端auth.token不一致,身份认证失败。
解决方法:修改frpc.toml和frps.toml中的auth.token,确保两者完全相同(建议设置复杂字符串,提升安全性)。
* 代理无法访问,客户端日志无异常
原因:服务端防火墙未开放bindPort(17000)和remotePort(如1222)。
解决方法(以CentOS为例):
开放端口(永久生效)
firewall-cmd --add-port=17000/tcp --permanent
firewall-cmd --add-port=1222/tcp --permanent
重新加载防火墙
firewall-cmd --reload
* 服务端提示“TLS handshake failed”
原因:服务端开启transport.tls.force = true,但客户端未开启TLS,或证书不匹配。
解决方法:确保客户端frpc.toml中transport.tls.enable = true,且证书与服务端使用同一CA签发。
七、配置完成后的注意事项
- 证书文件权限:保持证书文件权限为600(仅root可读写),避免权限泄露导致安全风险;
- 配置文件备份:将frpc.toml、frps.toml及证书文件备份,避免误删导致配置丢失;
- 定期更新证书:本教程生成的证书有效期为10年,到期前需重新生成证书并替换;
- 安全优化:生产环境中,建议修改默认的监控面板账号密码(webServer.user/webServer.password)、auth.token,避免弱密码泄露。
八、证书生成shell脚本(灵活配置IP)
为简化证书生成操作,以下脚本整合了所有证书生成命令,支持执行时传入IP变量或手动输入IP,无需逐行执行命令,适配前文所有证书配置逻辑。
1. 脚本内容
#!/bin/bash
# FRP TLS证书生成脚本(支持手动输入/参数传入IP)
# 用法1:执行时传入参数(服务器IP 客户端IP):bash frp_cert.sh 47.106.206.xxx 192.168.1.xxx
# 用法2:直接执行脚本,手动输入IP:bash frp_cert.sh
# 1. 处理IP参数(优先使用传入参数,无参数则手动输入)
if [ $# -eq 2 ]; then
SERVER_IP=$1 # 第一个参数:服务端公网IP
CLIENT_IP=$2 # 第二个参数:客户端内网IP
else
read -p "请输入FRP服务端公网IP:" SERVER_IP
read -p "请输入FRP客户端内网IP:" CLIENT_IP
fi
# 2. 定义证书存放目录(与前文一致,避免路径错误)
CERT_DIR="/etc/frp/ssl"
# 3. 创建证书目录并设置权限
echo "=== 1. 创建证书目录 ==="
mkdir -p $CERT_DIR
chmod 700 $CERT_DIR
cd $CERT_DIR || exit 1 # 进入目录,失败则退出脚本
# 4. 生成客户端证书配置文件(frpc.cnf)
echo "=== 2. 生成客户端配置文件 frpc.cnf ==="
cat > frpc.cnf << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = Frp
CN = frp-client
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
IP.1 = $CLIENT_IP
EOF
# 5. 生成服务端证书配置文件(frps.cnf)
echo "=== 3. 生成服务端配置文件 frps.cnf ==="
cat > frps.cnf << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = Frp
CN = frp-server
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
IP.1 = $SERVER_IP
EOF
# 6. 生成CA根证书(私钥+证书)
echo "=== 4. 生成CA根证书 ==="
openssl genrsa -out frp_ca.key 2048
chmod 600 frp_ca.key # 限制私钥权限,仅root可读写
openssl req -x509 -new -nodes -key frp_ca.key -subj "/CN=frp-ca" -days 3650 -out frp_ca.crt
# 7. 生成服务端证书与私钥
echo "=== 5. 生成服务端证书 ==="
openssl genrsa -out frps.key 2048
chmod 600 frps.key
openssl req -new -sha256 -key frps.key -subj "/C=CN/ST=Beijing/L=Beijing/O=Frp/CN=frp-server" -config frps.cnf -extensions v3_req -out frps.csr
openssl x509 -req -days 3650 -sha256 -in frps.csr -CA frp_ca.crt -CAkey frp_ca.key -CAcreateserial -extfile frps.cnf -extensions v3_req -out frps.crt
# 8. 生成客户端证书与私钥
echo "=== 6. 生成客户端证书 ==="
openssl genrsa -out frpc.key 2048
chmod 600 frpc.key
openssl req -new -sha256 -key frpc.key -subj "/C=CN/ST=Beijing/L=Beijing/O=Frp/CN=frp-client" -config frpc.cnf -extensions v3_req -out frpc.csr
openssl x509 -req -days 3650 -sha256 -in frpc.csr -CA frp_ca.crt -CAkey frp_ca.key -CAcreateserial -extfile frpc.cnf -extensions v3_req -out frpc.crt
# 9. 验证证书SAN配置(确认IP配置正确)
echo "=== 7. 验证证书配置 ==="
echo "服务端证书SAN信息:"
openssl x509 -in frps.crt -text -noout | grep -A 2 "Subject Alternative Name"
echo "客户端证书SAN信息:"
openssl x509 -in frpc.crt -text -noout | grep -A 2 "Subject Alternative Name"
echo "=== 证书生成完成!所有文件已保存至 $CERT_DIR ==="
echo "生成的文件清单:"
ls -l $CERT_DIR | grep -E "\.key|\.crt|\.cnf|\.csr"
2. 脚本使用说明
(1)脚本保存与授权
# 1. 保存脚本(命名为frp_cert.sh)
vim /etc/frp/frp_cert.sh
# 2. 将上述脚本内容复制粘贴到文件中,保存退出(vim按Esc,输入:wq回车)
# 3. 赋予脚本执行权限
chmod +x /etc/frp/frp_cert.sh
(2)两种执行方式(二选一)
方式1:执行时直接传入IP参数(推荐,高效快捷)
# 格式:bash 脚本路径 服务端公网IP 客户端内网IP
bash /etc/frp/frp_cert.sh 47.106.206.100 192.168.140.122
方式2:直接执行脚本,手动输入IP
# 执行脚本
bash /etc/frp/frp_cert.sh
# 按提示输入IP(示例)
# 请输入FRP服务端公网IP:47.106.206.100
# 请输入FRP客户端内网IP:192.168.140.122
3. 脚本注意事项
- 脚本会自动创建证书目录
/etc/frp/ssl,并设置权限,无需手动创建; - 私钥文件会自动设置为600权限(仅root可读写),提升安全性;
- 执行脚本前需确保系统已安装openssl(未安装可执行
yum install openssl -y或apt install openssl -y); - 若已生成过证书,执行脚本会覆盖原有文件,建议先备份原有证书(如
cp /etc/frp/ssl /etc/frp/ssl.bak)。