使用Caddy配置内网HTTPS
NAS 上通过 Docker 部署的服务越来越多,每次都是通过独立的端口开放出来,虽然也可以用,但是每次都需要 IP 感觉很麻烦。这周又搞了两个新的服务部署上去,尤其其中一个通过 IP 来使用还有点问题,就调研了下怎么折腾内网的HTTPS。
首先想到的就是 NGINX,工作中用的比较多,之前为了部署 Bitwarden 也已经部署了。不过内心有点拒绝,总感觉 NGINX 有点太重了,也可能是工作中用的比较多,对它的语法感觉不是特别喜欢,尤其是转发指令各种潜规则,很容易犯错。抱着折腾一下的心态,用 Google 和 GPT 搜了下可选的方案,发现 Google 和 GPT 都推荐 Caddy。简单查了一些资料,发现跟配置方式跟 NGINX 挺像的,而且貌似更轻量级,配置也简化了不少。
接下来直奔主题看下 HTTPS 怎么配置,我能想到的就是自签名证书的方式,所以重点看了相关的资料,Caddy 也的确支持。
首先是证书生成:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout "n1.key" -out "n1.crt" -subj "/CN=*.n1.to"
然后修改 Caddyfile 来使用证书:
{
auto_https off
log {
output file /data/caddy.log
level INFO
format console {
time_local
time_format wall_milli
}
}
}
*.n1.to {
tls /ssl/n1.crt /ssl/n1.key
}
https://chat.n1.to {
reverse_proxy * chatgpt:3000
}
https://vault.n1.to {
reverse_proxy * vaultwarden:80
}
配置后基本满足需求,能通过浏览器直接访问对应的域名,各个服务也能正常使用。但是有一点让我有点难受,Chrome 对于自签名证书每次重新打开的时候都会提示不安全,每次都需要点击一次确认才能使用。
这时候求助万能的GPT,caddy有其它方式支持内部域名https吗
,GPT 给出的答案中有一个内部CA颁发的证书的方案,专门去官网了解了下,发现 Caddy 可以通过 tls internal 的方式,直接使用内置的PKI 来颁发证书,而且配置非常的方便,只需要声明一个 tls internal,其它的 Caddy 帮你搞定。
然后就是第二版的 Caddyfile:
{
log {
output file /data/caddy.log
level INFO
format console {
time_local
time_format wall_milli
}
}
}
*.n1.to {
tls internal {
on_demand
}
@chat host chat.n1.to
handle @chat {
reverse_proxy * chatgpt:3000
}
@vault host vault.n1.to
handle @vault {
reverse_proxy * vaultwarden:80
}
handle {
abort
}
}
这里的核心就是 tls internal
这部分,Caddy 判断是内部tls 之后,会在请求指定域名的时候(比如 chat.n1.to
),内部通过 local 的 ca 来请求证书并下发给浏览器,只要你把 Caddy 的 root.crt 的根证书安装,所有Caddy 颁发的子证书都是被信任的。这个时候你打开指定的域名就不会提示不安全,而且地址栏上的🔐也是绿色的。
这里补充下Mac 上如何安装 root.crt
:
sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain /path/to/root.crt
然后这个 root.crt
哪里来,在类Unix 的环境中,可以在 $HOME/.local/share/caddy/pki/authorities/local/root.crt
中找到。
整体折腾完感觉还是很满意的,而且发现了 Caddy 这么一个神器,后续想做一个简单的反向代理完全可以拿过来用。而且 Caddy 有一个非常方便的功能,如果你有一个外网域名,完成不需要自己申请tls 证书,Caddy 直接集成了Let’s Encrypt,自动帮你申请和续签证书,配置也很简单,感觉这才是新网关应该有的样子。
配置参考:caddyfile