acme.sh踩坑:记一次坑爹的https证书申请经历
我的博客网站申请的免费的https证书快到期了,之前使用的是 https://zerossl.com/ 申请的免费证书,没想到用了几次之后就不给用了,到了最大使用免费次数云云。。
之后,我找到了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),执行申请证书脚本
注意:本文归作者所有,未经作者允许,不得转载