通过 Let's Encrypt 获取免费 SSL 证书的两种方法!
前言
Let’s Encrypt 是目前免费 SSL 证书应用最广泛的一家,不仅免费而且证书也被众多机构认可。以前 Let’s Encrypt 的证书只支持顶级域名申请,不过现在已经支持通配符/泛域名 SSL 证书。泛域名证书比单域名证书方便多了,一次签发所有子域名通用,只需要担心续期问题。

今天我们来说下如何申请使用 Let’s Encrypt 泛域名 SSL 证书,这里提供两种方式:acme.sh 和 certbot。
一、通过 acme.sh 获取 Let’s Encrypt SSL 证书
acme.sh 是一个纯 Shell 脚本编写的 ACME 客户端,支持多种验证方式,特别适合需要自动化 DNS 验证的场景。
安装
Debian/Ubuntu 和 CentOS 8+ 都可以用同样的方式安装:
cd ~curl https://get.acme.sh | sh或者用 wget:
wget -O - https://get.acme.sh | sh安装成功后,acme.sh 会被安装到用户目录下的 .acme.sh 目录中。
设置别名
安装完成后需要创建一个 bash alias,或者直接加载配置:
alias acme.sh=~/.acme.sh/acme.sh或:
source ~/.bashrc设置 Let’s Encrypt 为默认 CA
自 2022 年以后,acme.sh 默认将 CA 改为 ZeroSSL。如果希望使用 Let’s Encrypt,需要切换:
acme.sh --set-default-ca --server letsencrypt如果不设置这一步,申请证书时会卡在获取 EAB 授权那一步。
生成证书
这里使用 DNS 自动验证方式验证域名所有权。acme.sh 目前支持 Cloudflare、DNSPod、CloudXNS、GoDaddy 以及 OVH 等数十种解析商的自动集成,请自行查看官方提供的 DNS API 文档
Cloudflare
如果你的域名使用 Cloudflare 解析,设置 API Token:
export CF_Token="你的_Cloudflare_API_Token"
acme.sh --issue --dns dns_cf -d example.com -d *.example.comDNSPod
export DP_Id="你的_DNSPod_ID"export DP_Key="你的_DNSPod_Key"
acme.sh --issue --dns dns_dp -d example.com -d *.example.com手动 DNS 验证
如果你的 DNS 提供商没有提供 API,可以使用手动验证方式。比如使用 Hurricane (dns.he.net):
export HE_Username="用户名"export HE_Password="密码"
acme.sh --issue --dns dns_he -d example.com -d *.example.com第一个 -d 后不能只写通配符域名 *.example.com,否则可能会出现签发的证书无法被信任的情况,一定要写个单域名。第二个 -d 后面可以写泛域名。
复制证书到指定位置
正确的使用方法是使用 --installcert 命令,并将证书复制到指定目标位置:
acme.sh --installcert -d example.com \ --key-file /etc/nginx/ssl/example.com.key \ --fullchain-file /etc/nginx/ssl/fullchain.cer \ --reloadcmd "systemctl reload nginx"如果使用 service:
acme.sh --installcert -d example.com \ --key-file /etc/nginx/ssl/example.com.key \ --fullchain-file /etc/nginx/ssl/fullchain.cer \ --reloadcmd "service nginx reload"该命令会被自动记录,以后自动更新证书的时候也会自动执行该命令。
自动续期
acme.sh 安装时会自动创建一个 cron 任务,每天检查证书是否需要续期。证书在 60 天以后会自动更新,无需任何操作。
如果需要手动触发续期:
acme.sh --renew -d example.com --forceNginx 配置
创建配置文件 /etc/nginx/conf.d/example.com.conf:
server { listen 80; server_name example.com www.example.com; return 301 https://$server_name$request_uri;}
server { listen 443 ssl http2; server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on;
location / { root /var/www/html; index index.html; }}测试配置并重启 Nginx:
nginx -tsystemctl reload nginx注意事项
- Nginx 的配置
ssl_certificate使用/etc/nginx/ssl/fullchain.cer,而不是/etc/nginx/ssl/example.com.cer,否则 SSL Labs 的测试会报Chain issues Incomplete错误 - 如果提示
acme.sh: command not found,需要执行source ~/.bashrc或注销并重新登录 - 证书在 90 天以后会自动更新,无需任何操作
二、通过 certbot 获取 Let’s Encrypt SSL 证书
Certbot 是 Let’s Encrypt 官方推荐的获取证书客户端,支持所有 Unix 内核的操作系统。
安装
Debian/Ubuntu
sudo apt updatesudo apt install certbot python3-certbot-nginxCentOS 8+
sudo dnf install epel-releasesudo dnf install certbot python3-certbot-nginx生成证书
HTTP 验证(单域名证书)
如果你的网站已经运行在 Nginx 上,可以使用 webroot 模式:
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com这个命令会在 /var/www/html 中创建 .well-known 文件夹,里面包含一些验证文件。certbot 会通过访问 example.com/.well-known/acme-challenge 来验证域名是否绑定的这个服务器。
Standalone 验证
如果你的服务没有网站根目录,可以使用 standalone 模式。这个模式会自动启用服务器的 80 端口来验证域名的归属:
sudo certbot certonly --standalone -d example.com -d www.example.com使用 standalone 模式时,如果有其他服务(如 nginx)占用了 80 端口,必须先停止这些服务,在证书生成完毕后再启用。
DNS 验证(泛域名证书)
泛域名证书必须使用 DNS 验证方式:
sudo certbot certonly --manual --preferred-challenges=dns -d example.com -d *.example.com执行这个命令后,certbot 会提示你添加一个 TXT 记录到你的 DNS 配置中。按照提示在 DNS 管理界面添加记录,然后按回车继续。
自动化 DNS 验证
如果使用支持 API 的 DNS 提供商,可以自行搜索安装对应的 certbot 插件,来实现自动化 DNS 验证。例如使用 Cloudflare:
sudo apt install python3-certbot-dns-cloudflare创建 credentials 文件 /etc/letsencrypt/secrets/certbot-cloudflare.ini:
dns_cloudflare_api_token = 你的_Cloudflare_API_Token设置文件权限:
sudo chmod 600 /etc/letsencrypt/secrets/certbot-cloudflare.ini然后运行:
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/secrets/certbot-cloudflare.ini -d example.com -d *.example.com证书位置
证书生成完毕后,可以在 /etc/letsencrypt/live/example.com 目录下看到对应域名的文件夹,里面存放了证书文件:
fullchain.pem: 证书链(包含证书和中间证书)privkey.pem: 私钥cert.pem: 证书chain.pem: 中间证书
Nginx 配置
创建配置文件:
server { listen 80; server_name example.com www.example.com; return 301 https://$server_name$request_uri;}
server { listen 443 ssl http2; server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on;
location / { root /var/www/html; index index.html; }}测试配置并重启 Nginx:
sudo nginx -tsudo systemctl reload nginx自动续期
Let’s Encrypt 提供的证书只有 90 天的有效期。
从 certbot v0.19.0 开始,安装时会自动创建 systemd timer 和 cron job(通常在 /etc/cron.d/certbot),所以大多数情况下不需要手动添加续期任务。
检查自动续期是否正常工作:
sudo certbot renew --dry-run这个命令会模拟续期过程,如果一切正常,说明自动续期已配置好。
特殊情况需要手动配置
如果你的证书使用 standalone 模式生成,或者自动续期没有正常工作,则需要手动添加续期任务。
使用 standalone 模式时,如果有其他服务(如 nginx)占用了 80 端口,必须先停止这些服务,在证书生成完毕后再启用。
编辑 crontab:
sudo crontab -e添加以下内容:
0 0,12 * * * certbot renew -q这个设置会在每天凌晨 0 点和 12 点检查并续期证书。
如果是 standalone 模式,需要使用 pre/post hook:
15 2 * */2 * certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"或者使用 service:
15 2 * */2 * certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"--pre-hook 表示执行更新操作之前要做的事情,--post-hook 表示执行更新完成后要做的事情。
写在最后
两种方式各有优势:
- acme.sh: 轻量级,纯 Shell 实现,支持更多 DNS 提供商的自动化,适合需要自动化 DNS 验证的场景
- certbot: 官方推荐,功能完善,支持自动配置 Nginx,文档完善,适合常规使用
选择哪种方式主要看你的具体需求。如果你需要支持更多的 DNS 提供商或者喜欢轻量级的解决方案,acme.sh 是不错的选择。如果你希望使用官方推荐的工具并享受自动配置的便利,certbot 会更适合。
无论选择哪种方式,都能帮你轻松获取免费的 SSL 证书,让你的网站拥抱 HTTPS。
推荐文章
基于标签匹配 · 智能推荐支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
喵斯基部落