如何写一个 certbot 的插件

目前白嫖 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 模板:

@zope.interface.implementer(interfaces.IAuthenticator)
@zope.interface.provider(interfaces.IPluginFactory)
class Authenticator(dns_common.DNSAuthenticator):

    description = (
        'Obtain certificates using a DNS TXT record(if you are using Hostker for DNS).')

    def __init__(self, *args, **kwargs):
        super(Authenticator, self).__init__(*args, **kwargs)
        self.credentials = None

    @classmethod
    def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
        pass

    def more_info(self): # pylint: disable=no-self-use
        pass

    def _setup_credentials(self):
        pass

    # add txt record
    def _perform(self, domain, validation_name, validation):
        pass

    # delete txt record
    def _cleanup(self, domain, validation_name, validation):
        pass

其中主要搞清楚 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 中配置:

entry_points={
        'certbot.plugins': [
            'dns-hostker = certbot_dns_hostker.dns_hostker:Authenticator'
        ]

配置文件

上面我们写了读取配置的部分,但是配置文件的格式是什么——可以看一下 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

如果您觉得文章不错,可以通过赞助支持我

标签: 成品, 知识, 源代码, certbot

添加新评论