by Devin Yang

建立于: 5年前 ( 更新: 5年前 )

前言

本文主要分享,我如何采用Docker的方式进行Let's Encrypt证书申请,
Let's Encrypt有相当多种类的ACME Client,
我将使用官方推^Certbot(ACME Client)做说明。
并且使用docker的方式来运行ACME Client。
这样做对笔者来说,有两个好处:

一、我不需要在主机端(host),使用最高权限(root),跑certbot进程,也不需安装相关运行Client的Python环境。

二、粘贴命令,自动下载Client并运行,然后取得证书,当您理解docker命令及certbot参数后,这将会是非常简易的一件事情。

Dockerfile

再开始前,我们先来看看Certbot所提供的Dockerfile设置。
理解Dockerfile的设置,有助於我们了解等下要运行命令的目地,所以我们来稍微看看吧。
Dockerhub的位置,请参看这里:https://hub.docker.com/r/certbot/certbot
FROM python:2-alpine3.7

ENTRYPOINT [ "certbot" ]
EXPOSE 80 443
VOLUME /etc/letsencrypt /var/lib/letsencrypt
WORKDIR /opt/certbot

COPY CHANGELOG.md README.rst setup.py src/
COPY acme src/acme
COPY certbot src/certbot

RUN apk add --no-cache --virtual .certbot-deps \
        libffi \
        libssl1.0 \
        openssl \
        ca-certificates \
        binutils
RUN apk add --no-cache --virtual .build-deps \
        gcc \
        linux-headers \
        openssl-dev \
        musl-dev \
        libffi-dev \
    && pip install --no-cache-dir \
        --editable /opt/certbot/src/acme \
        --editable /opt/certbot/src \
    && apk del .build-deps
可以看见,上方的ENTRYPOINT就是certbot命令,我们可以由host代入参数端运行container内命令。

如何用certbot取得证书

我将他分为四种运用情境,并不是四个步骤哦。
情境二,只需一行命令,就可以生成证书的。
请留意docker命令中,certbot/certbot之后所代入的参数,
不同的情境,使用了不同的参数哦。

情境一、manual手动设置
代表当网页伺服器,是远程的主机,我们想在自己的电脑生成证书给该主机用时。
因为要挂载目录到container中,让生成的证书可以写我们的主机。
请先创建数据夹。
mkdir -p /etc/letsencrypt
再用下方的命令生成证书(请自己换成您自己的邮件哦)
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -ti certbot/certbot certonly --manual --email devin@ccc.tc --agree-tos
过程中,会询问我们,要使用那个域名,并且会要求我们将challenage的信息,放到远程网页伺服器上。
这里提供我的做法,直接ssh到该主机,拷贝certbot要求的相关信息,用echo标准输出,透过大於,重导成文件即可。
 
ssh root@我的主机
cd /var/www/html/.well-known/acme-challenge/
echo LW_70m1q1QWIAxktnR8rU3QK4znLP9iyvp1Uf3mBsU4._ZtWqdsZpgLv_TS7hHMCm0zcL8HXhJrGePNrNSSi23Y> LW_70m1q1QWIAxktnR8rU3QK4znLP9iyvp1Uf3mBsU4
完成后,再压Enter,如果他能经由网址连到该档验证通过,就会将证书发出,放至於/etc/letsencrypt下的相关目录中。


情境二、certonly只生成证书
代表了,透过运行中的网页伺服器来生成证书,简单说我们要运行命令的地方,
已经有一台活生生的网页伺服器运作中了。

运行命令前,请先确认主机端有这两个目录。
mkdir -p /etc/letsencrypt
mkdir -p /var/www/html/.well-known/acme-challenge
(这里假定您运作中的主机的网站根目录是在/var/www/html下,另外,请自行换成生成证书的域名,用www.ccc.tc是过不了的
如果您的目录不是/var/www/html请自行调整挂载的位置。
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/www/html:/html -ti certbot/certbot certonly --email devin@ccc.tc --agree-tos --webroot -w /html -d www.ccc.tc
上方命令,使用了-v的参数分别挂载了host端的两个数据夹。
/etc/letsencrypt  (证书与let's encrypt设置)
/var/www/html (网站的根目录)
另外多出了--webroot -w /html 这是什么意思呢?
这里是我定义了网站的根目录是/html (容器内)。不过我们透过了docker的-v /var/www/html:/html参数,
将host端的真正的跟目录/var/www/html挂载进了容器的/html中了。

所以certbot可将challenge的档写到我们的网站目录下。
/var/www/html/.well-known/acme-challenge
也就是说他会来连结我们主机上的由certbot随机生成文件及内容。
http://www.ccc.tc/.well-know/acme-challenge/0wCvy2q6URD-AwFTJQGUkz5sug6d3ptGp6QQGzqe1Eg

通过后,certbot便会将证书及设置存入host端的/etc/letsencrypt中(-v /etc/letsencrypt:/etc/letsencrypt)。
因此,同样的docker挂载方式,将certbot的entrypoint后,变更成renew,在证书快到其时,就能自动更新罗。
0 0 * * * docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/www/html:/html -ti certbot/certbot renew
试运行renew,可以看见,显示证书未过期:
root@ccc:~# docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/www/html:/html -ti certbot/certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.cc.tc.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/www.ccc.tc/fullchain.pem expires on 2019-04-12 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

情境三、standalone独立伺服器
当certbot多了--standalone参数时,代表了,他自己会创建一台challenges的http伺服器,因此,您应该确认您的防火墙是有开启port 80的,
下方的例子中-d后面所代入的域名的DNS正解,需能解析出您电脑所使用的外网IP。
docker run --rm  -v /etc/letsencrypt:/etc/letsencrypt  -p 80:80 -ti certbot/certbot certonly --standalone --email devin@ccc.tc --agree-tos --preferred-challenges http -d test1.ccc.tc
这个例字中,由certbot帮我们创建一台webserver接收challenge并生成证书。
很明显的,可以看到,这里透过-p将在主机端开启port 80并mapping到容器中的port 80。
另外当然要挂载容器内的/etc/letsencrypt,用来保留生成的证书,
由於docker参数中,我加了--rm,当执容器运行完必后,是会自动被移除的,
所以我们要透过-v挂载/etc/letsencrypt来保留设置及获取证书。

所以,不需要有网页伺服器,docker run时,certbot就会独立生成一台网页伺服器,作业结束后该主机就被停止。
然后,我们的/etc/letsencrypt上,就有该证书了。

关於-v左方的/etc/letsencrypt目录是可以自定义的。
如果我是在自己的家目录中建了letsencrypt数据夹,就可以设置如下的方式挂载 -v ${HOME}/letsencrypt:/etc/letsencrypt。
${HOME}指的就是我们的家目录,您可以用MacOS或Linux系统上echo ${HOME}看看。
希望大家能思考及了解参数背后的意义,进而依自己的环境需求调整参数,而不是只调整域名及邮件,就粘贴。

情境四、wildcard证书申请
如果我们要生成任意的子域名证书(*.ccc.tc),就可以用下方的命令。
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -ti certbot/certbot certonly --agree-tos --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory -d "*.ccc.tc"
wildcard的证书需采用dns进行challenge,所以您必需要能调整DNS Server,添加他要求的txt日志进行验证。
 

最后

如果您能成功的用docker的方式生成证书。其实参数都是一样的,
在无docker的环境,你也可以直接安装certbot档,直接使用certbot命令来生成证书。
把下方整段的docker命令
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/www/html:/html -ti certbot/certbot
想成运行certbot命令即可
/usr/bin/certbot


网页伺服器的证书设置,不在本篇的讨论范围,但是这里给大家一点小提示,在第二种的certonly的设置中,
因为生成证书主机跟网页主机是同一台上,我们可以直接将证书设置写到网页伺服器的设置中,以Apache为例:
SSLCertificateFile    /etc/letsencrypt/live/www.ccc.tc/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.ccc.tc/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.ccc.tc/chain.pem
加上调度每天检测certbot renew及如下命令来重启主机。
service httpd graceful
如此一来,就可以神不知鬼不觉的自动更新证书啦。
如果您的主机是nginx,可以用
nginx -s reload
如果是在container(容器)内的主机,我相信这招应该通杀,您或许可以试试 :)
https://www.ccc.tc/notes/50

看完本文,您是否发觉证书申请,简单到爆炸呢,自动化也不难,不是吗?



 

Tags: ssl certbot

Devin Yang

文章内容无法一一说明,如果您有什么不了解处,欢印提问哦:)

No Comment

Post your comment

需要登入才可留言!

类似文章


openssl

如何移除PEM的密码

您可以使用openssl rsa命令删除密码。 我们传入SSL .key并获得一个.key文档作为输出。

ssl,haproxy,certbot

完美SSL证书自动化更新环境(HAProxy加certbot)

HAProxy的重载速度很快,跟本感觉不出有重启,所有证书都给HAProxy处理真的很方便。主机环境需求,请确认您已有下面两个命令(Ubuntu怎么装? apt-get install -y haproxy cerbot,我猜的,如果不是请自行Google)

php openssl curl

修正CA设置问题

有时可能PHP版本更新或环境变动造成找不到ca文件。 修正很简单