用于管理多个供应商的DNS的工具

作者:Sec-Labs | 发布时间:

DNS 即代码 - 跨多个提供商管理 DNS 的工具

基础设施方面 代码 OctoDNS 提供了一组工具和模式,可以轻松跨多个提供商管理您的 DNS 记录。 生成的配置可以存在于存储库中,并可以 进行部署,保持清晰的历史记录并使用您现有的审查和工作流程。 像其他代码一样

该架构是可插拔的,工具很灵活,可以适用于各种各样的用例。 已努力使添加新提供者尽可能容易。 在涉及单个写入的简单情况下 class和几百行代码,其中大部分在提供商的架构和 OctoDNS 之间进行转换。 更多关于我们使用它的一些方法以及如何在 /docs 目录 下面和中扩展它。

项目地址

https://github.com/octodns/octodns

目录

入门

工作区

运行以下命令将安装最新版本的 OctoDNS 并为您的配置文件设置一个存放位置。 要确定是否需要提供者的特定要求,请参阅下面的 提供者表

$ mkdir dns
$ cd dns
$ python -m venv env
...
$ source env/bin/activate
$ pip install octodns <provider-specific-requirements>
$ mkdir config

安装特定的提交 SHA

如果您想以可重复/安全的方式安装尚未发布的版本,您可以执行以下操作。 由于计划和应用过程,通常 octoDNS 在两次发布之间相当稳定,但无论如何都应该小心。

$ pip install -e git+https://git@github.com/octodns/octodns.git@<SHA>#egg=octodns

配置

我们首先创建一个配置文件来告诉 OctoDNS 我们的提供商和我们希望它管理的区域。 下面我们设置一个 YamlProvider从我们的配置文件和两者中获取记录 Route53ProviderDynProvider作为这些记录的目标。 您可以设置任意数量的区域以及每个区域的任意数量的数据源和记录目标。 您还可以拥有多个配置文件,它们使用单独的帐户,每个帐户管理一组不同的区域。 这可能是一个很好的例子 ./config/staging.yaml& ./config/production.yaml. 我们将专注于一个 config/production.yaml.

---
manager:
  include_meta: False
  max_workers: 2

providers:
  config:
    class: octodns.provider.yaml.YamlProvider
    directory: ./config
    default_ttl: 3600
    enforce_order: True
  dyn:
    class: octodns.provider.dyn.DynProvider
    customer: 1234
    username: 'username'
    password: env/DYN_PASSWORD
  route53:
    class: octodns.provider.route53.Route53Provider
    access_key_id: env/AWS_ACCESS_KEY_ID
    secret_access_key: env/AWS_SECRET_ACCESS_KEY

zones:
  example.com.:
    sources:
      - config
    targets:
      - dyn
      - route53

  example.net.:
    alias: example.com.

class是一个特殊的键,它告诉 OctoDNS 应该加载什么 python 类。 任何其他键都将作为配置值传递给该提供程序。 一般来说,任何敏感或经常旋转的值都应该来自环境变量。 当 OctoDNS 看到一个以 env/它将在进程的环境中查找该值并传递结果。

更多信息可以在 docstring每个源和提供者类。

include_meta键入 manager配置部分控制在由 OctoDNS 管理的区域的根目录创建 TXT 记录。 如果设置为 True, OctoDNS 将为区域的根创建一条 TXT 记录,其值为 provider=<target-provider>. 如果未指定,则默认值为 include_metaFalse.

max_workers键入 manager配置部分启用线程以并行化同步的计划部分。

在这个例子中, example.net是 zone 的别名 example.com,这意味着它们共享相同的源和目标。 因此,它们将具有相同的记录。

现在我们有一些东西要告诉 OctoDNS 我们的提供商和区域,我们需要告诉它我们的记录。 我们暂时保持简单,只创建一个 A记录在域的顶层。

config/example.com.yaml
---
'':
  ttl: 60
  type: A
  values:
    - 1.2.3.4
    - 1.2.3.5

更多信息可以在 记录文档 中找到。

没有

我们已经准备好对我们的新设置进行试运行,看看它会做出什么改变。 因为我们在这里假装我们会表现得好像没有现有记录 example.com.在我们在任一提供商的帐户中。

$ octodns-sync --config-file=./config/production.yaml
...
********************************************************************************
* example.com.
********************************************************************************
* route53 (Route53Provider)
*   Create <ARecord A 60, example.com., [u'1.2.3.4', '1.2.3.5']>
*   Summary: Creates=1, Updates=0, Deletes=0, Existing Records=0
* dyn (DynProvider)
*   Create <ARecord A 60, example.com., [u'1.2.3.4', '1.2.3.5']>
*   Summary: Creates=1, Updates=0, Deletes=0, Existing Records=0
********************************************************************************
...

屏幕上还会显示其他日志记录信息,但成功运行的同步将始终以类似上述的摘要结束,以显示任何提供程序和区域的更改。 如果没有更改,则会打印一条消息,说明如此。 上面我们在两个提供者中创建了一个新区域,因此它们显示相同的更改,但情况并非总是如此。 如果启动其中一个具有不同的状态,您会看到 OctoDNS 打算进行的更改以同步它们。

做出改变

警告 :OctoDNS 假定您指向它的任何域的所有权。 当你告诉它采取行动时,它会做任何必要的事情来尝试匹配状态,包括删除任何意外记录。 玩 OctoDNS 时要小心。 在您对系统感到满意之前,最好尝试使用虚假区域或没有任何重要数据的区域。

现在是时候告诉 OctoDNS 让事情发生了。 我们将使用相同的选项再次调用它并添加一个 --doit最后告诉它这次我们实际上希望它尝试进行指定的更改。

$ octodns-sync --config-file=./config/production.yaml --doit
...

此处的输出将与以前相同,最后会增加几行日志,因为它会进行实际更改。 之后,Route53 和 Dyn 中的配置应该与 yaml 文件中的配置相匹配。

工作流程

在上述情况下,我们从命令行手动运行 OctoDNS。 这很有效,它比进入提供商 GUI 并通过单击进行更改要好,但 OctoDNS 旨在作为部署过程的一部分运行。 实现细节远远超出了本 README 的范围,但这里是我们在 GitHub 使用的工作流示例。 它遵循 GitHub 本身的分支部署 方式。

第一步是使用您的更改创建 PR。

0231f5dbe1103649

 

假设代码测试和配置验证状态为绿色,下一步是进行 noop 部署并验证 OctoDNS 计划进行的更改是否符合您的预期。

c6f36329f0103706

 

之后是一组评论。 一个来自队友的人,他应该对你想要完成的事情有完整的背景,并了解你正在做的改变。 另一个来自拥有 DNS 的 GitHub 团队成员,主要是作为健全性检查并确保遵循最佳实践。 尽可能多地被烘烤成 octodns-validate.

在审查之后,是时候分支部署更改了。

7795b36f87103722

 

如果一切顺利,您将再次看到预期的更改,并使用 dig和/或 octodns-report你很高兴点击合并按钮。 如果有问题可以快速进行 .deploy dns/main回到以前的状态。

引导配置文件

很少有情况会涉及从空白开始,这就是为什么内置工具可以将现有数据从提供程序中提取到匹配的配置文件中。

$ octodns-dump --config-file=config/production.yaml --output-dir=tmp/ example.com. route53
2017-03-15T13:33:34  INFO  Manager __init__: config_file=tmp/production.yaml
2017-03-15T13:33:34  INFO  Manager dump: zone=example.com., sources=('route53',)
2017-03-15T13:33:36  INFO  Route53Provider[route53] populate:   found 64 records
2017-03-15T13:33:36  INFO  YamlProvider[dump] plan: desired=example.com.
2017-03-15T13:33:36  INFO  YamlProvider[dump] plan:   Creates=64, Updates=0, Deletes=0, Existing Records=0
2017-03-15T13:33:36  INFO  YamlProvider[dump] apply: making changes

上述命令将现有数据拉出 Route53 并将结果放入 tmp/example.com.yaml. 可以检查该文件并将其移至 config/成为新的源头。 如果事情按设计进行,则后续的 noop 同步应该显示零更改。

来源

类似于提供者,但只能用于将记录填充到区域中,不能同步到。

资源 记录支持 动态的 笔记
环境变量源 TXT 只读环境变量注入
AxfrSource A、AAAA、CAA、CNAME、LOC、MX、NS、PTR、SPF、SRV、TXT 只读
区域文件源 A、AAAA、CAA、CNAME、MX、NS、PTR、SPF、SRV、TXT 只读
TinyDns文件源 A、CNAME、MX、NS、PTR 只读

笔记

  • ALIAS 支持因提供者而异,应注意验证您的需求是否得到详细满足。
  • Dyn 的 UI 不允许编辑或查看 TTL,但 API 接受并存储提供的值,服务时似乎未使用此值
  • Dnsimple 在通过 ALIAS 提供服务时使用配置的 TTL,还有一个辅助 TXT 记录与 octoDNS 忽略的 ALIAS 一起创建
  • octoDNS 本身支持非 ASCII 字符集,但在测试中,Cloudflare 是目前唯一提供端到端功能的提供商。 其他人在客户端库或 API 调用中出现故障

兼容性和合规性

lenient

lenient主要关注细节 Records 和标准合规性。 当设置为 trueoctoDNS 将尽可能允许不合规的配置和值。 例如,不以 a 结尾的 CNAME 值 .、标签长度限制和无效的地理代码 dynamic记录。 当处于宽松模式时,octoDNS 将在以下位置记录验证问题 WARNING并尝试继续使用现有的配置或源数据。 请参阅 Lenience 。 有关该概念以及如何配置它的更多信息,

strict_supports(工作正在进行中)

strict_supports是一个 Provider当要求提供者创建它无法支持的记录时,级别参数开始发挥作用。 最简单的情况是记录类型,例如 SSHFP不被支持 AzureProvider. 如果这样的记录被传递给 AzureProvider作为目标,提供者将根据 strict_supports. 什么时候 true它会抛出一个异常,说它无法创建记录,当设置为 false它将登录 WARNING包含有关它无法做什么以及它如何尝试解决它的信息。 其他无法支持的事情的例子是 dynamic仅支持简单或不支持提供程序中特定地理位置的提供程序上的记录,例如 Route53Provider 不支持 NA-CA-*.

值得注意的是,这些错误将在事物的计划阶段发生,因此无需进行更改即可看到问题。

这个概念目前正在进行中,只是部分实施。 虽然工作正在进行中 strict_supports将默认为 false. 一旦工作被认为完成并准备就绪,默认值将更改为 true因为这是一个更安全且不那么令人惊讶的默认设置,因为您配置的就是您将得到的,除非抛出错误告诉您为什么无法完成。 然后,您将可以选择明确要求事情继续解决 strict_supports调成 false. 同时,鼓励您手动配置参数以 true在您的提供商配置中。

配置 strict_supports

strict_supports参数在所有提供程序上都可用,并且可以在 YAML 中进行如下配置:

providers:
  someprovider:
    class: whatever.TheProvider
    ...
    strict_supports: true

自定义来源和提供者

您可以查看 提供程序 目录以查看当前支持的内容。 来源充当记录信息的来源。 AxfrSource 和 TinyDnsFileSource 是目前唯一的 OSS 源,尽管我们内部还有其他几个特定于我们环境的源。 其中包括从 gPanel 和类似的提供商中提取主机数据的东西,该提供商获取有关我们网络设备的信息以创建两者 A& PTR他们的接口记录。 可能成为良好 OSS 源的东西可能包括 ElbSource提取有关 AWS Elastic Load Balancer 的信息并动态创建 CNAMEs 为他们,或 Ec2Source提取实例信息,以便可以为主机创建记录,类似于我们的 GPanelProvider作品。

OctoDNS 中包含的大多数东西都是提供者,明显的区别在于它们既可以作为数据的来源,也可以作为数据的目标。 我们真的很希望看到这个列表随着时间的推移而增长,所以如果您使用不受支持的提供商,那么欢迎 PR。 现有的提供者应该作为合理的例子。 那些没有 GeoDNS 支持的相对简单。 不幸的是,执行 GeoDNS 风格的流量管理所涉及的大多数 API 都很复杂且有些不一致,因此添加对该功能的支持会很好,但它是可选的,最好在单独的通道中完成。

class提供者配置部分中的键可用于指向 python 路径中的任意类,因此可以轻松地包含内部或第 3 方提供者,除了将它们放入 PYTHONPATH 之外无需协调,很可能使用 OctoDNS 安装到 virtualenv 中。

有关构建第三方来源和提供者的示例,请参阅 相关项目和资源

其他用途

提供者之间的同步

虽然主要用例是将一组 yaml 配置文件同步到一个或多个 DNS 提供商,但 OctoDNS 的构建方式使您可以轻松地任意获取和定位事物。 作为一个简单的例子,下面的配置将同步 githubtest.net.从 Route53 到 Dyn。

---
providers:
  route53:
    class: octodns.provider.route53.Route53Provider
    access_key_id: env/AWS_ACCESS_KEY_ID
    secret_access_key: env/AWS_SECRET_ACCESS_KEY
  dyn:
    class: octodns.provider.dyn.DynProvider
    customer: env/DYN_CUSTOMER
    username: env/DYN_USERNAME
    password: env/DYN_PASSWORD

zones:

  githubtest.net.:
    sources:
      - route53
    targets:
      - dyn

动态来源

在内部,我们使用自定义源来创建基于动态数据的记录,这些数据在没有直接人工干预的情况下经常变化。 一个示例可能如下所示。 对于主机来说,这种机制是清洁的,定期运行,确保只要主机还活着就存在正确的记录,并确保在主机被销毁后将它们删除。 主机配置和销毁过程执行创建和销毁记录的实际工作。

---
providers:
  gpanel-site:
    class: github.octodns.source.gpanel.GPanelProvider
    host: 'gpanel.site.github.foo'
    token: env/GPANEL_SITE_TOKEN
  powerdns-site:
    class: octodns.provider.powerdns.PowerDnsProvider
    host: 'internal-dns.site.github.foo'
    api_key: env/POWERDNS_SITE_API_KEY

zones:

  hosts.site.github.foo.:
    sources:
      - gpanel-site
    targets:
      - powerdns-site

标签:工具分享, DNS管理工具