From a3adf38a86eb8dcf7d0153952647d522fa986f9b Mon Sep 17 00:00:00 2001 From: mm644706215 Date: Sat, 2 Aug 2025 15:52:49 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 32 +++++++++++++++++++++++++++++ renew_derper.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 renew_derper.sh diff --git a/README.md b/README.md index 75bf0b7..895a92c 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,35 @@ docker run --rm \ -v ``` +## 定时续期 + +```shell +chmod +x renew_restart.sh +ln -s ${PWD}/renew_restart.sh /usr/local/bin/renew-restart.sh +crontab -e +``` + +```shell +0 3 * * * root /usr/local/bin/renew-cert.sh >> /var/log/certbot/renew.log 2>&1 +``` + + +## 自动管理证书 + +Tailscale 自带的 derper 在设计上确实有一个「自动获取与续期证书」的模式,参数是 -certmode letsencrypt(对应环境变量 DERP_CERT_MODE=letsencrypt)。这种模式会使用内置的 ACME 客户端向 Let’s Encrypt 申请证书并在到期前自动续期。但它有两个重要前提: + +**必须使用 ACME 支持的端口进行验证。**Let’s Encrypt 的 HTTP‑01 挑战只能通过公网上的 80 端口完成,TLS‑ALPN‑01 挑战只能通过 443 端口完成 +community.letsencrypt.org +。因此,derper 必须监听 443(默认)并且允许 Let’s Encrypt 的验证服务器访问 80 或 443,才能自动完成申请和续期。 + +**域名需要直接解析到运行 derper 的服务器。**只有这样 Let’s Encrypt 的验证请求才能到达 derper。 + +当你把 derper 改为监听 3477 这类高端口时,Let’s Encrypt 无法再通过 80/443 进行验证。国内博文也指出,如果自建 DERP 服务器使用高位端口,就无法通过自动验证,只能手动申请证书 +alampy.com +。所以在这种情况下,derper 自身的自动证书功能会失效,需要自行管理证书并挂载进容器。 + +总结: + +如果能让 derper 监听 443,并开放 80/443 两个端口,你可以启用 -certmode letsencrypt,derper 会自动申请并定期续期证书,完全不需要手动管理。 + +如果不能开放 80/443(例如用的是 3477 端口或服务器 behind NAT),Let’s Encrypt 的 HTTP/TLS‑ALPN 挑战无法完成,derper 就不能自动续期。你需要使用 DNS‑01 挑战通过 certbot 等工具申请证书,并在续期后重启 derper,或手动申请更新证书然后挂载到容器 \ No newline at end of file diff --git a/renew_derper.sh b/renew_derper.sh new file mode 100644 index 0000000..8f3a0e2 --- /dev/null +++ b/renew_derper.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# 检查参数 +if [ $# -lt 2 ]; then + echo "用法: $0 <工作目录> <域名>" + exit 1 +fi + +WORKDIR="$1" # 第一个参数:工作目录,比如 /opt/caddy/certbot-aliyun-docker/derper +DOMAIN="$2" # 第二个参数:域名,比如 derper.jmsu.top + +# 可选:你可以将阿里云AK/SK/邮箱也作为参数或放到环境变量/配置文件 +REGION="cn-hangzhou" +ACCESS_KEY_ID="LTAI5tP1yWFMMJhF6nrGYEit" # 推荐写到外部变量,或传参数 +ACCESS_KEY_SECRET="LTAI5tP1yWFMMJhF6nrGYEit" # 推荐写到外部变量,或传参数 +EMAIL="pylyzeng@gmail.com" + +cd "$WORKDIR" || exit 1 + +echo ">>> 停止 derper 服务" +docker compose down + +echo ">>> 续期证书 $DOMAIN" + +docker run --rm \ + -e REGION="$REGION" \ + -e ACCESS_KEY_ID="$ACCESS_KEY_ID" \ + -e ACCESS_KEY_SECRET="$ACCESS_KEY_SECRET" \ + -e DOMAIN="$DOMAIN" \ + -e EMAIL="$EMAIL" \ + -v "$PWD/letsencrypt:/etc/letsencrypt" \ + -v "$PWD/certs:/app/certs" \ + -v "$PWD/logs:/var/log/certbot" \ + hotwa/certbot:latest \ + certbot renew \ + --manual \ + --preferred-challenges dns \ + --manual-auth-hook "alidns" \ + --manual-cleanup-hook "alidns clean" \ + --deploy-hook "/app/scripts/webhook.sh" \ + --no-random-sleep-on-renew \ + -v + +echo ">>> 启动 derper 服务" +docker compose up -d + +echo "crontab 添加任务选项(请根据实际需求选择,复制到 crontab 即可):" +echo +echo "【每周一凌晨 2 点执行】" +echo "0 2 * * 1 $WORKDIR/renew_derper.sh $WORKDIR $DOMAIN >> /var/log/renew_derper.log 2>&1" +echo +echo "【每月 1 号凌晨 2 点执行】" +echo "0 2 1 * * $WORKDIR/renew_derper.sh $WORKDIR $DOMAIN >> /var/log/renew_derper.log 2>&1"