#dns-records #ipv4 #dns #ipv4-address #nat #cloudflare #cloud

bin+lib clouddns-nat-helper

从云提供商的 AAAA 记录自动生成 NAT 设置的 A 记录

13 个版本

0.2.13 2024 年 6 月 9 日
0.2.12 2024 年 5 月 4 日
0.2.11 2023 年 9 月 14 日
0.2.10 2023 年 2 月 1 日
0.1.1-alpha.42022 年 10 月 11 日

命令行工具 中排名第 384

Download history 152/week @ 2024-05-01 5/week @ 2024-05-08 2/week @ 2024-05-22 157/week @ 2024-06-05 26/week @ 2024-06-12 7/week @ 2024-07-03 46/week @ 2024-07-24 17/week @ 2024-07-31

每月下载量 63

自定义许可

98KB
2K SLoC

Release License Coverage

clouddns-nat-helper

一个工具,可以基于 DNS 区域中现有的 AAAA 记录自动生成主机 Ipv4 A DNS 记录。

使用场景

此工具是为了以下场景编写的

  • 托管一个或多个应用程序
  • 应用程序服务器可以通过 IPv6 正常访问,并具有公共 DNS 记录,而 IPv4 访问通过 NAT 进行
  • 您可以自动设置 IPv6 记录,但 IPv4 NAT 地址会定期更改,需要定期更新。
  • 您不希望/无法让每个应用程序更新 DNS A 记录

那么,这种场景何时会出现呢?例如,当您从住宅 ISP 连接托管双栈 Kubernetes 集群时!大多数 ISP 分配单个动态公共 IPv4 地址以及公共 IPv6 前缀。

路由 Ipv6 流量“足够容易”

  1. 在您的前缀中创建一个将包含您的公共 k8s 服务的 Ipv6 子网
  2. 使用 MetalLB 或类似工具从该子网分配服务地址
  3. 使用 external-dns 在外部 DNS 提供商(如 Cloudflare)处生成 DNS 记录以将流量路由到您的网络
    • 注意:在撰写本文时(2022 年 10 月),external-dns 实际上并不支持 Ipv6!是的,真的。幸运的是,有一些分支对我来说是有效的(请参阅这里这里
  4. 调整您的防火墙设置

上述设置的图示

(前缀和配置已略有简化)

然而,这在与 IPv4 地址相关时就不适用了,因为我们没有公共 IPv4 网络可以分配给 k8s 集群。我们可以使用内部 Ipv4 网络来获取 NAT 背后的服务,然后配置我们的 NAT 路由器将这些地址端口转发,但 external-dns 没有意识到如何处理这种情况。它只会将内部 Ipv4 地址推入公共 DNS,这当然是完全错误的。

解决此问题的方法之一是编写一个脚本,该脚本获取公网IP地址,然后将该地址作为硬编码值注入到external-dns配置中[^1]。

另一种方法(这正是此工具所做的事情)是配置external-dns只发布AAAA记录,然后查找没有相关A记录的AAAA记录并生成它们。

[^1]:请注意,这需要运行两个版本的external-dns,一个用于IPv4并使用硬编码值,另一个用于IPv6。可能会变得混乱

工作原理

此工具操作分为3个基本步骤

  1. 它从DNS提供商(如Cloudflare)读取记录
  2. 它查找具有AAAA记录但没有A记录的域名
  3. 它根据提供的IPv4地址源(如静态地址或查询的主机名)为这些缺失的域名创建A记录

nat-helper还使用TXT记录(或未来可能的其他注册表)跟踪域名所有权,这意味着它知道哪些A记录是由它创建的,哪些不是。这也允许我们跟踪更改,在记录过时时更新记录,以及在没有更多AAAA记录时删除所有权的域名上的A记录。

状态

该项目旨在用于实验性、爱好者和其他非生产性用途。尽管如此,它是在可靠性、安全性和可扩展性的考虑下构建的。然而,请自行承担风险。在需要时,未来版本可能会发生破坏性更改。

提供程序、注册表和Ipv4Sources使用可插拔接口,因此将来添加新的是简单的。

安装

二进制文件

您可以从发布页面下载linux二进制文件。

使用Cargo

如果您已安装cargo,只需运行

cargoinstall clouddns-nat-helper

通过Docker

Docker镜像会自动构建并推送到以下注册表

注意

  • 建议您使用版本标签(例如 :0.2),以确保不会发生破坏性更改
  • latest标签指向此存储库的master分支,并且可能在任何时间破坏
  • 支持的架构:amd64arm64。这些镜像都是多架构镜像,因此无需指定架构标签

要向镜像传递参数,请使用环境变量或环境文件

$ docker run --env-file ./.env maxhoesel/clouddns-nat-helper:0.1

$ cat .env
# there are more configuration options available, run with --help, check the README and see src/bin/cli/mod.rs for more details
CLOUDDNS_NAT_PROVIDER=cloudflare
CLOUDDNS_NAT_CLOUDFLARE_API_TOKEN=abc123456789

CLOUDDNS_NAT_SOURCE=hostname
CLOUDDNS_NAT_IPV4_HOSTNAME=maxhoesel.de

您还可以通过在此项目的根目录中运行docker build来创建自己的容器。

在kubernetes集群中

官方推荐的安装clouddns-nat-helper的方式是通过Helm。

首先,安装存储库,如下所示

helm repo add spacebird https://charts.spacebird.dev

然后,安装图表

helm install clouddns-nat-helper spacebird/clouddns-nat-helper \
  --create-namespace
  --namespace clouddns-nat-helper
  --values values.yml

用法

几乎所有的标志都可以通过命令行或环境变量传递。

有关所有标志的列表,请参阅clouddns-nat-helper --help

快速入门

clouddns-nat-helper-s hostname-p cloudflare--ipv4-hostname<yourdomain.invalid> --cloudflare-api-token<your_cf_api_token>

  • -s指定要使用的IPv4源。在这里,使用主机名解析IP地址
    • --ipv4-hostname指定要解析其IP地址的主机名
  • -p指定要使用的DNS提供商
    • 目前仅支持cloudflare
    • --cloudflare-api-token 是您的API密钥。您可能希望通过环境变量(CLOUDDNS_NAT_CLOUDFLARE_API_TOKEN)传递以提高安全性

一些其他有用的选项

  • --dry-run/-d:预览将要进行的更改
  • --run-once:如果您只想运行一次工具,请设置此选项
  • --interval/-i:设置运行之间的不同间隔,默认为60秒

限制执行操作和控制所有权

如上所述,此工具将不会修改它未创建/不拥有的任何记录。本身,这应该可以防止与手动输入的IPv4地址或其他DNS自动化发生冲突。

但是,如果您想更加小心,或者遇到这种情况不适用的情况,您可以进一步限制允许的操作。


注意

如果您想手动更改此工具之前管理的A记录,您需要先删除其所有权信息。对于TXT注册表(默认),删除与该域名关联的所有权TXT记录(查找包含 clouddns 的受影响域名的TXT记录)。

删除此记录将删除域名的所有权,并且工具将不再干扰您的手动输入


--policy 标志可以用来限制此工具可能对记录执行的操作。选项有

  • createonly:不修改任何记录,仅创建新的。 这会中断记录更新,并且不适用于动态IPv4地址
  • upsert:创建记录并更新现有记录,但如果相应的AAAA记录被删除则不删除A记录
  • sync(默认):根据需要执行创建、更新和删除操作

开发

入门

要开始此项目的开发,请按照以下步骤操作

  1. 克隆此存储库
  2. 安装 cargo-make: cargo install cargo-make --locked
  3. (可选但推荐)安装 pre-commit
  4. (可选,用于Docker构建和交叉编译)确保已安装docker
  5. 祝您编码愉快!

此项目使用最新版本的Rust和 cargo-make 进行构建。大多数常见操作可以通过运行 cargo make <command> 来执行。有关可用操作的列表,请参阅 cargo make --list-all-steps

代码风格检查

  • cargomake lint

构建

  • 本地构建: cargo make build
  • 对于发布二进制文件: cargo make -p release build

此项目使用 cross 为不同的目标平台交叉编译二进制文件。您可以通过以下方式创建针对不同目标的二进制文件

  • 调试: cargo make build-aarch64-unknown-linux-gnu
  • 发布: cargo make -p release build-aarch64-unknown-linux-gnu

要查看可用的目标,请运行以下命令:cargo make --list-category-steps build

测试

  • 默认(主机)目标:cargo make test
  • 自定义目标:cargo make test-aarch64-unknown-linux-gnu
  • 获取覆盖率报告:cargo make coverage

文档

  • cargomake docs

Docker

  • 为本地平台构建镜像:cargo make docker
  • 自定义目标:cargo make docker-arm64
    • 确保您的系统可以使用QEMU构建多平台镜像
    • cargo-make将自动生成适当的构建器。
  • 使用自定义标签构建镜像:cargo make -e DOCKER_TAG=registry.invalid/user/project:0.1.2 docker

发布管理

草稿发布通过version-maintenance工作流程自动管理。按照这些草稿中的说明发布新版本。

依赖项

~10–23MB
~358K SLoC