CodeSky 代码之空

随手记录自己的学习过程

如何写一个 certbot 的插件

2019-10-29 22:11分类: Python评论: 1

目前白嫖 HTTPS 的主流途径依旧是 LetsEncrpyt,certbot 似乎是官方主要推荐的一个申请方式,关于用途和用法,这里不多介绍,总之,是一个品种齐全,种类多样的 cli 工具:https://certbot.eff.org/

这里由于我的 NAS 希望签 HTTPS,但是电信开外网是不允许开 80 和 443 端口的,所以无法用 HTTP 协议去校验,只能选择 DNS,如果没有 DNS 插件,那么只能用 Manual 的方式,非常麻烦。

于是,我开始了面向源代码编程——

准备好你的参考资料

  1. certbot developer guide
  2. certbot-dns-cloudflare GitHub

开始实现

要实现一个 certbot dns plugin,只要实现一个 IAuthenticator,其中最重要的两个方法就是 performcleanup,分别用于增加和删除记录。

这里提供一个最简单的 Authenticator 模板:

1@zope.interface.implementer(interfaces.IAuthenticator)
2@zope.interface.provider(interfaces.IPluginFactory)
3class Authenticator(dns_common.DNSAuthenticator):
4
5    description = (
6        'Obtain certificates using a DNS TXT record(if you are using Hostker for DNS).')
7
8    def __init__(self, *args, **kwargs):
9        super(Authenticator, self).__init__(*args, **kwargs)
10        self.credentials = None
11
12    @classmethod
13    def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
14        pass
15
16    def more_info(self): # pylint: disable=no-self-use
17        pass
18
19    def _setup_credentials(self):
20        pass
21
22    # add txt record
23    def _perform(self, domain, validation_name, validation):
24        pass
25
26    # delete txt record
27    def _cleanup(self, domain, validation_name, validation):
28        pass
29

其中主要搞清楚 domain, validation_name

  • domain: 你填写的需要申请证书的域名
  • validation_name: _acme-challenge.[你输入的域名]

certbot 会调用内部的函数来运行流程。

内部流程大致如下:

  1. descriptionmore_info,是普通的描述信息,最开始展示选项时使用,如果不是交互式命令,则不会有描述
  2. _setup_credentials,在配置信息里对应的字段
  3. _perform,开始注册 txt record。
  4. 注册完毕,开始检查(这部分不用内部实现)
  5. 检查完毕,执行 _cleanup 开始删除 txt record

也就是说,理论上每次只注册一个 record,删除一个 record,特别的情况下(比如已经注册过了但是没有删除干净),可以使用遍历删除所有同名的 txt record。

最后,要完全能用,还需要在 setup.py 中配置:

1entry_points={
2        'certbot.plugins': [
3            'dns-hostker = certbot_dns_hostker.dns_hostker:Authenticator'
4        ]
5

配置文件

上面我们写了读取配置的部分,但是配置文件的格式是什么——可以看一下 certbot_dns_hostker 的介绍,对应的是 entry_point 作为前缀加上我们配置参数的部分,可以保存成任意文件名,只要 text/plain 可以读取即可:

certbot_dns_hostker:dns_hostker_email=[your email]
certbot_dns_hostker:dns_hostker_token=[your token]

测试

同样的,单元测试也主要测试 performcleanup 的部分,如果你在实现过程中有一些比较复杂的逻辑部分,可以额外的将这些纳入测试。

在 certbot_dns_hostker 中基本只实现了核心部分的测试,可以直接根据这个来写你的测试:https://github.com/csvwolf/certbot-dns-hostker/blob/master/certbot_dns_hostker/dns_hostker_test.py

最后

抄就一个字——这又是一篇拖了半个月的更新……当然,随着 certbot dns 插件越来越多,其实开发的场景也很少,多看几个 certbot 仓库下的插件也就够了。

如果有兴趣,可以关注一下 certbot-dns-hostker

评论 (1)

wlt2332020年12月6日 23:05

pip install certbot-dns-hostker的时候似乎没有安装依赖,导致ker.py这个模块要手动install好像(