Let's Encrypt SSL 证书申请

本文最后更新于 1 年前

Let’s Encrypt SSL 证书申请

为什么申请?

HTTP:未实施数据加密

每个以 HTTP 开头的 URL 链接都使用一种基本类型的“超文本传输协议”。由 Tim Berners-Lee 于 1990 年代初创建,当时互联网仍处于起步阶段,该网络协议标准允许 Web 浏览器和服务器通过数据交换进行通信。

HTTP 也被称为“无状态系统”,这意味着它可以按需连接。您单击一个链接,请求连接,您的 Web 浏览器将此请求发送到服务器,服务器通过打开页面进行响应。连接越快,数据呈现给您的速度就越快。

作为一种“应用层协议”,HTTP 仍然专注于呈现信息,但不太关心这些信息从一个地方传播到另一个地方的方式。不幸的是,这意味着 HTTP 可能会被拦截并可能被更改,从而使信息和信息接收者(即您)都容易受到攻击。

HTTPS:加密连接

HTTPS 不是 HTTP 的对立面,而是它的表弟。两者本质上是相同的,因为它们都指的是相同的“超文本传输协议”,该协议使请求的 Web 数据能够显示在您的屏幕上。但是,HTTPS 仍然略有不同,更先进,也更安全。

简单的说,HTTPS协议是HTTP的扩展。缩写中的“S”来自 Secure 一词,它由传输层安全性 (TLS) [安全套接字层 (SSL)的后继者] 提供支持,这是一种在 Web 服务器和服务器之间建立加密连接的标准安全技术。浏览器。

如果没有 HTTPS,您输入网站的任何数据(例如您的用户名/密码、信用卡或银行详细信息、任何其他表单提交数据等)都将以明文形式发送,因此容易被拦截或窃听。因此,在输入任何信息之前,您应该始终检查站点是否使用 HTTPS。

除了加密服务器和您的浏览器之间传输的数据外,TLS 还验证您正在连接的服务器并保护传输的数据不被篡改。

这有助于我这样思考——HTTPS 中的 HTTP 相当于一个目的地,而 SSL 相当于一个旅程。第一个负责将数据显示到屏幕上,第二个负责管理数据到达那里的方式。通过联合力量,他们以安全的方式移动数据。

What’s the difference between HTTP and HTTPS?

HTTPS 有助于确保网络安全。毫无疑问,它是比 HTTP 更好的网络协议解决方案。

将网站开启HTTPS的服务是需要SSL的证书的,我们来看一下如何在Let’s Encrypt上申请免费的SSL证书。

Let’s Encrypt 是免费、开放和自动化的证书颁发机构。由非盈利组织互联网安全研究小组(ISRG)运营。

申请的前提条件

我们申请SSL证书的前提条件有下面这几个

  1. 拥有域名,能够自主配置DNS。或者提供Web服务器做验证,在网站目录下放一个文件。
  2. 获取证书的环境要能访问DNS服务器,因为会需要做DNS解析校验。
  3. 需要有远程主机的权限,会需要更新和安装组件。
  4. 公网IP,保留地址无法申请SSL。

申请步骤

Let’s Encrypt 的证书申请除去手动申请常见的主要有下面这几种

  • acme.sh的方式(我当时选取了这个方式)
  • docker 镜像获取
  • certbot方式获取证书(官网建议使用这种方式获取证书,可以在不下线的状态下自动执行证书颁发和安装)

acme.sh脚本

Github链接:An ACME Shell script: acme.sh

Github的README其实介绍的其实很全面,这里copy一下。

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.

主要步骤:

  1. 安装 acme.sh
  2. 生成证书
  3. copy 证书到 nginx/apache 或者其他服务
  4. 更新证书
  5. 更新 acme.sh
  6. 出错怎么办, 如何调试

下面详细介绍.

1. 安装 acme.sh

安装很简单, 一个命令:

这里输入你的邮箱,这个邮箱有什么用倒是不太清楚

1
curl https://get.acme.sh | sh -s email=my@example.com
SHELL

普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:

  1. 把 acme.sh 安装到你的 home 目录下:
1
~/.acme.sh/
SHELL

并创建 一个 shell 的 alias, 例如 .bashrc,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

  1. 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

更高级的安装选项请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-install

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

2. 生成证书

acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: http 和 dns 验证.

1. http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.

1
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
SHELL

只需要指定域名, 并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用.

如果你用的 apache服务器, acme.sh 还可以智能的从 apache的配置中自动完成验证, 你不需要指定网站根目录:

1
acme.sh --issue -d mydomain.com --apache
STYLUS

如果你用的 nginx服务器, 或者反代, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:

1
acme.sh --issue -d mydomain.com --nginx
STYLUS

注意, 无论是 apache 还是 nginx 模式, acme.sh在完成验证之后, 会恢复到之前的状态, 都不会私自更改你本身的配置. 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置, 否则只能成功生成证书, 你的网站还是无法访问https. 但是为了安全, 你还是自己手动改配置吧.

如果你还没有运行任何 web 服务, 80 端口是空闲的, 那么 acme.sh 还能假装自己是一个webserver, 临时听在80 端口, 完成验证:

1
acme.sh --issue -d mydomain.com --standalone
STYLUS

更高级的用法请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert

2. 手动 dns 方式, 手动在域名上添加一条 txt 解析记录, 验证域名所有权.

这种方式的好处是, 你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证. 坏处是,如果不同时配置 Automatic DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。

1
2
acme.sh --issue --dns -d mydomain.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
STYLUS

然后, acme.sh 会生成相应的解析记录显示出来, 你只需要在你的域名管理面板中添加这条 txt 记录即可.

等待解析完成之后, 重新生成证书:

1
2
acme.sh --renew -d mydomain.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
STYLUS

注意第二次这里用的是 --renew

dns 方式的真正强大之处在于可以使用域名解析商提供的 api 自动添加 txt 记录完成验证.

acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的自动集成.

以 dnspod 为例, 你需要先登录到 dnspod 账号, 生成你的 api id 和 api key, 都是免费的. 然后:

1
2
3
4
5
export DP_Id="1234"

export DP_Key="sADDsdasdgdsf"

acme.sh --issue --dns dns_dp -d aa.com -d www.aa.com
ROUTEROS

证书就会自动生成了. 这里给出的 api id 和 api key 会被自动记录下来, 将来你在使用 dnspod api 的时候, 就不需要再次指定了. 直接生成就好了:

1
acme.sh --issue -d mydomain2.com --dns  dns_dp
STYLUS

更详细的 api 用法: https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

3. 其他的激活方式

https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert

3. copy/安装 证书

前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.

注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.

正确的使用方法是使用 --install-cert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:

Apache example:

1
2
3
4
5
acme.sh --install-cert -d example.com \
--cert-file /path/to/certfile/in/apache/cert.pem \
--key-file /path/to/keyfile/in/apache/key.pem \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd "service apache2 force-reload"
GRADLE

Nginx example:

1
2
3
4
acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"
STYLUS

(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)

我当时使用这个命令的时候发现用 service nginx force-reload 报没有权限,然后是将当前用户

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

--install-cert命令可以携带很多参数, 来指定目标文件. 并且可以指定 reloadcmd, 当证书更新以后, reloadcmd会被自动调用,让服务器生效.

详细参数请参考: https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc

值得注意的是, 这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用.

4. 查看已安装证书信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
acme.sh --info -d example.com
# 会输出如下内容:
DOMAIN_CONF=/root/.acme.sh/example.com/example.com.conf
Le_Domain=example.com
Le_Alt=no
Le_Webroot=dns_ali
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_Keylength=
Le_OrderFinalize=https://acme-v02.api.letsencrypt.org/acme/finalize/23xxxx150/781xxxx4310
Le_LinkOrder=https://acme-v02.api.letsencrypt.org/acme/order/233xxx150/781xxxx4310
Le_LinkCert=https://acme-v02.api.letsencrypt.org/acme/cert/04cbd28xxxxxx349ecaea8d07
Le_CertCreateTime=1649358725
Le_CertCreateTimeStr=Thu Apr 7 19:12:05 UTC 2022
Le_NextRenewTimeStr=Mon Jun 6 19:12:05 UTC 2022
Le_NextRenewTime=1654456325
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/etc/acme/example.com/privkey.pem
Le_ReloadCmd=service nginx force-reload
Le_RealFullChainPath=/etc/acme/example.com/chain.pem
ROUTEROS

5. 更新证书

目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.

请确保 cronjob 正确安装, 看起来是类似这样的:

1
2
3
crontab  -l

56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
JBOSS-CLI

6. 关于修改ReloadCmd

目前修改ReloadCmd没有专门的命令,可以通过重新安装证书来实现修改reloadCmd的目的。 此外,安装证书后,相关信息是保存在~/.acme.sh/example.com/example.conf文件下的,内容就是acme.sh --info -d example.com输出的信息,不过ReloadCmd在文件中使用了Base64编码。理论上可以通过直接修改该文件来修改ReloadCmd,且修改时,无需Base64编码,直接写命令原文acme.sh也可以识别。 不过,example.conf文件的位置和内容格式以后可能会改变!example.conf一直都是内部使用, 后面有可能会改为用 sqlite 或者mysql 格式存储. 所以一般不建议自己修改。

7. 更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步.

升级 acme.sh 到最新版 :

1
acme.sh --upgrade
STYLUS

如果你不想手动升级, 可以开启自动升级:

1
acme.sh --upgrade --auto-upgrade
STYLUS

之后, acme.sh 就会自动保持更新了.

你也可以随时关闭自动更新:

1
acme.sh --upgrade --auto-upgrade  0
STYLUS

8. 出错怎么办:

如果出错, 请添加 debug log:

1
acme.sh --issue  .....  --debug 
JBOSS-CLI

或者:

1
acme.sh --issue  .....  --debug  2
JBOSS-CLI

请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

最后, 本文并非完全的使用说明, 还有很多高级的功能, 更高级的用法请参看其他 wiki 页面.

https://github.com/Neilpang/acme.sh/wiki

Docker

1
2
3
4
5
docker run --rm  -itd  \
-v "$(pwd)/out":/acme.sh \
-e Ali_Key="xxxxxx" \
-e Ali_Secret="xxxx" \
neilpang/acme.sh --issue --dns dns_ali -d domain.cn -d *.domain.cn
SHELL

详细用法,可以参考:传送门

acme.sh 💕 docker

作为 docker 的忠实粉丝之一,我知道我们讨厌在 docker 主机上安装任何东西,即使它只是复制一个 shell 脚本。

用于 letsencrypt ssl 证书的带有 acme.sh 的自动化 nginx 反向代理 docker 图像: https: //github.com/Neilpang/letsproxy

部署到 docker 容器并重新加载它:https ://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers

所以,这里出现了“docker 中的 acme.sh”。

  1. 基于alpine,只有 5MB 大小。
  2. 作为可执行文件运行或作为守护进程运行
  3. 支持所有命令行参数。

1.说“Hello World”

1
docker run --rm neilpang/acme.sh
DOCKERFILE

2.用作可执行文件:

1
2
3
4
docker run --rm  -it  \
-v "$(pwd)/out":/acme.sh \
--net=host \
neilpang/acme.sh --issue -d example.com --standalone
STYLUS

您可以在此处使用acme.sh支持的任何命令,其他示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#revoke a cert
docker run --rm -it \
-v "$(pwd)/out":/acme.sh \
--net=host \
neilpang/acme.sh --revoke -d example.com
#use dns mode
docker run --rm -it \
-v "$(pwd)/out":/acme.sh \
neilpang/acme.sh --issue --dns -d example.com
#run cron job
docker run --rm -it \
-v "$(pwd)/out":/acme.sh \
--net=host \
neilpang/acme.sh --cron
STYLUS

无论如何,您可以像调用真正的 shell 脚本一样调用neilpang/acme.sh。

3. 将 acme.sh 作为 docker 守护进程运行。

  1. 将 acme.sh 作为 docker 守护进程运行,以便它可以自动处理更新 cronjob。
1
2
3
4
5
docker run --rm  -itd  \
-v "$(pwd)/out":/acme.sh \
--net=host \
--name=acme.sh \
neilpang/acme.sh daemon
ROUTEROS
  1. 然后你就可以使用docker exec来执行任何acme.sh 命令了。
1
2
docker  exec  acme.sh --help
docker exec acme.sh --issue -d example.com --standalone
STYLUS

是的,再次强调,您可以在此处使用acme.sh支持的任何命令

Certbot

https://certbot.eff.org/


Let's Encrypt SSL 证书申请
https://www.oikiou.top/2023/e7fefe87/
作者
Oikiou
发布于
2023年1月12日
许可协议