# Acme申请SSL证书实践

TIP
申请域名证书的过程中,发现Acme基本是最优的选择,但是申请过程有点复杂。发现x-ui有集成优化使用Cloudflare DNS API进行证书申请,这个刚好是自己想要的,另外不需要x-ui还担心多余资源占用,就把这部分单独分离出来
# 证书申请
使用该脚本申请证书,需满足以下条件:
- 知晓Cloudflare 注册邮箱
- 知晓Cloudflare Global API Key
- 域名已添加到cloudflare且已激活
使用Cloudflare DNS API进行证书申请,需要获取API Key以及对应的账户邮箱。Cloudflare的API key可在“我的个人资料”->”API 密钥“中进行查看。
登陆服务器,输入以下代码
wget https://raw.githubusercontent.com/zhongziso/Acme_OneKeyAllInOne/refs/heads/main/ssl_cert_issue.sh -O ssl_cert_issue.sh && chmod +x ssl_cert_issue.sh && clear && ./ssl_cert_issue.sh
第一步确认以上内容按y回车 第二步输入你要申请SSL证书的域名 第三步输入刚才获取的Global API Key 第四步输入cloudflare账号邮箱,回车等待域名证书申请
注意事项:
- 该脚本使用DNS API进行证书申请
- 默认使用Let'sEncrypt作为CA方
- 证书安装目录为/root/cert目录
- 本脚本申请证书均为泛域名证书
证书申请成功,比如申请的是discuz.eu.org,对应的证书在下列位置
/root/cert/discuz.eu.org.cer(这是域名的服务器证书,也称为公钥证书或站点证书) /root/cert/discuz.eu.org.key(这是域名的服务器私钥,与公钥配对) /root/cert/ca.cer(这是证书颁发机构的证书,也称为根证书或中间证书)
# 证书复制
NOTE
证书已经申请成功,但有时遇到程序固定了ssl证书位置,也就是我们要证书放置的位置是不同目录时,需要做一个复制脚本
新建一个文件,比如copy_cert_files.sh
nano copy_cert_files.sh
输入以下内容
#!/bin/bash
# 定义源文件路径
CERT_DIR="/root/cert"
SOURCE_CERT="${CERT_DIR}/discuz.eu.org.cer"
SOURCE_KEY="${CERT_DIR}/discuz.eu.org.key"
SOURCE_CA="${CERT_DIR}/ca.cer"
# 定义目标路径
TARGET_DIR="/etc/nginx/ssl"
TARGET_CERT="${TARGET_DIR}/server.crt"
TARGET_KEY="${TARGET_DIR}/server.key"
TARGET_CA="${TARGET_DIR}/ca.cer"
# 执行复制并替换文件
cp -f $SOURCE_CERT $TARGET_CERT
cp -f $SOURCE_KEY $TARGET_KEY
cp -f $SOURCE_CA $TARGET_CA
# 输出复制结果
echo "文件已成功复制并替换到 $TARGET_DIR"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1.保存文件:
- 编辑完文件后,按 Ctrl + O(字母 "O" 是 "Output" 的意思)。
- Nano 会提示 File Name to Write:,即文件名,如果文件名正确,直接按 Enter。
2.退出编辑器:
- 按 Ctrl + X 退出 nano 编辑器
# 赋予脚本执行权限
chmod +x copy_cert_files.sh
# 创建定时任务
使用cron定时任务,每天凌晨 1 点执行该脚本。
1.打开 crontab 编辑器:
crontab -e
2.按i键进入编辑模式添加以下定时任务:
0 1 * * * /root/copy_cert_files.sh
3.按ESC键退出编辑模式,输入:wq保存并退出 crontab
# 关于Acme
IMPORTANT
我们通常说的acme一般是指acme脚本,用于方便快捷地申请证书。实际上acme自身是一种协议,其英文全称为Automated Certificate Management Environment,最早由Let‘s Ecrypt进行开发。
在这里我们引用acme仍特指acme脚本。Acme脚本在申请证书时支持多种系统环境,支持多个CA方,如Let‘s Encrypt、ZeroSSL、BuyPass等,同时还支持多种方式进行申请,具体包括:
1.Webroot模式 2.Standalone模式 3.Apache模式 4.Nginx模式 5.DNS模式 备注:此处所列模式未详尽
WARNING
本身acme支持申请泛域名证书,关于何为泛域名证书这里不做过多解释。申请泛域名证书时参数为*.example.com即可使n个三级域名(a.example.com,b.example.com,c.example.com…)都使用该证书
CAUTION
本文只是使用了该脚本的DNS模式,有更多需要的可以到网上了解更详细的资料
ssl申请代码
#!/bin/bash
ssl_cert_issue() {
echo ""
echo "******使用说明******"
echo "该脚本将使用Acme脚本申请证书,使用时需保证:"#!/bin/bash
ssl_cert_issue() {
echo ""
echo "******使用说明******"
echo "该脚本将使用Acme脚本申请证书,使用时需保证:"
echo "1.知晓Cloudflare 注册邮箱"
echo "2.知晓Cloudflare Global API Key"
echo "3.域名已通过Cloudflare进行解析到当前服务器"
echo "4.该脚本申请证书默认安装路径为/root/cert目录"
# 使用 read 进行确认
read -p "我已确认以上内容[y/n]:" confirm_choice
if [[ "$confirm_choice" == "y" ]]; then
cd ~
echo "安装Acme脚本"
curl https://get.acme.sh | sh
if [ $? -ne 0 ]; then
echo "安装acme脚本失败"
exit 1
fi
CF_Domain=""
CF_GlobalKey=""
CF_AccountEmail=""
certPath=/root/cert
# 创建证书目录
if [ ! -d "$certPath" ]; then
mkdir $certPath
else
rm -rf $certPath
mkdir $certPath
fi
# 读取域名
echo "请设置域名:"
read -p "Input your domain here: " CF_Domain
echo "你的域名设置为: ${CF_Domain}"
# 读取API密钥
echo "请设置API密钥:"
read -p "Input your key here: " CF_GlobalKey
echo "你的API密钥为: ${CF_GlobalKey}"
# 读取注册邮箱
echo "请设置注册邮箱:"
read -p "Input your email here: " CF_AccountEmail
echo "你的注册邮箱为: ${CF_AccountEmail}"
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
if [ $? -ne 0 ]; then
echo "修改默认CA为Lets'Encrypt失败,脚本退出"
exit 1
fi
export CF_Key="${CF_GlobalKey}"
export CF_Email=${CF_AccountEmail}
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
if [ $? -ne 0 ]; then
echo "证书签发失败,脚本退出"
exit 1
else
echo "证书签发成功,安装中..."
fi
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
--cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
--fullchain-file /root/cert/fullchain.cer
if [ $? -ne 0 ]; then
echo "证书安装失败,脚本退出"
exit 1
else
echo "证书安装成功,开启自动更新..."
fi
~/.acme.sh/acme.sh --upgrade --auto-upgrade
if [ $? -ne 0 ]; then
echo "自动更新设置失败,脚本退出"
ls -lah cert
chmod 755 $certPath
exit 1
else
echo "证书已安装且已开启自动更新,具体信息如下"
ls -lah cert
chmod 755 $certPath
fi
fi
}
ssl_cert_issue
# 参考资料
参考资料:https://github.com/vaxilu/x-ui
参考资料:https://coderfan.net/how-to-use-acme-to-issue-ssl-certifiates.html