使用 acme.sh 配置 Let's Encrypt 签发的 IP 地址 SSL 证书

本文将介绍使用 acme.sh 配置 Let's Encrypt 为 IP 地址签发 SSL 证书。

acme.sh 本身不强制 root 运行(官方也写了 "You don't have to be root then, although it is recommended"),但本文的证书需要写入 /etc 且 --reloadcmd 需要重载服务,均需要 root 权限,所以建议先使用 sudo -i 切换到 root 用户再执行本文命令。

之前写过一篇使用 acme.sh 签发证书的教程,但在很长一段时间里,Let's Encrypt 只能给域名签发证书。

经过几个月的测试之后,现在终于可以对 IP 地址 下手了。

#为什么要给 IP 签发证书

在很多场景下,我们并不一定需要域名,但确实需要 HTTPS。比如:

  1. DNS over HTTPS(DoH)服务无需依赖域名解析

直接通过 IP 提供 DoH 服务,避免「为了安全先做一次不安全的域名解析」这种哲学问题。

  1. Web 服务默认站点隐藏真实域名

默认站点只暴露 IP,不暴露真实域名,顺便还能挡掉一部分不太礼貌的爬虫。

  1. 临时服务或测试环境

临时起个服务,只想加个锁,不想再去 DNS 那边折腾。

  1. 避免证书透明日志(Certificate Transparency Log)暴露域名,保护隐私

有些域名不太想出现在公开日志里,低调一点总是好的。

#准备工作

首先更新 acme.sh 到最新版本:

因为 IP 证书目前只能通过 http-01 和 tls-alpn-01 方式进行验证,所以你需要检查服务器的防火墙,设置允许 TCP 80 和 TCP / UDP 443 端口在公网可以访问。

#配置 Nginx 80 端口的默认站点

这里我只介绍在 Nginx 下的配置吧,我们可以直接写入 80 端口的默认配置:

如果你在 Debian 或 Ubuntu 下安装 Nginx,可以直接覆盖 /etc/nginx/sites-available/default 文件:

然后创建两个目录并重新加载 Nginx:

#使用 acme.sh 签发 IP 证书

假设你服务器的 IP 地址是 192.0.2.2 和 2001:db8::2:

注意这里我们必须使用 shortlived 这个 Profile,因为 Let's Encrypt 的 IP 证书有效期只有 6.66666 天(160 小时),同时 acme.sh 需要更短的时间来进行检查更新证书,所以可以设置 --days 3 参数,让它 3 天检查并更新一次,你也可以设置 4 或 5,但是不要设置 6,否则可能证书过期了都没更新哦。

执行命令以后会看到类似的申请成功返回:

然后我们可以把申请好的证书放在 /etc/nginx/ssl 目录:

#配置 Nginx 443 端口的默认站点

安装完证书后我们即可配置 Nginx 默认的 443 端口了,你可以把这段配置一起放入 /etc/nginx/sites-available/default 文件:

然后检查并重新加载 Nginx:

一切就绪以后就可以直接访问 https://192.0.2.2/ 并返回 403 错误页面,我们可以看到证书里 Subject Alt Names 字段也显示 IP Address 了:

读者们在使用过程中如果遇到问题,可以在 V2EX 交流讨论或在下方评论:

https://be.st/pGx9