如何在Ubuntu18.04上使用DNSControl部署和管理DNS
作者选择了 Electronic Frontier Foundation Inc 作为 Write for DOnations 计划的一部分来接受捐赠。
介绍
DNSControl 是一种 基础设施即代码 工具,可让您使用标准软件开发原则(包括版本控制、测试和自动化部署)来部署和管理 DNS 区域。 DNSControl 由 Stack Exchange 创建并用 Go 编写。
使用 DNSControl 消除了手动 DNS 管理的许多缺陷,因为区域文件以可编程格式存储。 这使您可以同时将区域部署到多个 DNS 提供商、识别语法错误并自动推出您的 DNS 配置,从而降低人为错误的风险。 DNSControl 的另一个常见用途是将您的 DNS 快速迁移到不同的提供商; 例如,在发生 DDoS 攻击或系统中断时。
在本教程中,您将安装和配置 DNSControl,创建基本的 DNS 配置,并开始将 DNS 记录部署到实时提供商。 作为本教程的一部分,我们将使用 DigitalOcean 作为示例 DNS 提供程序。 如果您希望使用 不同的提供程序 ,设置非常相似。 完成后,您将能够在安全的离线环境中管理和测试您的 DNS 配置,然后自动将其部署到生产环境中。
先决条件
在开始本指南之前,您需要以下内容:
- 按照 Initial Server Setup 和 Ubuntu 18.04 设置一台 Ubuntu 18.04 服务器,包括 sudo 非 root 用户并启用防火墙以阻止非必要端口。
your-server-ipv4-address
是指您托管网站或域的服务器的 IP 地址。 - 由 支持的提供商 托管的具有 DNS 的完全注册域名。 本教程将始终使用
example.com
并使用 DigitalOcean 作为服务提供者。 - 具有读写权限的 DigitalOcean API 密钥(个人访问令牌)。 要创建一个,请访问 如何创建个人访问令牌。
准备好这些后,以非 root 用户身份登录到您的服务器即可开始。
第 1 步 — 安装 DNSControl
DNSControl 是用 Go 编写的,因此您将通过将 Go 安装到您的服务器并设置 GOPATH
来开始这一步。
Go 在 Ubuntu 的默认软件存储库中可用,因此可以使用传统的包管理工具进行安装。
首先更新本地包索引以反映任何新的上游更改:
sudo apt update
然后,安装 golang-go
包:
sudo apt install golang-go
确认安装后,apt
将下载并安装 Go 及其所有必需的依赖项。
接下来,您将为 Go 配置所需的路径环境变量。 如果您想了解更多相关信息,可以阅读 Understanding the GOPATH 上的本教程。 首先编辑 ~/.profile
文件:
nano ~/.profile
将以下行添加到文件的最后:
~/.profile
... export GOPATH="$HOME/go" export PATH="$PATH:$GOPATH/bin"
将这些行添加到文件底部后,保存并关闭它。 然后通过注销并重新登录或再次获取文件来重新加载您的个人资料:
source ~/.profile
现在您已经安装并配置了 Go,您可以安装 DNSControl。
go get
命令可用于获取代码副本,自动编译并将其安装到您的 Go 目录中:
go get github.com/StackExchange/dnscontrol
完成后,您可以检查已安装的版本以确保一切正常:
dnscontrol version
您的输出将类似于以下内容:
Outputdnscontrol 0.2.8-dev
如果您看到 dnscontrol: command not found
错误,请仔细检查您的 Go 路径设置。
现在您已经安装了 DNSControl,您可以创建一个配置目录并将 DNSControl 连接到您的 DNS 提供商,以允许它更改您的 DNS 记录。
第 2 步 — 配置 DNSControl
在此步骤中,您将为 DNSControl 创建所需的配置目录,并将其连接到您的 DNS 提供商,以便它可以开始对您的 DNS 记录进行实时更改。
首先,创建一个新目录,您可以在其中存储您的 DNSControl 配置,然后进入该目录:
mkdir ~/dnscontrol cd ~/dnscontrol
注意:本教程将重点介绍DNSControl的初始设置; 但是对于生产用途,建议将您的 DNSControl 配置存储在版本控制系统 (VCS) 中,例如 Git。 这样做的优点包括完整的版本控制、与 CI/CD 集成以进行测试、无缝回滚部署等。
如果您打算使用 DNSControl 编写 BIND 区域文件,您还应该创建 zones
目录:
mkdir ~/dnscontrol/zones
BIND 区域文件 是一种原始的标准化方法,用于以纯文本格式存储 DNS 区域/记录。 它们最初用于 BIND DNS 服务器软件,但现在被广泛用作存储 DNS 区域的标准方法。 如果您想将 DNSControl 生成的 BIND 区域文件导入自定义或自托管 DNS 服务器,或用于审计目的,这些文件非常有用。
但是,如果您只想使用 DNSControl 将 DNS 更改推送到托管提供商,则不需要 zones
目录。
接下来,您需要配置 creds.json
文件,这将允许 DNSControl 向您的 DNS 提供商进行身份验证并进行更改。 creds.json
的格式因您使用的 DNS 提供商而略有不同。 请查看官方 DNSControl 文档中的 Service Providers 列表 以找到您自己的提供商的配置。
在~/dnscontrol
目录下创建文件creds.json
:
cd ~/dnscontrol nano creds.json
将您的 DNS 提供商的示例 creds.json
配置添加到文件中。 如果您使用 DigitalOcean 作为您的 DNS 提供商,您可以使用以下内容:
~/dnscontrol/creds.json
{ "digitalocean": { "token": "your-digitalocean-oauth-token" } }
此文件告诉 DNSControl 您希望它连接到哪些 DNS 提供商。
您需要为您的 DNS 提供商提供某种形式的身份验证。 这通常是 API 密钥或 OAuth 令牌,但某些提供程序需要额外信息,如官方 DNSControl 文档中的 服务提供程序列表 中所述。
警告: 此令牌将授予对您的 DNS 提供商帐户的访问权限,因此您应该像保护密码一样保护它。 此外,如果您使用的是版本控制系统,请确保排除包含令牌的文件(例如 使用 .gitignore
),或以某种方式安全加密。
如果您使用 DigitalOcean 作为您的 DNS 提供商,您可以在您作为先决条件的一部分生成的 DigitalOcean 帐户设置 中使用所需的 OAuth 令牌 。
如果您有多个不同的 DNS 提供程序(例如,多个域名或委托的 DNS 区域),您可以在同一个 creds.json
文件中定义所有这些。
您已经设置了初始 DNSControl 配置目录,并配置了 creds.json
以允许 DNSControl 向您的 DNS 提供商进行身份验证并进行更改。 接下来,您将为 DNS 区域创建配置。
第 3 步 — 创建 DNS 配置文件
在此步骤中,您将创建一个初始 DNS 配置文件,其中将包含您的域名或委派 DNS 区域的 DNS 记录。
dnsconfig.js
是 DNSControl 的主要 DNS 配置文件。 在此文件中,DNS 区域及其对应记录是使用 JavaScript 语法定义的。 这被称为 DSL 或领域特定语言。 官方 DNSControl 文档中的 JavaScript DSL 页面提供了更多详细信息。
首先,在 ~/dnscontrol
目录中创建 DNS 配置文件:
cd ~/dnscontrol nano dnsconfig.js
然后,将以下示例配置添加到文件中:
~/dnscontrol/dnsconfig.js
// Providers: var REG_NONE = NewRegistrar('none', 'NONE'); var DNS_DIGITALOCEAN = NewDnsProvider('digitalocean', 'DIGITALOCEAN'); // Domains: D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN), A('@', 'your-server-ipv4-address') );
此示例文件定义了特定提供商的域名或 DNS 区域,在本例中为 DigitalOcean 托管的 example.com
。 还为区域根 (@
) 定义了一个示例 A
记录,指向您托管域/网站的服务器的 IPv4 地址。
构成基本 DNSControl 配置文件的三个主要函数:
NewRegistrar(name, type, metadata)
:为您的域名定义域名注册商。 DNSControl 可以使用它来进行必要的更改,例如修改权威名称服务器。 如果您只想使用 DNSControl 来管理您的 DNS 区域,通常可以将其保留为NONE
。NewDnsProvider(name, type, metadata)
:为您的域名或委托区域定义一个DNS服务提供商。 这是 DNSControl 将推送您所做的 DNS 更改的地方。D(name, registrar, modifiers)
:定义一个域名或委托 DNS 区域供 DNSControl 管理,以及该区域中存在的 DNS 记录。
您应该使用官方 DNSControl 文档中的 服务提供商列表 相应地配置 NewRegistrar()
、NewDnsProvider()
和 D()
。
如果您使用 DigitalOcean 作为您的 DNS 提供商,并且只需要能够进行 DNS 更改(而不是权威名称服务器),那么前面代码块中的示例已经是正确的。
完成后,保存并关闭文件。
在此步骤中,您将为 DNSControl 设置一个 DNS 配置文件,并定义相关的提供程序。 接下来,您将使用一些有用的 DNS 记录填充该文件。
第 4 步 — 填充您的 DNS 配置文件
接下来,您可以使用 DNSControl 语法为您的网站或服务填充有用的 DNS 记录的 DNS 配置文件。
与传统的 BIND 区域文件不同,其中 DNS 记录以原始的逐行格式写入,DNSControl 中的 DNS 记录被定义为 D()
函数的函数参数(域修饰符),如下所示步骤 3。
每个标准 DNS 记录类型都有一个域修饰符,包括 A
、AAAA
、MX
、TXT
、NS
、[ X133X],以此类推。 DNSControl 文档的 Domain Modifiers 部分提供了可用记录类型的完整列表。
单个记录的修饰符也可用(记录修饰符)。 目前,这些主要用于设置单个记录的 TTL(生存时间)。 DNSControl 文档的 Record Modifiers 部分提供了可用记录修饰符的完整列表。 记录修饰符是可选的,在大多数基本用例中可以省略。
每种记录类型的 DNS 记录设置语法略有不同。 以下是最常见记录类型的一些示例:
A
记录:- 目的:指向一个 IPv4 地址。
- 语法:
A('name', 'address', optional record modifiers)
- 示例:
A('@', 'your-server-ipv4-address', TTL(30))
AAAA
记录:- 目的:指向一个 IPv6 地址。
- 语法:
AAAA('name', 'address', optional record modifiers)
- 示例:
AAAA('@', 'your-server-ipv6-address')
(省略记录修饰符,因此将使用默认 TTL)
CNAME
记录:- 目的:使您的域/子域成为另一个域的别名。
- 语法:
CNAME('name', 'target', optional record modifiers)
- 示例:
CNAME('subdomain1', 'example.org.')
(请注意,如果值中有任何点,则必须包含尾随的.
' )
MX
记录:- 目的:将电子邮件定向到特定的服务器/地址。
- 语法:
MX('name', 'priority', 'target', optional record modifiers)
- 示例:
MX('@', 10, 'mail.example.net')
(请注意,如果值中有任何点,则必须包含尾随的.
' )
TXT
记录:- 目的:添加任意纯文本,通常用于没有自己专用记录类型的配置。
- 语法:
TXT('name', 'content', optional record modifiers)
- 示例:
TXT('@', 'This is a TXT record.')
CAA
记录:- 目的:限制和报告可以为您的域/子域颁发 TLS 证书的证书颁发机构 (CA)。
- 语法:
CAA('name', 'tag', 'value', optional record modifiers)
- 示例:
CAA('@', 'issue', 'letsencrypt.org')
为了开始为您的域或委派的 DNS 区域添加 DNS 记录,请编辑您的 DNS 配置文件:
cd ~/dnscontrol nano dnsconfig.js
接下来,您可以使用前面列表中描述的语法以及官方 DNSControl 文档的 Domain Modifiers 部分开始填充现有 D()
函数的参数。 必须在每条记录之间使用逗号 (,
)。
作为参考,此处的代码块包含基本的初始 DNS 设置的完整示例配置:
~/dnscontrol/dnsconfig.js
... D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN), A('@', 'your-server-ipv4-address'), A('www', 'your-server-ipv4-address'), A('mail', 'your-server-ipv4-address'), AAAA('@', 'your-server-ipv6-address'), AAAA('www', 'your-server-ipv6-address'), AAAA('mail', 'your-server-ipv6-address'), MX('@', 10, 'mail.example.com.'), TXT('@', 'v=spf1 -all'), TXT('_dmarc', 'v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;') );
完成初始 DNS 配置后,保存并关闭文件。
在此步骤中,您将设置初始 DNS 配置文件,其中包含您的 DNS 记录。 接下来,您将测试配置并进行部署。
第 5 步 — 测试和部署您的 DNS 配置
在此步骤中,您将对 DNS 配置运行本地语法检查,然后将更改部署到实时 DNS 服务器/提供程序。
首先,进入你的 dnscontrol
目录:
cd ~/dnscontrol
接下来,使用 DNSControl 的 preview
函数来检查文件的语法,并输出它将进行哪些更改(实际上不进行更改):
dnscontrol preview
如果您的 DNS 配置文件的语法正确,DNSControl 将输出其所做更改的概述。 这应该类似于以下内容:
Output******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE A example.com your-server-ipv4-address ttl=300 #2: CREATE A www.example.com your-server-ipv4-address ttl=300 #3: CREATE A mail.example.com your-server-ipv4-address ttl=300 #4: CREATE AAAA example.com your-server-ipv6-address ttl=300 #5: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 #6: CREATE AAAA www.example.com your-server-ipv6-address ttl=300 #7: CREATE AAAA mail.example.com your-server-ipv6-address ttl=300 #8: CREATE MX example.com 10 mail.example.com. ttl=300 ----- Registrar: none...0 corrections Done. 8 corrections.
如果您在输出中看到错误警告,DNSControl 将提供有关错误在您的文件中的位置和位置的详细信息。
警告: 下一个命令将对您的 DNS 记录和可能的其他设置进行实时更改。 请确保您为此做好准备,包括备份现有 DNS 配置,并确保您有办法在需要时回滚。
最后,您可以将更改推送到您的实时 DNS 提供商:
dnscontrol push
您将看到类似于以下内容的输出:
Output******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 SUCCESS! #2: CREATE A example.com your-server-ipv4-address ttl=300 SUCCESS! #3: CREATE AAAA example.com your-server-ipv6-address ttl=300 SUCCESS! #4: CREATE AAAA www.example.com your-server-ipv6-address ttl=300 SUCCESS! #5: CREATE AAAA mail.example.com your-server-ipv6-address ttl=300 SUCCESS! #6: CREATE A www.example.com your-server-ipv4-address ttl=300 SUCCESS! #7: CREATE A mail.example.com your-server-ipv4-address ttl=300 SUCCESS! #8: CREATE MX example.com 10 mail.example.com. ttl=300 SUCCESS! ----- Registrar: none...0 corrections Done. 8 corrections.
现在,如果您在 DigitalOcean 控制面板中检查您的域的 DNS 设置,您将看到更改。
您还可以通过为您的域/委派区域运行 DNS 查询来检查记录创建。 您会看到记录已相应更新:
dig +short example.com
您将看到显示 IP 地址和相关 DNS 记录的输出,这些记录来自您使用 DNSControl 部署的区域。 DNS 记录可能需要一些时间才能传播,因此您可能需要等待并再次运行此命令。
在最后一步中,您运行了 DNS 配置文件的本地语法检查,然后将其部署到您的实时 DNS 提供商,并测试更改是否成功。
结论
在本文中,您设置了 DNSControl 并将 DNS 配置部署到实时提供商。 现在,您可以在安全的离线环境中管理和测试您的 DNS 配置更改,然后再将它们部署到生产环境。
如果您希望进一步探索此主题,DNSControl 旨在集成到您的 CI/CD 管道中,允许您运行深入的测试并更好地控制您的生产部署。 您还可以考虑将 DNSControl 集成到您的基础架构构建/部署过程中,从而允许您部署服务器并将它们完全自动添加到 DNS。
如果您希望进一步使用 DNSControl,以下 DigitalOcean 文章提供了一些有趣的后续步骤,以帮助将 DNSControl 集成到您的变更管理和基础设施部署工作流程中: