Docker使用acme.sh申请ssl证书

@Wen's  July 31, 2019

作为 docker 用户, 最不希望的就是别人污染 docker host, 哪怕是拷贝一个 纯 shell 脚本 都像是要了命.

话不多说:

  1. acme.sh 采用了最轻的 alpine base image.

  2. 并且支持作为可执行程序运行 和 作为守护进程 两种模式.

  3. 100% 支持 所有 acme.sh 已有的命令行参数.

在这里简要的说一下用法:

1. Hello world

docker run --rm neilpang/acme.sh

2. 作为可执行程序运行:

上面的 hello world 并不会产生什么实际效果. 只会显示出 acme.sh 的帮助信息.

我们生成一个证书试试:

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

注意上面最后一行, 可以携带所有 acme.sh 支持的命令行参数. 100% 兼容.

最后生成的证书都在 当前目录下的 out/ 里面.

3. 作为守护进程运行:

另外一种更方便的用法是作为守护进程运行, 这样做的好处是可以自动处理自动续签证书.

第一步启动 daemon:

docker run --rm  -itd  \
  -v "$(pwd)/out":/acme.sh  \
  --net=host \
  --entrypoint /bin/sh \
  --name=acme.sh \
  neilpang/acme.sh

第二步: 像 使用 shell 脚本一样使用 docker, 注意下面必须用 docker exec:

docker  exec  acme.sh --help
docker  exec  acme.sh --issue -d example.com  --standalone

这里的命令行上也可以携带所有 acme.sh 支持的命令行参数. 100% 支持.

详细的说明请见:

https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker


(补充)

关于acme.sh的介绍,请看这里

域名验证

为了验证域名所有权,Let's Encrypt支持两种域名验证方式:

  • 域名DNS解析:配置一个随机的 TXT 记录来验证

  • 域名URL访问:配置一个随机的 URL 地址来验证

我这里使用DNS解析的验证方式。

acme.sh通过阿里云开放的API和授权的AccessKey操作域名解析记录。

因此,需要到阿里云申请AccessKey,步骤略。

AccessKeyID:LTAI********3SqE
AccessKeySecret:lTA9************************Az15

颁发证书

Docker方式

# 使用守护进程的方式启动容器
docker run -itd --name acme.sh \
-e Ali_Key=LTAI********3SqE \
-e Ali_Secret=lTA9************************Az15 \
-v ${PWD}/acme.sh:/acme.sh \
neilpang/acme.sh daemon
# 颁发证书
docker exec -it acme.sh --issue --dns dns_ali -d yourdomain.com -d *.yourdomain.com

Docker Compose

docker-compose.yml:

version: "3"

services:
  nginx:
    image: nginx:1.14-alpine
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ${PWD}/nginx.d:/etc/nginx/conf.d
      - ${PWD}/acme.sh:/etc/acme.sh
    links:
      - ...
  acme.sh:
    image: neilpang/acme.sh
    restart: always
    command: daemon
    volumes:
      - ${PWD}/acme.sh:/acme.sh
    environment:
      - Ali_Key=LTAI********3SqE
      - Ali_Secret=lTA9************************Az15

启动方式:

docker-compose up -d acme.sh
docker-compose exec acme.sh --issue --dns dns_ali -d yourdomain.com -d *.yourdomain.com

Nginx配置SSL证书

配置证书文件

在/etc/nginx/conf.d/目前下添加ssl.conf,内容如下:

server {
    listen 443 default ssl;

    ssl on;
    ssl_certificate /etc/acme.sh/yourdomain.com/fullchain.cer;
    ssl_certificate_key /etc/acme.sh/yourdomain.com/yourdomain.com.key;
    ssl_session_timeout 5m;
}

以上配置中, 需将${PWD}/acme.sh挂载至容器的/etc/acme.sh;可以根据自己的实际情况修改

http请求强制跳转https

在/etc/nginx/conf.d/目前下添加redirect.conf,内容如下:

server {
    listen 80;
    server_name _;
    return 301 https://$host$request_uri;
}

修改监听端口

最后,将/etc/nginx/conf.d/目录下其他的conf文件添加443端口的监听.


问:为什么使用守护进程的方式启动容器?
答:Let's Encrypt证书有效期为3个月;acme.sh可以自动更新证书;而自动更新需要容器的定时任务触发.

问:为什么不用系统的定时服务执行更新证书的任务?这样做有什么优点和缺点?
答:洁癖!不想在host机器上为容器服务做额外配置.



添加新评论