在这个很多功能使用都要求 HTTPS 的浏览器环境下,一般站点使用 Caddy 配置代理真的很方便,不需要申请再手动配置 SSL 证书,更不需要考虑定期更新证书以免忘记更新导致站点访问报错。如果是想要了解怎么使用可以参考 Caddy 使用入门,这里主要参考 Automatic HTTPS (opens new window) 来聊聊怎么在各自场景下用 Caddy 给解析的域名配置 HTTPS 。
Caddy is the first and only web server to use HTTPS automatically and by default.
Caddy 默认情况下会给所有的站点配置 HTTPS,对本地地址使用的是自签名的证书,对公共 DNS 解析的域名使用 ACME CA
(目前是 Let's Encrypt (opens new window) 和 ZeroSSL (opens new window))提供的证书。Caddy 默认会把 HTTP 重定向到 HTTPS,更方便的一点是 Caddy 还会自动更新证书。
# 80 和 443 开放的时候
这种情况下配置 HTTPS 非常简单,简单到就是不需要做任何额外的配置,只要根据需求配置好 Caddy 然后启动就会自动配置,直接访问域名就会跳转到对应的 HTTPS 站点。
# 80 和 443 不开放的时候
如果由于某些原因不能开放 80 和 443 端口的情况下,直接按照默认配置是无法成功启用 HTTPS 的,启动的时候会给出类似下面的报错:
这是因为如果要获得受信任的 TLS 证书是需要受信任的第三方机构进行验证通过的。这种验证默认情况下是访问 80/443 端口进行验证,但是由于 80/443 端口是不可访问的,就会导致验证不通过,从而造成 SSL 证书生成失败,自然也就无法使用 HTTPS 了。
实际上 ACME protocol (opens new window) 提供了三种验证方式,Caddy 默认会随机使用 HTTP challenge
或者 TLS-ALPN challenge
中的一种进行验证。其中 HTTP challenge
是通过域名的 A/AAAA 记录找到对应的主机,然后使用 HTTP 请求通过 80 端口访问临时的加密资源,如果获取到预期的资源就会颁发证书;TLS-ALPN challenge
是对主机的 443 端口访问获取资源进行校验。两者的要求就是 80 或 443 端口开放,即使 Caddy 不能监听也要能监听端口的把对应请求转发到 Caddy 的端口上。
因此在 80 和 443 端口不能访问的情况下,只能选择第三种 DNS challenge
。DNS challenge
就是通过 DNS 查找到域名对应的一条特殊的 TXT解析记录
,如果其解析结果是 CA 预期的值就会颁发证书。这种验证方式不需要服务器任何开放端口,并且请求证书的服务器也不需要是公网可访问的。
不过由于 DNS challenge
需要配置域名的解析,所以需要提供一些配置来让 Caddy 操作对应 DNS 服务商提供 API 来设置和清除验证用的特殊 TXT解析记录
。Caddy 2 使用 新的和改进的 DNS 提供者接口 (opens new window) 处理 ACME DNS challenge。
# 获取带有 DNS 服务商插件的 Caddy
首先要获取一个安装了对应 DNS 服务商插件的 Caddy,有几种常用的方法可以获取:
# 方法一
- 进入 Caddy 下载页面 (opens new window)
- 搜索 ( dns.providers.) 或对应服务商名字,找到对应的 DNS 服务商,点击选中
- 下载添加了选中模块的 Caddy
这种方法相对比较简单,只要找到对应插件添加后下载即可。只是下载的时候需要注意选择合适的平台即可。
# 方法二
---shell xcaddy build --with github.com/caddy-dns/REPOSITORY
这种方法相对比较复杂,需要安装 xcaddy 以及对应环境等,适合高阶用户操作。
#### 方法三
除了上述两种方法外还可以使用官方提供的 docker 进行操作。后面的例子是基于官方 docker 加上要安装的插件构建想要的 Caddy。
```shell
FROM caddy:2.6.2-builder AS builder
RUN xcaddy build \
--with github.com/caddyserver/nginx-adapter \
--with github.com/caddy-dns/alidns
FROM caddy:2.6.2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
如果使用 docker 的话,这种方法相对来说是最简单的,都是基于官方 docker 进行操作。
# 方法四
如果没有找到对应 DNS 提供商,也可以参考 这里 (opens new window) 提供的方案。(注意:该方案未实际操作)
# 启用 DNS challenge
按照上述操作获取了一个带有 DNS 服务商插件的 Caddy 后只需在配置中启用 DNS challenge 即可。
# 全局选项(对所有站点使用)
在 Caddyfile 的顶部使用 全局 acme_dns 选项 (opens new window) 进行配置:
{
acme_dns <provider> ...
}
# 例如
{
acme_dns alidns {
access_key_id {env.ALIYUN_ACCESS_KEY_ID}
access_key_secret {env.ALIYUN_ACCESS_KEY_SECRET}
}
}
2
3
4
5
6
7
8
9
10
11
# 站点单独配置
如果是为了指定站点配置,可以在站点的配置项中加上 tls 指令 (opens new window):
tls {
dns <provider> ...
}
# 例如
tls {
dns alidns {
access_key_id {env.ALIYUN_ACCESS_KEY_ID}
access_key_secret {env.ALIYUN_ACCESS_KEY_SECRET}
}
}
2
3
4
5
6
7
8
9
10
如果您的凭据在环境中,您也可以使用 {env.*)
占位符。不同 DNS 服务商插件的配置项可能会有所区别,根据对应文档进行配置即可。
# JSO 配置
如果使用 JSON,请使用 颁发者配置自动化策略 acme58 (opens new window) 设置:
{
"module": "acme",
"challenges": {
"dns": {
"provider": {
"name": "alidns",
"access_key_id":"YOUR_ALIYUN_ACCESS_KEY_ID",
"access_key_secret":"YOUR_ALIYUN_ACCESS_KEY_SECRET"
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
# 禁用自动 HTTPS
上面都是怎么自动配置 HTTPS 的,那如果就是想要一个 HTTP 站点呢,也是可以的:
- 在配置文件中明确禁用,配置 auto_https 属性
- off:完全禁用
- disable_redirects: 仅禁用 HTTP 到 HTTPS 重定向
- disable_certs:仅禁用证书自动化
- ignore_loaded_certs:即使手动加载证书,也执行证书自动化
- 不在配置中提供任何主机名或 IP 地址
- 专门监听 HTTP 端口
- 在配置中为网站地址加上前缀
http://
- 手动加载证书(除非设置了 ignore_loaded_certificates)
对于简单的站点,用 Caddy 实现 HTTPS 的确是个不错的选择!