写一个删除旧证书脚本
#!/bin/bash
# 定义一个函数,用于检查并删除指定目录
delete_if_old() {
local domain_name="$1"
local age_minutes="$2"
local live_dir="/etc/letsencrypt/live/$domain_name"
local archive_dir="/etc/letsencrypt/archive/$domain_name"
# 检查 /etc/letsencrypt/live/ 下的目录是否存在且修改时间超过指定分钟数
if [ -d "$live_dir" ] && [ "$(find "$live_dir" -maxdepth 0 -mmin +$age_minutes)" ]; then
echo "Deleting $live_dir ..."
rm -rf "$live_dir"
echo "Deleting $archive_dir ..."
rm -rf "$archive_dir"
else
echo "$live_dir does not exist or is not old enough."
fi
}
# 调用函数,删除超过43200分钟的目录
delete_if_old blog.example.com 1440
nginx 域名配置
server {
listen 80;
listen [::]:80;
listen 443 ssl;
server_name blog.example.com;
ssl_certificate /etc/letsencrypt/cert/blog.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/cert/blog.example.com/privkey.pem;
location ~/.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location = /xmlrpc.php {
return 403;
}
location / {
if ($block_ip) {
return 403; # 返回 403 Forbidden
}
#limit_req zone=mylimit burst=4 nodelay;
#limit_req_status 598;
proxy_pass http://wordpress/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
编写定时
0 7 * * 6 docker cp /data/app/delete_old_cert_blog.sh nginx:/delete_old_cert_blog.sh
1 7 * * 6 docker exec nginx /bin/bash -c '/delete_old_cert_blog.sh'
2 7 * * 6 docker run --rm --volumes-from nginx certbot/certbot certonly --force-renewal --webroot --non-interactive --agree-tos --webroot-path=/usr/share/nginx/html -m admin@qq.com -d blog.example.com
3 7 * * 6 docker exec nginx bash -c 'cp -rfL /etc/letsencrypt/live/* /etc/letsencrypt/cert'
4 7 * * 6 docker exec nginx bash -c 'nginx -s reload'
这里有3个注意点
1.crontab里不能用docker exec -it 这种交互式脚本,用了也执行不了。
2.这里不用/etc/letsencrypt/live/作为nginx的配置目录,因为脚本删除旧配置文件的操作会导致网站访问失效,所以这里用live目录生成的复制到/etc/letsencrypt/cert作为nginx的证书目录
3.--webroot-path=/usr/share/nginx/html这里对应nginx里
location ~/.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
这里的root路径,如果有多个域名,分时段执行时不用改这个路径,同时执行最好改下这个路径。
注意上面3点即可保持证书更新,上面脚本已经稳定运行两年,然后宝塔证书续签现在还有bug
定时改成acme脚本
0 7 * * 6 docker cp /data/app/delete_old_cert_blog.sh nginx:/delete_old_cert_blog.sh
1 7 * * 6 docker exec nginx /bin/bash -c '/delete_old_cert_blog.sh'
2 7 * * 6 docker run --rm --volumes-from nginx neilpang/acme.sh --issue -d blog.example.com --webroot /usr/share/nginx/html --accountemail admin@qq.com --force --staging
3 7 * * 6 docker exec nginx bash -c 'cp -rfL /etc/acme.sh/blog.example.com/fullchain.cer /etc/letsencrypt/live/blog.example.com/fullchain.pem && cp -rfL /etc/acme.sh/blog.example.com/blog.example.com.key /etc/letsencrypt/live/blog.example.com/privkey.pem'
4 7 * * 6 docker exec nginx bash -c 'nginx -s reload'
由于现在证书透明工具如:crt.sh | Certificate Search 可以快速找到域名下的https域名,会导致一些测试用途的域名,如小程序开发域名遭受频繁攻击,所以能申请泛域名就申请泛域名。
acme泛域名dnspod脚本申请
0 7 * * 6 docker cp /data/app/delete_old_cert_blog.sh nginx:/delete_old_cert_blog.sh
1 7 * * 6 docker exec nginx /bin/bash -c '/delete_old_cert_blog.sh'
2 7 * * 6 docker run --rm --volumes-from nginx -e DP_Id=your_dp_id -e DP_Key=your_dp_key neilpang/acme.sh --issue --dns dns_dp -d blog.example.com -d *.blog.example.com --accountemail admin@qq.com --force --staging
3 7 * * 6 docker exec nginx bash -c 'cp -rfL /etc/acme.sh/blog.example.com/fullchain.cer /etc/letsencrypt/live/blog.example.com/fullchain.pem && cp -rfL /etc/acme.sh/blog.example.com/blog.example.com.key /etc/letsencrypt/live/blog.example.com/privkey.pem'
4 7 * * 6 docker exec nginx bash -c 'nginx -s reload'