部署教程与其他博主相同
部署 Tailscale Derper 自建中继服务器 – 猫猫博客
(8 封私信 / 2 条消息) 大内网战略(6):自建 Tailscale DERP 中继服务器 保姆级教程 – 知乎
区别:证书使用宝塔签发的证书
1.这里使用derp的域名建立网站,并且开启ssl,主要用这个网站生成的证书
![图片[1]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-1024x783.png)
2.进入宝塔证书路径
![图片[2]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-1-1024x486.png)
fullchain.pem 里面包含域名证书.crt ,拆分出来即可。
privkey.pem 直接重命名为key文件。先手动生成文件,并且运行derp
![图片[3]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-2-1024x609.png)
这里可以看到运行成功了。
![图片[4]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-4-1024x539.png)
3.宝塔面板三个月自动更新证书,可以在后台运行一个分离证书的sh,提取crt 和重命名key
以下是最终优化版脚本,支持自动覆盖目标文件,明确输出目录信息,并为新生成的证书文件设置644权限(私钥保持600):
#!/bin/bash
# split_cert.sh - 拆分 PEM 证书并按目录名重命名(自动覆盖 + 权限规范)
set -e
# ========== 参数处理 ==========
TARGET_DIR="${1:-/www/server/panel/vhost/ssl/ts.qifeng.la}"
if [[ ! -d "$TARGET_DIR" ]]; then
echo "❌ 错误: 目标目录不存在"
echo " 路径: $TARGET_DIR"
echo "用法: $0 [目标目录路径]"
exit 1
fi
# 获取绝对路径和目录名
ABS_PATH=$(cd "$TARGET_DIR" && pwd 2>/dev/null || echo "$TARGET_DIR")
DIR_NAME=$(basename "$ABS_PATH")
# ========== 文件路径定义 ==========
FULLCHAIN="${ABS_PATH}/fullchain.pem"
PRIVKEY="${ABS_PATH}/privkey.pem"
DOMAIN_CERT="${ABS_PATH}/${DIR_NAME}.crt"
CHAIN_CERT="${ABS_PATH}/root_bundle.crt"
PRIVKEY_RENAMED="${ABS_PATH}/${DIR_NAME}.key"
# ========== 显示处理信息 ==========
echo "=========================================="
echo "📁 证书拆分处理(自动覆盖模式)"
echo "=========================================="
echo "✅ 完整目录路径 : $ABS_PATH"
echo "✅ 目录名称 : $DIR_NAME"
echo "------------------------------------------"
# ========== 检查输入文件 ==========
if [[ ! -f "$FULLCHAIN" ]]; then
echo "❌ 错误: 未找到 fullchain.pem"
echo " 路径: $FULLCHAIN"
exit 1
fi
if [[ ! -f "$PRIVKEY" ]]; then
echo "❌ 错误: 未找到 privkey.pem"
echo " 路径: $PRIVKEY"
exit 1
fi
echo "✓ 检测到输入文件:"
echo " • fullchain.pem"
echo " • privkey.pem"
echo ""
# ========== 覆盖提示 ==========
OVERWRITE_FILES=()
[[ -f "$DOMAIN_CERT" ]] && OVERWRITE_FILES+=("$DOMAIN_CERT")
[[ -f "$CHAIN_CERT" ]] && OVERWRITE_FILES+=("$CHAIN_CERT")
[[ -f "$PRIVKEY_RENAMED" ]] && OVERWRITE_FILES+=("$PRIVKEY_RENAMED")
if [[ ${#OVERWRITE_FILES[@]} -gt 0 ]]; then
echo "⚠️ 以下文件将被覆盖:"
for f in "${OVERWRITE_FILES[@]}"; do
echo " • $(basename "$f")"
done
echo ""
fi
# ========== 拆分证书(直接覆盖) ==========
echo "📦 正在提取域名证书(第一个证书)..."
awk '
BEGIN {count=0; output=0}
/-----BEGIN CERTIFICATE-----/ {
count++
if (count == 1) {
output=1
print
} else {
output=0
}
next
}
/-----END CERTIFICATE-----/ {
if (output) {
print
exit
}
next
}
{if (output) print}
' "$FULLCHAIN" > "$DOMAIN_CERT"
chmod 644 "$DOMAIN_CERT" # 设置证书权限为 644
echo "🔗 正在提取证书链(中间证书 + 根证书)..."
awk '
BEGIN {count=0; output=0}
/-----BEGIN CERTIFICATE-----/ {
count++
if (count > 1) output=1
else output=0
if (output) print
next
}
/-----END CERTIFICATE-----/ {
if (output) print
next
}
{if (output) print}
' "$FULLCHAIN" > "$CHAIN_CERT"
chmod 644 "$CHAIN_CERT" # 设置证书链权限为 644
# ========== 重命名私钥(直接覆盖) ==========
echo "🔑 正在重命名私钥文件(覆盖模式)..."
cp -f "$PRIVKEY" "$PRIVKEY_RENAMED"
chmod 600 "$PRIVKEY_RENAMED" # 私钥保持 600 权限
# ========== 验证结果 ==========
if [[ ! -s "$DOMAIN_CERT" ]]; then
echo "❌ 错误: 域名证书生成失败或为空"
exit 1
fi
CHAIN_COUNT=$(grep -c '-----BEGIN CERTIFICATE-----' "$CHAIN_CERT" 2>/dev/null || echo 0)
if [[ $CHAIN_COUNT -eq 0 ]]; then
echo "ℹ️ 提示: 证书链为空(fullchain.pem 可能仅包含单个证书)"
fi
if [[ ! -s "$PRIVKEY_RENAMED" ]]; then
echo "❌ 错误: 私钥文件生成失败"
exit 1
fi
# ========== 最终输出 ==========
echo ""
echo "=========================================="
echo "✅ 处理完成(所有目标文件已覆盖)"
echo "=========================================="
echo "📁 完整目录路径 : $ABS_PATH"
echo "🏷️ 目录名称 : $DIR_NAME"
echo "------------------------------------------"
echo "生成的文件及权限:"
echo " • ${DIR_NAME}.crt (权限 644)"
echo " 路径: $DOMAIN_CERT"
echo ""
echo " • root_bundle.crt (权限 644)"
echo " 路径: $CHAIN_CERT"
echo " 包含证书数量: $CHAIN_COUNT"
echo ""
echo " • ${DIR_NAME}.key (权限 600)"
echo " 路径: $PRIVKEY_RENAMED"
echo "=========================================="
# 显示证书主题(可选)
if command -v openssl &>/dev/null; then
SUBJECT=$(openssl x509 -in "$DOMAIN_CERT" -noout -subject 2>/dev/null | sed 's/subject=//g' | sed 's/^[[:space:]]*//g' || echo "N/A")
echo "📄 域名证书主题: $SUBJECT"
fi
🔑 权限说明
| 文件类型 | 文件名 | 权限 | 说明 |
|---|---|---|---|
| 域名证书 | ${DIR_NAME}.crt | 644 | 公开可读,Web 服务常用权限 |
| 证书链 | root_bundle.crt | 644 | 公开可读,中间/根证书 |
| 私钥 | ${DIR_NAME}.key | 600 | 仅所有者可读写,保障安全 |
🚀 使用示例
# 保存脚本(例如 ~/scripts/split_cert.sh)
chmod +x ~/scripts/split_cert.sh
# 处理指定目录(自动覆盖 + 权限规范)
~/scripts/split_cert.sh /www/server/panel/vhost/ssl/ts.qifeng.la
💡 输出示例片段
生成的文件及权限:
• ts.qifeng.la.crt (权限 644)
路径: /www/server/panel/vhost/ssl/ts.qifeng.la/ts.qifeng.la.crt
• root_bundle.crt (权限 644)
路径: /www/server/panel/vhost/ssl/ts.qifeng.la/root_bundle.crt
包含证书数量: 2
• ts.qifeng.la.key (权限 600)
路径: /www/server/panel/vhost/ssl/ts.qifeng.la/ts.qifeng.la.key
4.将此文件设置为计划任务
/www/wwwroot/split_cert.sh /www/server/panel/vhost/ssl/ts.qifeng.la
![图片[5]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-5-1024x606.png)
![图片[6]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-7-1024x852.png)
5.记得给宝塔网站加个备案号,防止掉备案
![图片[7]-部署 Tailscale Derper 自建中继服务器 使用宝塔Let’s Encrypt证书-起风啦](https://wp.qifeng.la/wp-content/uploads/2026/02/image-6-1024x668.png)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END







