acme.sh踩坑:记一次坑爹的https证书申请经历

Published on 2021-03-30 10:53 in 分类: 软件 with 狂盗一枝梅
分类: 软件

acme.sh踩坑:记一次坑爹的https证书申请经历

我的博客网站申请的免费的https证书快到期了,之前使用的是 https://zerossl.com/ 申请的免费证书,没想到用了几次之后就不给用了,到了最大使用免费次数云云。。

image-20210329160535915

之后,我找到了acme.sh这个牛逼的工具,这个工具封装了实现了 acme 协议, 可以从 letsencrypt 生成免费的证书,而且还支持自动续签操作。

acme.sh是个开源项目,github地址:https://github.com/acmesh-official/acme.sh ,中文使用说明:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

关于具体使用方式,在官方的中文文档中已经做了详细的说明,就不多做解释了。说下我遇到的问题吧。

1.初始脚本和遇到的问题

我使用nginx作为博客网关并做请求转发,但是这个nginx是用docker部署的,博客的mysql、nginx以及后端的java程序都是使用docker-compose做的编排。

nginx是使用官方1.16版本的镜像直接创建的容器,这就意味着如果想实现https证书自动续签功能,就要把acme.sh安装到容器内。

nginx容器内运行的应该是debian linux,我写了个脚本实现安装

#!/bin/bash
  
mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
echo "deb http://mirrors.163.com/debian/ buster main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ buster-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ buster-backports main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian-security/ buster/updates main non-free contrib" >>/etc/apt/sources.list

export DEBIAN_FRONTEND=noninteractive
apt-get update &&
    apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes &&
    apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -q -y --force-yes

apt -y update
apt-get install -y gnupg2
apt-get install -y ca-certificates
apt install -y --no-install-recommends curl
apt-get install -y cron
apt-get install -y socat
apt-get install -y vim

mkdir /usr/local/etc/blog

blue(){
    echo -e "\033[34m\033[01m$1\033[0m"
}
green(){
    echo -e "\033[32m\033[01m$1\033[0m"
}
red(){
    echo -e "\033[31m\033[01m$1\033[0m"
}

cd /usr/sbin

your_domain="blog.kdyzm.cn"
        green " "
        green " "
        green "=========================================="
		blue "获取到你的域名为 $your_domain"
        green "=========================================="
        sleep 3s
    green " "
        green " "
        green "=========================================="
        blue "安装acme.sh 并开始签发证书"
        green "=========================================="
        sleep 3s

/usr/sbin/nginx -s reload

        curl https://get.acme.sh | sh
        ~/.acme.sh/acme.sh --issue -d $your_domain --nginx
        ~/.acme.sh/acme.sh --installcert -d $your_domain --key-file /usr/local/etc/blog/private.key --fullchain-file /usr/local/etc/blog/cert.crt
        ~/.acme.sh/acme.sh --upgrade --auto-upgrade
        chmod -R 755 /usr/local/etc/blog

if test -s /usr/local/etc/blog/cert.crt; then

/usr/sbin/nginx -s reload

        green "=========================================="
                blue "检测到证书已经正常签发"
        green "=========================================="
else
        green "=========================================="
                red "证书签发失败,请重新尝试"
        green "=========================================="
fi

这个脚本修改过很多次,理论上是没有问题的,但是最后却卡在了github下载上,死活下载不动,试过修改dns的方法,但是没有生效

github在大陆访问极其不友好,使用curl下载东西肯定超时

2.修改脚本

仔细看看官网,除了在线安装的方法之外,还有离线安装解决方案,那就是git clone 项目之后,直接执行acme.sh脚本,这时候就不会自动到github下载了,修改之后的脚本

#!/bin/bash
  
mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
echo "deb http://mirrors.163.com/debian/ buster main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ buster-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ buster-backports main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian-security/ buster/updates main non-free contrib" >>/etc/apt/sources.list

export DEBIAN_FRONTEND=noninteractive
apt-get update &&
    apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes &&
    apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -q -y --force-yes

apt -y update
apt-get install -y gnupg2
apt-get install -y ca-certificates
apt-get install -y curl
apt-get install -y cron
apt-get install -y socat
apt-get install -y vim

mkdir /usr/local/etc/blog
blue(){
    echo -e "\033[34m\033[01m$1\033[0m"
}
green(){
    echo -e "\033[32m\033[01m$1\033[0m"
}
red(){
    echo -e "\033[31m\033[01m$1\033[0m"
}

cd /usr/sbin

your_domain="blog.kdyzm.cn"
        green " "
        green " "
        green "=========================================="
                        blue "获取到你的域名为 $your_domain"
        green "=========================================="
        sleep 3s
    green " "
        green " "
        green "=========================================="
        blue "       安装acme.sh 并开始签发证书"
        green "=========================================="
        sleep 3s

/usr/sbin/nginx -s reload

#        curl https://get.acme.sh | sh
        cd /acme
        chmod a+x ./acme.sh
        ./acme.sh --install -m kdyzm@foxmail.com
        ~/.acme.sh/acme.sh --issue -d $your_domain --nginx
        ~/.acme.sh/acme.sh --installcert -d $your_domain --key-file /usr/local/etc/blog/private.key --fullchain-file /usr/local/etc/blog/cert.crt
        #~/.acme.sh/acme.sh --upgrade --auto-upgrade
        chmod -R 755 /usr/local/etc/blog

if test -s /usr/local/etc/blog/cert.crt; then

/usr/sbin/nginx -s reload

        green "=========================================="
                blue "检测到证书已经正常签发"
        green "=========================================="
else
        green "=========================================="
                red "证书签发失败,请重新尝试"
        green "=========================================="
fi

我将curl https://get.acme.sh | sh这行代码注释掉,使用了本地安装的方法,但是这时候需要手动将acme.sh代码拉下来并拷贝到容器;同时,要关闭自动更新,因为自动更新还会下载github上的代码。

3.修改nginx配置

证书申请完成之后生成了两个关键文件在/usr/local/etc/blog文件夹:private.key以及cert.crt,nginx的https配置需要这两个文件,

server {
        listen 443;
        ssl on;
        server_name  blog.kdyzm.cn;
        ssl_certificate  /usr/local/etc/blog/cert.crt;
        ssl_certificate_key /usr/local/etc/blog/private.key;
        location / {
            proxy_pass   http://....;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Proto https;
            client_max_body_size  20m;
        }
    }

提前准备好这个文件,执行完成脚本之后会自动重启nginx,该文件中的配置会自动生效。

4.注意事项

  • /usr/local/etc/blog/private.key 和 /usr/local/etc/blog/cert.crt 在未正式申请证书之前就要存在,否则nginx会检测不到有效证书而陷入无限重启中
  • 容器全部启动之后进入nginx容器(使用命令 docker exec -it 容器id /bin/bash),执行申请证书脚本

#acme #https
目录