脚本介绍
无论是搭建代理节点,还是建立自己的网站,来自一个权威CA机构的SSL证书是必不可少的。切勿使用自签证书,尤其是在生产环境中,被中间人攻击的概率非常高。Let's Encrypt
是一家非营利组织,它是免费级别SSL证书中最权威的CA机构。但是向Let's Encrypt
申请证书一直是一些用户的难点,为了简化整个流程,我制作了这个脚本来自动完成申请证书的步骤,非常容易上手。
本交互式脚本自动向Let's Encrypt
申请免费证书。脚本会自动安装证书客户端Certbot并且自动验证域名。你只需要在脚本执行过程中根据脚本提示输入你的Cloudflare
的API口令,和你的域名。其它步骤按"Y"即可。
脚本执行前的步骤
- 本脚本只适用于ubuntu/debian,需要sudo权限。
- 在执行本脚本前需要先完成安装
snapd
, 并重启操作系统。
- 对于ubuntu24以后版本一般不需要重启也能成功运行,但是相对比较旧的或者是debian系统,建议重启一下系统,否则可能失败。
1
2
3
|
sudo apt update #更新
sudo apt install snapd #安装snapd
sudo reboot #重启系统
|
运行脚本
- 运行脚本前,请务必确保你的域名已经添加到cloudflare。
- 此脚本是交互式脚本,执行过程中,需要提供DNS的API令牌(从cloudflare获取),以及提供你的域名,支持通配符。
- 无需其它介入,脚本将会自动为你的域名向
Let's Encrypt
申请证书。
- 将以下内容复制到任意文本文件,另存为脚本格式文件
certbot.sh
,运行:bash certbot.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
#!/bin/bash
# 输出颜色
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # 无颜色
# 打印成功信息的函数
success() {
echo -e "${GREEN}成功: $1${NC}"
}
# 打印提示/信息消息的函数
info() {
echo -e "${YELLOW}提示: $1${NC}"
}
# 打印错误信息并退出的函数
error_exit() {
echo -e "${RED}错误: $1${NC}"
exit 1
}
# 运行命令并检查其状态的函数
run_command() {
info "正在执行: $1"
eval "$1" # 使用 eval 来处理可能包含管道或复杂引用的命令。
# 对于简单命令,直接 "$1" "$2" ... 更好。但这里传递的是完整的命令字符串。
if [ $? -ne 0 ]; then
error_exit "命令失败: $1"
fi
}
# --- start ---
echo -e "${YELLOW}Certbot 安装及证书设置脚本${NC}"
echo "本脚本假定您已经:"
echo "1. 运行 'sudo apt update'"
echo "2. 运行 'sudo apt install snapd'"
echo "3. 重启了您的系统。"
echo ""
read -p "您是否已完成这些步骤并重启系统? (是/no): " confirmation
if [[ "$confirmation" != "是" && "$confirmation" != "yes" && "$confirmation" != "y" ]]; then
info "请先完成前提步骤并重启系统,然后重新运行此脚本。"
exit 0
fi
echo ""
info "开始:安装最新的 snap core..."
echo ""
# 步骤 3: 安装 snap 最新 core
run_command "sudo snap install core"
snap_core_version=$(snap list core | awk 'NR==2 {print $2}')
success "Snap Core ${snap_core_version} 已安装。"
echo ""
# 步骤 4: 安装 hello-world 测试程序
info "正在安装 hello-world 以测试 Snap..."
run_command "sudo snap install hello-world"
success "hello-world 已安装。"
info "正在测试 hello-world..."
if hello_world_output=$(hello-world); then
if [[ "$hello_world_output" == "Hello World!" ]]; then
success "hello-world 测试成功: $hello_world_output"
else
error_exit "hello-world 测试输出不是 'Hello World!'。实际输出: $hello_world_output"
fi
else
error_exit "hello-world 命令运行失败。"
fi
echo ""
# 步骤 5: 安装 certbot
info "正在通过 Snap 安装 Certbot..."
run_command "sudo snap install --classic certbot"
certbot_version=$(snap list certbot | awk 'NR==2 {print $2}')
success "Certbot ${certbot_version} 已安装。"
echo ""
# 步骤 6: 继续 Certbot 设置
info "正在为 Certbot 创建软链接..."
if [ -L /usr/bin/certbot ]; then
info "/usr/bin/certbot 软链接已存在。跳过创建。"
else
run_command "sudo ln -s /snap/bin/certbot /usr/bin/certbot"
success "软链接 /usr/bin/certbot 已创建。"
fi
info "正在设置 Certbot trust-plugin-with-root..."
run_command "sudo snap set certbot trust-plugin-with-root=ok"
success "Certbot trust-plugin-with-root 已设置。"
info "正在安装 Certbot DNS Cloudflare 插件..."
run_command "sudo snap install certbot-dns-cloudflare"
cloudflare_plugin_version=$(snap list certbot-dns-cloudflare | awk 'NR==2 {print $2}')
success "Certbot DNS Cloudflare 插件 ${cloudflare_plugin_version} 已安装。"
echo ""
# 步骤 7: 配置 DNS API (Cloudflare)
info "正在配置 Cloudflare API 凭据..."
SECRETS_DIR="/root/.secrets/certbot"
CLOUDFLARE_INI_PATH="${SECRETS_DIR}/cloudflare.ini"
run_command "sudo mkdir -p ${SECRETS_DIR}"
success "目录 ${SECRETS_DIR} 已确保存在。"
echo ""
info "您需要提供您的 Cloudflare API 令牌。"
info "此令牌将存储在 ${CLOUDFLARE_INI_PATH}"
read -sp "请输入您的 Cloudflare API 令牌: " CLOUDFLARE_API_TOKEN
echo "" # 秘密输入后换行
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
error_exit "Cloudflare API 令牌不能为空。"
fi
# 写入 INI 文件
# 使用 sudo tee 写入 root 拥有的文件
echo "dns_cloudflare_api_token = ${CLOUDFLARE_API_TOKEN}" | sudo tee "${CLOUDFLARE_INI_PATH}" > /dev/null
if [ $? -ne 0 ]; then
error_exit "写入 ${CLOUDFLARE_INI_PATH} 失败。"
fi
success "Cloudflare API 令牌已写入 ${CLOUDFLARE_INI_PATH}。"
info "正在为 ${CLOUDFLARE_INI_PATH} 设置权限..."
run_command "sudo chown root:root ${CLOUDFLARE_INI_PATH}"
run_command "sudo chmod 600 ${CLOUDFLARE_INI_PATH}"
success "${CLOUDFLARE_INI_PATH} 的权限已设置为 600 (所有者: root)。"
echo ""
# 步骤 8: 申请证书
info "准备使用 Cloudflare 的 DNS-01 质询方式申请 SSL 证书。"
echo "您需要输入您的域名。对于通配符域名和主域名,请使用格式:yourdomain.com,*.yourdomain.com"
read -p "请输入您的域名 (例如: example.com,*.example.com): " DOMAINS
if [ -z "$DOMAINS" ]; then
error_exit "域名不能为空。"
fi
# 提取基础域名供后续参考 (例如,用于查找证书)
# 取域名列表中的第一个,移除可能的前导'*.',然后取最后两部分。
FIRST_DOMAIN_PART=$(echo "$DOMAINS" | cut -d',' -f1 | sed 's/^\*\.//')
BASE_DOMAIN=$(echo "$FIRST_DOMAIN_PART" | rev | cut -d'.' -f1,2 | rev) # 确保提取正确的域名部分
echo ""
info "Certbot 现在将尝试为以下域名获取证书: ${DOMAINS}"
info "Certbot 可能会提示您输入电子邮件地址以接收续订通知并同意服务条款。"
# 构建 certbot 命令
CERTBOT_CMD="sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ${CLOUDFLARE_INI_PATH} \
--dns-cloudflare-propagation-seconds 60 \
-d '${DOMAINS}'"
echo -e "${YELLOW}将执行以下命令:${NC}"
echo "$CERTBOT_CMD"
echo ""
read -p "继续申请证书吗? (是/no): " proceed_cert
if [[ "$proceed_cert" != "是" && "$proceed_cert" != "yes" && "$proceed_cert" != "y" ]]; then
info "用户中止了证书申请。"
exit 0
fi
# 执行 certbot 命令
eval "$CERTBOT_CMD" # 使用 eval 是因为 -d '${DOMAINS}' 中的引号
cert_status=$?
if [ $cert_status -eq 0 ]; then
success "证书申请成功!"
echo -e "${GREEN}您的证书和证书链已保存在:${NC}"
echo -e "${GREEN}/etc/letsencrypt/live/${FIRST_DOMAIN_PART}/${NC} (或类似路径,请检查 Certbot 输出)"
echo -e "${GREEN}您的密钥文件已保存在:${NC}"
echo -e "${GREEN}/etc/letsencrypt/live/${FIRST_DOMAIN_PART}/privkey.pem${NC} (或类似路径)"
echo ""
info "请记得配置您的 Web 服务器 (例如 Nginx, Apache) 以使用这些证书。"
info "Certbot 已设置自动续订。"
info "您可以使用以下命令测试续订: sudo certbot renew --dry-run"
else
error_exit "证书申请失败。请检查上面的 Certbot 输出以获取详细信息。"
fi
echo ""
success "Certbot 设置和证书申请过程已完成。"
|
欢迎关注我的
Youtube频道
观看视频。
END.