侧边栏壁纸
博主头像
赵东阳的个人网站

行动起来,活在当下

  • 累计撰写 20 篇文章
  • 累计创建 8 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

1Panel OpenResty 为 Headscale 配置 Let's Encrypt 与 HTTPS 反代

温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1Panel OpenResty 为 Headscale 配置 Let's Encrypt 与 HTTPS 反代(命令行)

适用场景:服务器已用 1PanelOpenResty 占用 80/443,Headscale 监听本机 127.0.0.1:8080,需要为控制面域名签发证书并完成 HTTPS 反代。

背景

自建 Headscale 时,Tailscale 客户端必须能访问一个 HTTPS 控制面地址server_url)。常见做法是:

  • Headscale 容器内跑 明文 HTTP(例如 8080
  • 由前置 反向代理 终止 TLS,对外提供 https://你的域名

本机 80/443 已被 1Panel 的 OpenResty 占用,无法在 Headscale 容器里再绑一份 Caddy/Nginx。因此采用:

客户端 ──HTTPS──▶ OpenResty (443) ──HTTP──▶ Headscale (127.0.0.1:8080)

架构要点

组件 说明
Headscale Docker 映射 127.0.0.1:8080,配置 server_url: https://hs.example.com
OpenResty 1Panel 容器,站点配置挂载在宿主 /opt/1panel/www
证书 Let's Encrypt HTTP-01,证书需复制到 /opt/1panel/www/sites/域名/ssl/(容器内读 /www/...
DERP 443 做 HTTP 反代时,不要开嵌入 DERP;用公共 derp.urls 中继即可

日志里若出现 Listening without TLS but ServerURL does not start with http://,表示 TLS 在反代层终止,属于正常现象。

前置条件

  1. 域名 A/AAAA 已解析到本机公网 IP
  2. 公网能访问 80(Let's Encrypt 校验)
  3. 上游已就绪:curl http://127.0.0.1:8080/health 返回 200
  4. 存在名称匹配 1Panel-openresty* 的 Docker 容器

一键脚本(推荐)

脚本已整理进个人 Skills 仓库:my-ide-skills / 1panel-openresty-letsencrypt-proxy

git clone https://github.com/zhaodongyang2016/my-ide-skills.git
cd my-ide-skills/1panel-openresty-letsencrypt-proxy
sudo chmod +x scripts/provision-https-reverse-proxy.sh

export DOMAIN="hs.example.com"
# 可选:反代目标,默认 http://127.0.0.1:8080
# export UPSTREAM="http://127.0.0.1:8080"
# 可选:Certbot 邮箱
# export EMAIL="you@example.com"

sudo -E bash scripts/provision-https-reverse-proxy.sh

脚本会自动完成:

  1. 写入 Nginx 站点与反代片段(含 WebSocket、长超时)
  2. 先以 仅 HTTP 配置 reload,便于 HTTP-01
  3. certbot certonly --webroot 申请证书
  4. 证书复制到 1Panel 站点目录,启用 HTTPS 并 301 跳转
  5. 安装 续期 deploy hook(续签后同步证书并 reload OpenResty)

验证

# 证书与 TLS
curl -fsS "https://${DOMAIN}/health"

# 期望输出类似
# {"status":"pass"}

浏览器访问 https://你的域名/health 应无证书警告。

配置文件落盘位置

用途 宿主路径
站点 server /opt/1panel/www/conf.d/${DOMAIN}.conf
反代、日志、证书、ACME webroot /opt/1panel/www/sites/${DOMAIN}/
Let's Encrypt 源证书 /etc/letsencrypt/live/${DOMAIN}/
续期钩子 /etc/letsencrypt/renewal-hooks/deploy/01-copy-${DOMAIN}-to-1panel-www.sh

手动 reload OpenResty:

CT=$(docker ps --filter "name=1Panel-openresty" --format '{{.Names}}' | head -1)
sudo docker exec "$CT" openresty -t && sudo docker exec "$CT" openresty -s reload

客户端接入(简要)

确认控制面可用后,在客户端指定自定义登录服务器:

export HS_URL="https://hs.example.com"
sudo tailscale up --login-server "$HS_URL" --accept-dns

或使用预授权密钥(在 Headscale 服务器生成):

sudo tailscale up --login-server "$HS_URL" --authkey <PREAUTH_KEY> --accept-dns

各平台图形界面入口一般为 Custom Login Server / Use alternate server,填入 https://你的域名

故障排查

现象 可能原因与处理
证书申请失败 80 未指向本机;检查 /.well-known/acme-challenge/ 是否落到站点 index 目录
HTTPS 仍是 localhost 证书 域名未匹配独立 server 块,走了 443 default_server;确认 server_name 与 reload
/health 404 反代未指向上游;确认 proxy_pass http://127.0.0.1:8080
502 上游未启动;本机 curl http://127.0.0.1:8080/health

与 1Panel 面板的关系

本方式直接写 /opt/1panel/www/conf.d,面板里未必显示为「已创建网站」。请避免对同一域名在面板再建一套冲突配置。若改由面板托管,迁移后删除 conf.d 里对应文件并 reload。

续期

系统 certbot.timer 负责自动续期;deploy hook 会把新证书同步到站点 ssl/ 并 reload。可手动模拟:

sudo certbot renew --dry-run

参考

0

评论区