Docker部署acme.sh申请Let's encrypt泛域名证书

Docker部署acme.sh申请Let's encrypt泛域名证书

  • 一:手动安装acme.sh
  • 二:申请证书
    • 2.1 DNSAPI申请方式
    • 2.2 DNS手动校验方式
    • 2.3 HTTP校验方式申请
    • 2.4 无80端口申请证书
    • 2.5 证书续签
  • 三:Docker部署acme.sh申请证书
    • 3.1 安装docker-compose
    • 3.2 启动容器
    • 3.3 申请证书
    • 3.4 设置 crontab 任务自动续签
  • 四:nginx配置

一:手动安装acme.sh

本次测试系统为:Ubuntu16.04

curl https://get.acme.sh | sh
# 也可以使用wget方式:wget -O - https://get.acme.sh | sh
source ~/.bashrc

然后可以执行下面的命令获取 acme.sh 更新,并设置之后都自动更新 acme.sh 脚本

acme.sh --upgrade --auto-upgrade

二:申请证书

使用acme.sh有三种申请方法

  1. 使用HTTP校验方式申请证书
  2. 使用DNS手动校验方式申请证书
  3. 使用DNSAPI校验方式申请证书

2.1 DNSAPI申请方式

github上的How to use DNS API
下面以godaddy域名为例申请泛域名证书,方式需要先获取godaddy账号的API信息,获取地址
Docker部署acme.sh申请Let's encrypt泛域名证书
申请完成后记录下Key与Secret,然后在命令行导入key与secret

export GD_Key="xxxxxxxxxxxxxxxxxxxxxxx"
export GD_Secret="xxxxxxxxxxxxxxxxxxxx"
# 上面的信息会保存在 .acme.sh/account.conf配置文件中
# 注意:GD_Key, GD_Secret根据域名商的不同而不一样,具体见github

导入完成后开始申请域名证书:

acme.sh --issue --dns dns_gd -d example.com -d '*.example.com'  # dns_gd这个参数根据域名商不同会不一样
...............................................................
# 该命令执行完成后,会显示证书所在的路径
# 证书保存路径:~/.acme.sh

nginx的配置:

server {
        listen 443;
        server_name  task.example.com;
        root   /wwwroot/task/front-web;
        access_log  logs/task.access.log  main;
        error_log  logs/task.error.log  error;
        # 修改下面两行代码后面的证书路径即可
        ssl_certificate /home/ubuntu/.acme.sh/example.com/fullchain.cer;
        ssl_certificate_key /home/ubuntu/.acme.sh/example.com/example.com.key;
        location / {
            index  index.html index.htm;
        }
        ............................
}
server {
        listen 80;
        server_name task.inve.one;
        if ($host = task.inve.one) {
                return 301 https://$host$request_uri;
        }
}

2.2 DNS手动校验方式

通配符证书,英文 Wildcard Certificate 国内黑话叫做野卡,经过一个月的跳票后,Let’s Encrypt 目前已经支持通配符的证书,同样 acme.sh 也是支持的,和多域名证书不同,通配符证书必须使用 DNS TXT 记录验证方式

acme.sh --issue -d example.com -d '*.example.com' --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
[Tue Mar 20 16:34:35 HKT 2018] Domains have changed.
[Tue Mar 20 16:34:35 HKT 2018] Registering account
[Tue Mar 20 16:34:36 HKT 2018] Registered
[Tue Mar 20 16:34:36 HKT 2018] ACCOUNT_THUMBPRINT='blablablabla'
[Tue Mar 20 16:34:36 HKT 2018] Multi domain='DNS:example.com,DNS:*.example.com'
[Tue Mar 20 16:34:36 HKT 2018] Getting domain auth token for each domain
[Tue Mar 20 16:34:38 HKT 2018] Getting webroot for domain='example.com'
[Tue Mar 20 16:34:38 HKT 2018] Getting webroot for domain='*.example.com'
[Tue Mar 20 16:34:38 HKT 2018] Add the following TXT record:
[Tue Mar 20 16:34:38 HKT 2018] Domain: '_acme-challenge.example.com'
[Tue Mar 20 16:34:38 HKT 2018] TXT value: 'blablablabla1'
[Tue Mar 20 16:34:38 HKT 2018] Please be aware that you prepend _acme-challenge. before your domain
[Tue Mar 20 16:34:38 HKT 2018] so the resulting subdomain will be: _acme-challenge.example.com
[Tue Mar 20 16:34:38 HKT 2018] Add the following TXT record:
[Tue Mar 20 16:34:38 HKT 2018] Domain: '_acme-challenge.example.com'
[Tue Mar 20 16:34:38 HKT 2018] TXT value: 'blablablabla2'
[Tue Mar 20 16:34:38 HKT 2018] Please be aware that you prepend _acme-challenge. before your domain
[Tue Mar 20 16:34:38 HKT 2018] so the resulting subdomain will be: _acme-challenge.example.com
[Tue Mar 20 16:34:38 HKT 2018] Please add the TXT records to the domains, and re-run with --renew.
[Tue Mar 20 16:34:38 HKT 2018] Please add '--debug' or '--log' to check more details.
[Tue Mar 20 16:34:38 HKT 2018] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

接着你需要给 _acme-challenge.example.com 增加两个 TXT 记录 “blablablabla1” 和 “blablablabla2”,然后等 DNS 生效(两个TXT值在上面的命令中输出了)
Docker部署acme.sh申请Let's encrypt泛域名证书
检查是否生效:

root@example ~ # dig TXT _acme-challenge.example.com @9.9.9.9 +short
"blablablabla1"
"blablablabla2"

TXT记录生效后才能申请证书:

root@example ~ # acme.sh --renew -d example.com -d '*.example.com' --force --yes-I-know-dns-manual-mode-enough-go-ahead-please
[Tue Mar 20 16:41:25 HKT 2018] Renew: 'example.com'
[Tue Mar 20 16:41:26 HKT 2018] Multi domain='DNS:example.com,DNS:*.example.com'
[Tue Mar 20 16:41:26 HKT 2018] Getting domain auth token for each domain
[Tue Mar 20 16:41:26 HKT 2018] Verifying:example.com
[Tue Mar 20 16:41:29 HKT 2018] Success
[Tue Mar 20 16:41:29 HKT 2018] Verifying:*.example.com
[Tue Mar 20 16:41:32 HKT 2018] Success
[Tue Mar 20 16:41:32 HKT 2018] Verify finished, start to sign.
[Tue Mar 20 16:41:33 HKT 2018] Cert success.
-----BEGIN CERTIFICATE-----
# 这里是证书文件
-----END CERTIFICATE-----
[Tue Mar 20 16:41:33 HKT 2018] Your cert is in  /root/.acme.sh/example.com/example.com.cer 
[Tue Mar 20 16:41:33 HKT 2018] Your cert key is in  /root/.acme.sh/example.com/example.com.key 
[Tue Mar 20 16:41:33 HKT 2018] The intermediate CA cert is in  /root/.acme.sh/example.com/ca.cer 
[Tue Mar 20 16:41:33 HKT 2018] And the full chain certs is there:  /root/.acme.sh/example.com/fullchain.cer 
[Tue Mar 20 16:41:33 HKT 2018] It seems that you are using dns manual mode. please take care: The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
[Tue Mar 20 16:41:33 HKT 2018] Call hook error.

2.3 HTTP校验方式申请

HTTP校验方式需要申请的域名80端口可以访问

# www.example.com必须可以正常访问,否则无法通过校验
acme.sh --issue -d example.com -d *.example.com -w /wwwroot/www/example

2.4 无80端口申请证书

如果你本地没有装任何 Web 服务器软件,或者你的 Web 服务器软件并没有监听 TCP 80 端口,那么可以用 Standalone 方式直接获取多域名证书,注意以下操作必须使用 root 或 sudo 切换
我们以 example.com / www.example.com / subdomain.example.com 这三个域名为例
首先,你需要把这三个域名都解析到你的服务器 IPv4 上,并且确保你的服务器可以访问公网,无法访问公网的内网服务器是不行的
另外,你也可以给 example.com 增加一个 CAA 记录为 0 issue “letsencrypt.org” 这样可以告诉 Let’s Encrypt 的 CA ,你授权给他们签发 SSL 证书

acme.sh --issue --standalone -d example.com -d www.example.com -d subdomain.example.com

通过这个方式,即可为 example.com www.example.com 和 subdomain.example.com 三个域名签发一张多域名证书

2.5 证书续签

安装了ACME后,它会添加一个自动任务到你服务器的Cron里,每天都会检查你的Let’s Encrypt免费泛域名证书是否快要过期,ACME会自动帮你续签。

ubuntu@ip-172-31-31-252:~$ crontab -l
....................................
12 0 * * * "/home/ubuntu/.acme.sh"/acme.sh --cron --home "/home/ubuntu/.acme.sh" > /dev/null

三:Docker部署acme.sh申请证书

Docker在ubuntu上的安装见:Docker(一):安装Dodcker

3.1 安装docker-compose

可以不安装docker-compose,使用命令行直接启动容器,为了方便管理,这里以docker-compose来启动docker
安装方式一
先下载docker-compose二进制文件

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

赋予该文件可执行权限

sudo chmod +x /usr/local/bin/docker-compose

最后检查docker-compose是否安装成功

docker-compose --version
docker-compose version 1.23.1, build 1719ceb

安装方式二

# 没有pip,需要先安装pip
pip install docker-compose

3.2 启动容器

这里以阿里云域名做为演示,docker-compose文件如下:

version: "3"
services:
  acme.sh:
    image: neilpang/acme.sh
    container_name: acme-chainfin
    restart: always
    command: daemon
    environment:
      - Ali_Key=xxxxxxxx
      - Ali_Secret=xxxxxxxxxx
    volumes:
      - /data/acme_docker/chainfin.online:/acme.sh
    network_mode: host

Ali_Key,Ali_Secret为阿里云账号API的accesskey
保存后在 docker-compose.yml 同目录下运行如下命令启动 acme.sh。如果更改了 docker-compose.yml 文件,只要在此运行如下命令,就能够更新到最新状态。

docker-compose up -d

3.3 申请证书

sudo docker exec acme-chainfin --issue --dns dns_ali -d example.com -d '*.example.com' --keylength ec-384

3.4 设置 crontab 任务自动续签

运行 crontab -e 来编辑 crontab 文件,添加如下内容,保存即可

*/10 0 * * * docker exec acme.sh --cron		# acme.sh为容器名

四:nginx配置

设置域名www.example.com与example.com都跳转到https://www.example.com

server {
	listen  80;
	server_name example.com www.example.com;
	rewrite ^/(.*)  https://www.example.com/$1 permanent;
}
server {
	listen 443;
	server_name example.com;
	rewrite ^/(.*)  https://www.example.com/$1 permanent;
	ssl_certificate /opt/example.com_ecc/fullchain.cer;
	ssl_certificate_key /opt/example.com_ecc/example.com.key;

}
server {
	listen 443 default_server ssl;
    server_name www.example.com;
    root /application/nginx/html/linker-front/;
    location / {
        index index.html index.htm;
    }
    access_log  /var/log/nginx/linker.access.log  main;
    error_log  /var/log/nginx/linker.error.log  error;
	ssl_certificate /opt/example.com_ecc/fullchain.cer;
	ssl_certificate_key /opt/example.com_ecc/example.com.key;
    location /admin {
        alias "/application/nginx/html/linker-manage";
    }
    location /linker {
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_pass http://172.17.0.1:8082/linker;
         # 下面三项配置转发websocket请求
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
    }
    
}

你可能感兴趣的:(Linux运维)