首先是需要获取 certbot 工具,具体可以参考文章Let's Encrypt 免费 SSL 证书建立 HTTPS

申请泛域名证书

# 通配符证书(泛域名)申请
# `--manual` 交互式获取
# `--preferred-challenges dns` 使用DNS验证的方式(泛域名只能使用DNS验证)
# `--server` 指明支持 acme-v02 的 Server 地址,默认是 acme-v01 的地址
# example.com 改为自己的域名

./certbot-auto --manual -d *.example.com --preferred-challenges dns-01 certonly --server https://acme-v02.api.letsencrypt.org/directory

执行完这一步之后,会下载一些需要的依赖,稍等片刻之后,会提示输入邮箱,该邮箱用于安全提醒以及续期提醒。

操作记录如下

[root@test certbot]# ./certbot-auto --manual -d *.example.com --preferred-challenges dns-01 certonly --server https://acme-v02.api.letsencrypt.org/directory
Complete!
Creating virtual environment...
Installing Python packages...
Installation succeeded.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
# 请输入你的邮箱地址
cancel): example@example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for funtui.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

# 是否公开记录申请该证书的IP地址? 不同意就无法继续。
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 添加 DNS 的 TXT 解析记录
# 配置域名解析,添加一条 TXT 类型
# 域名:_acme-challenge.example.com
# 解析值:wwEl8CKDJnMhrEIqLXw3ZcTSZFHU7G68mtI-4isZu2k
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

wwEl8CKDJnMhrEIqLXw3ZcTSZFHU7G68mtI-4isZu2k

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2019-02-24. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

[root@test certbot]#

申请通配符证书是要经过 DNS 认证的,按照提示,前往域名后台添加对应的 DNS TXT 记录。添加之后,不要心急着按回车,等待3-5分钟,在 linux 上执行 dig -t txt _acme-challenge.example.com @8.8.8.8 确认解析记录是否生效,生效之后再回去按回车确认,然后大功告成,证书存放在 /etc/letsencrypt/live/example.com/ 里面

续期

关于通配符证书续期,和普通续期不太一样,执行 ./certbot-auto renew 会出现类似以下错误信息。

Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)

大概意思是说,通配符证书申请、续期的时候只能通过 DNS 验证,而 DNS 添加记录只能手动,整个 cerbot 操作无法做到自动化,所以 ./certbot-auto renew 就失败了。 那如何解决呢,cerbot 提供了一个 --manual-auth-hook 命令,可以编写一个脚本,这个脚本是要你自己根据自己域名解析商提供的接口来自己实现的,由这个脚本来先完成 DNS 验证,然后再进行 renew。对应的脚本会自动添加 DNS 记录,从而完成 DNS 校验,并自动 renew 证书。

GitHub: Let’s Encrypt 通配符证书如何续期代码 Aliyun:API key 和 Secrec 官方申请文档

本文使用的是阿里云DNS,在这里直接使用 GitHub 社区开源的 python 脚本来自动更新,不再重复造轮子。

下载

# 获取脚本
git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au.git
# 赋予权限
cd certbot-letencrypt-wildcardcertificates-alydns-au
chmod 0777 au.sh autxy.sh augodaddy.sh python-version/au.sh

python-version 里的脚本是 python 环境使用的,外面的脚本是 PHP 环境使用的,都是同一种效果。

[root@test certbot-letencrypt-wildcardcertificates-alydns-au]# ll
total 48
-rwxrwxrwx 1 root root 5955 Feb 20 16:01 alydns.php
-rwxrwxrwx 1 root root  549 Feb 20 16:00 augodaddy.sh
-rwxrwxrwx 1 root root  550 Feb 20 16:00 au.sh
-rwxrwxrwx 1 root root  550 Feb 20 16:00 autxy.sh
-rw-r--r-- 1 root root 5415 Feb 20 16:00 godaddydns.php
drwxr-xr-x 2 root root 4096 Feb 20 16:38 python-version
-rw-r--r-- 1 root root 6735 Feb 20 16:00 README.md
-rwxr-xr-x 1 root root 7177 Feb 20 16:00 txydns.php

以阿里云DNS为例,使用到的脚本就两个文件:

  • au.sh:--manual-auth-hook 对应的脚本,主要就是执行 hook 操作,会调用一些 certbot 内部变量。
  • alydns.py:au.sh 会调用该脚本,完成 DNS 记录的更新操作。

au.sh

#!/bin/bash

# 阿里云操作 DNS Hook

PATH=$(cd `dirname $0`; pwd)

echo $PATH"/alydns.php"

# 调用 PHP 脚本,自动设置 DNS TXT 记录。
# 第一个参数:需要为那个域名设置 DNS 记录
# 第二个参数:需要为具体那个 RR 设置
# 第三个参数: letsencrypt 动态传递的 RR 值

echo $CERTBOT_DOMAIN"_acme-challenge"$CERTBOT_VALIDATION

/usr/bin/php  $PATH"/alydns.php"  $CERTBOT_DOMAIN "_acme-challenge"  $CERTBOT_VALIDATION >"/var/log/certdebug.log"

# DNS TXT 记录刷新时间
/bin/sleep 20

echo "END"
###

alydns.py

在使用 alydns.py 脚本脚本前,需要修改 accessKeyId、accessSecrec(需要去阿里云申请 API key 和 Secrec,用于调用阿里云 DNS API)

# coding:utf-8

import base64
import urllib
import hmac
import pytz
import datetime
import random
import string
import json
import sys

pv = "python2"
#python2
if sys.version_info[0] < 3:
    from urllib import quote
    from urllib import urlencode
    import hashlib
else:
    from urllib.parse import quote
    from urllib.parse import urlencode
    from urllib import request
    pv = "python3"

ACCESS_KEY_ID = 'access_key_id'
ACCESS_KEY_SECRET = 'access_key_secret'

# 只展示 alydns.php 前几行,其他略...
# 略...

注: 使用 alydns.py 需要用到 python 的 pytz 模块,默认没有安装,需要手动安装

# 安装epel扩展源
yum -y install epel-release
# 安装pip
yum -y install python-pip
# 显示版本和路径
pip --version
# 安装 pytz
easy_install --upgrade pytz

使用

申请证书

参数说明:

  • certonly:表示采用验证模式,只会获取证书,不会为web服务器配置证书。
  • --manual:表示插件。
  • --preferred-challenges dns:表示采用DNS验证申请者合法性(是不是域名的管理者)。
  • --dry-run:在实际申请/更新证书前进行测试,强烈推荐。
  • -d:表示需要为那个域名申请证书,可以有多个。
  • --manual-auth-hook:在执行命令的时候调用一个 hook 文件。
# 测试是否有错误,为避免遇到操作次数的限制,加入 dry-run 参数,能够避免操作限制,等执行无误后,再进行真实的renew 操作。
# 下面统一以 `au.sh` 为例介绍
./certbot-auto certonly  -d *.example.com --manual --preferred-challenges dns --dry-run  --manual-auth-hook au.sh
# 实际申请
./certbot-auto certonly  -d *.example.com --manual --preferred-challenges dns  --manual-auth-hook au.sh

如果你想为多个域名申请通配符证书(合并在一张证书中,也叫做 SAN 通配符证书),直接输入多个 -d 参数即可,比如:

./certbot-auto certonly  -d *.example.com -d *.example.org -d www.example.cn  --manual --preferred-challenges dns  --dry-run --manual-auth-hook au.sh

续期证书

对机器上所有证书 renew

./certbot-auto renew  --manual --preferred-challenges dns  --manual-auth-hook au.sh

对某一张证书进行续期

./certbot-auto renew --cert-name example.com  --manual-auth-hook au.sh

查看证书剩余天数

./certbot-auto certificates

加入 crontab

# 证书有效期 < 30天才会 renew,所以 crontab 可以配置为 1 天或 1 周
1 1 */1 * * root certbot-auto renew --manual --preferred-challenges dns  --manual-auth-hook au.sh

# 如果是 certbot 机器和运行 web 服务(比如 nginx,apache)的机器是同一台,那么成功 renew 证书后,可以启动对应的 web 服务器,运行下列 crontab
# 注意只有成功 renew 证书,才会重新启动 nginx
1 1 */1 * * root certbot-auto renew --manual --preferred-challenges dns -deploy-hook  "service nginx restart"  --manual-auth-hook au.sh

PS:

1、服务器 443 端口开了吗! 开了吗! 开了吗!

1、如果出现 -bash: dig: command not found 需要执行 yum -y install bind-utils

2、申请的泛域名证书 *.example.com 并不能用在 example.com ,所以服务器还是需要两个证书


results matching ""

    No results matching ""