标签 ssl 下的文章

最近玩了下Cloudflare,其丰富的免费功能,令我印象深刻。虽然其提供了一键开启的免费SSL服务,但是开发测试环境还是需要用到SSL证书。这里记录一下获取SSL证书的配置。

1. 准备

需要先准备好以下三个方面:

  • 域名

    • 可直接购买,一般按年收费。
    • eu.org提供免费域名,但申请域名的审核时长不定。
  • DNS

    • Cloudflare提供免费DNS服务,需要先免费注册账户。
    • Cloudflare设置域名解析。
  • 证书机构。推荐一直在使用“Let's Encrypt”。其具有以下三个优点:

    • 基于DNS服务验证域名所有权。通过在DNS添加指定的TXT记录实现验证。
    • 支持通配符证书。
    • 客户端程序Certbot实现证书申请和续签。

参考:

2. Cloudflare API Token

  • 登录Cloudflare并进入Dashboard:https://dash.cloudflare.com/
  • 点击右上角的用户头像,再点“My profile”。
  • 点左边菜单的“API Tokens”,再点右边的“Create Token”按钮。
  • 找到“Edit zone DNS”的行,点击右边的“Use template”按钮。
  • “Token name”填写Token名称,“Zone Resources”选“Include”、“Specific zone”、指定的域名,再点下面的“Continue to summary”按钮。
  • 最后点“Create Token”,就显示所申请的API Token了。由于只显示一次,要保存好。

3. Certbot

这里以Debian 12为例,安装、配置和使用Certbot。

Certbot官方网站:Certbot

3.1 安装

Certbot官方安装教程是使用snapd,但Debian 12的软件仓库已提供Certbot,以及cloudflare的插件。

sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflare

3.2 配置

编辑文件/etc/letsencrypt/certbot-dns-cloudflare-credentials.ini,填写以下内容。其中“_cloudflare_api_token_”需要替换为第2步申请到的Cloudflare API Token。

# Cloudflare API token, get SSL for foxail.eu.org
dns_cloudflare_api_token=_cloudflare_api_token_

保存后,设置该文件的权限:

sudo chmod 600 /etc/letsencrypt/certbot-dns-cloudflare-credentials.ini

3.3 申请SSL证书

执行以下命令申请SSL证书。其中:

  • example.com需要改为实际的域名。
  • 选项--key-type ecdsa使用ECDSA密钥。ECDSA使用更短的密钥就可实现和RSA相同的安全级别,意味着更高的效率。
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/certbot-dns-cloudflare-credentials.ini \
  --key-type ecdsa \
  --domain "example.com,*.example.com"

第一次执行会提示域名所有权验证失败,按所给提示,在DNS添加相关的TXT记录即可。即添加DNS记录,类型为“TXT”,名称为“_acme-challenge”,内容为提示所给的。添加成功后,再执行一次刚才的命令。

执行命令后会提示一些问题:

  • 要求输入邮箱,可以跳过。输入邮箱的话,可以接收到证书过期或安全问题的通知。
  • 同意服务条款,输入Y并按回车。
  • 是否订阅电子前沿基金会的邮件,看需要选Y或N。

成功后会提示证书的存储位置。

3.4 更新SSL证书

第一次成功执行Certbot后,会自动创建定时任务/etc/cron.d/certbot,实现自动更新证书,该文件的内容如下:

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
#
# Important Note!  This cronjob will NOT be executed if you are
# running systemd as your init system.  If you are running systemd,
# the cronjob.timer function takes precedence over this cronjob.  For
# more details, see the systemd.timer manpage, or use systemctl show
# certbot.timer.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

3.5 删除域名

无效的域名会导致所有证书更新失败。执行以下Shell脚本可以删除指定域名(以www.example.com为例)的相关配置:

sudo rm -rf /etc/letsencrypt/live/www.example.com/
sudo rm -rf /etc/letsencrypt/archive/www.example.com/
sudo rm /etc/letsencrypt/renewal/www.example.com.conf

宽带的80、443端口不能使用了,更新免费的SSL证书(Let’s Encrypt的免费证书)就成问题了。后来找到相关的文章,说是可以通过DNS验证并更新,指向以下官方网址:
User Guide -> Getting certificates (and choosing plugins) -> dns-plugins
https://certbot.eff.org/docs/using.html#dns-plugins

找DNSPod的插件时,发现github上居然有不同的版本(名称却是一样的),因此走了弯路(浪费了一个下午)。最后按照这个的说明,成功更新了证书。
DNSPOD DNS Authenticator plugin for Certbot
https://github.com/SkyLothar/certbot-dns-dnspod/blob/master/README.rst

简单来说,就是
1)去DNSPod.cn申请api授权
2)安装插件

pip install certbot-dns-dnspod

3)生成插件配置文件,例如保存到文件/etc/cetbot-dns-dnspod-credentials.ini。重点是双引号不可缺,token的格式是id和token以逗号分隔

certbot_dns_dnspod:dns_dnspod_email = "DNSPod账户的Email"
certbot_dns_dnspod:dns_dnspod_api_token = "api_id,api_token"

4)配置文件设置权限(只是为了安全,此步可不做)

sudo chmod 600 /etc/cetbot-dns-dnspod-credentials.ini

5)更新证书。xxx.com需要替换为相关域名。

certbot certonly -a certbot-dns-dnspod:dns-dnspod \
  --certbot-dns-dnspod:dns-dnspod-credentials /etc/cetbot-dns-dnspod-credentials.ini \
  -d xxx.com

证书更新成功后,会发现certbot的配置文件(/etc/letsencrypt/renewal/xxx.com.conf)也更新了。