在 DN42 中注册自己的域名

来源:https://lantian.pub/article/modify-website/register-own-domain-in-dn42.lantian


DN42 全称 Decentralized Network 42(42 号去中心网络),是一个大型的 VPN 网络。但是与其它传统 VPN 不同的是,DN42 使用了大量在互联网骨干上应用的技术(例如 BGP),可以很好的模拟一个真实的网络环境。

我在先前的一篇文章中加入了 DN42 网络,并连接了大部分自己拥有的 VPS。(剩下几台是没有 Tun/Tap 的 OpenVZ VPS,无法加入)之前我就知道 DN42 拥有自己的域名体系,例如 DN42 的 Wiki 站(https://wiki.dn42.us/Home)就可以在 DN42 中以 https://internal.dn42 的域名访问,但是之前没有时间去完成域名注册,并且当时对 DN42 的了解还不够。这个月我完成了域名注册,就来分享一下过程。

搭建权威 DNS 服务器

权威 DNS 服务器,就是指管理某个域名记录的服务器。例如本站主域名 lantian.pub 的权威服务器是 lv3ns[1-4].ffdns.net,就是 CloudXNS。在互联网上注册域名时,我们可以用现成的 CloudXNS、Cloudflare 等免费 DNS 服务,但是在 DN42 中,虽然有人提供这样的服务,但是需要在 IRC 上与他们交流申请,我觉得太麻烦,就干脆自建了。

Linux 下自建 DNS 一般使用 Bind 或 PowerDNS 两款软件。Bind 以文件形式保存 DNS 记录,跨服务器同步有些麻烦,而 PowerDNS 不仅可以用文件保存,还可以用 MySQL 等数据库形式保存,同时自己也提供记录同步功能。

由于我配置 PowerDNS 自带的记录同步功能总是失败,查不出原因,我就干脆设置了 MySQL 主从复制来进行同步。

搭建 DNS:设置 MySQL 主从同步

首先,在每台服务器中安装一个 MySQL,并且在 my.cnf 设置上这些内容:

# 每台服务器的编号,随便设置,但不能重复  server-id=1  # 每台服务器的名称,设置后可以在 phpMyAdmin 中看到从服务器的名字  report-host=Master  # MySQL 日志文件的位置,主从复制的核心文件  log_bin=mysql-bin  log_error=mysql-bin.err

然后用 phpMyAdmin 登录主 MySQL 服务器,在"Replication / 主从复制"页面将这台服务器设置为 Master / 主服务器,并创建一个用于主从复制的用户(拥有 REPLICATION SLAVE 和 REPLICATION CLIENT 权限)。由于这一步我已经做过了,所以我没法截图。

设置完后你应该可以看到类似这样的状态:

插图

其中的"File / 文件名"就是日志文件名,"Position / 位置"就是当前记录的行数。记下这两个值。

然后,关闭所有服务器上的 MySQL,用 rsync 之类方法把数据库复制到从服务器上,覆盖掉各自的数据目录,再打开所有的 MySQL。如果是没什么数据库写入操作的站,例如个人小博客,可以尝试不关主服务器 MySQL,但是可能会造成复制出去的数据损坏。

然后,用 phpMyAdmin 登录从 MySQL 服务器。因为 phpMyAdmin 在设置从服务器时有奇怪的 bug,所以我没用它的向导来设置,而是直接执行 SQL:

change master to master_host='服务器 IP',  master_user='主从复制用户名',  master_password='主从复制用户密码',  master_log_file='主服务器日志文件名',  master_log_pos=主服务器记录行数;  start slave;

然后进入"Replication / 主从复制"页面,点击"See slave status table / 查看从服务器状态表",确认 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes,主从同步就已经开始了。

插图

搭建 DNS:设置 PowerDNS

设置完数据库,我们就可以设置 PowerDNS 了。先在 MySQL 给 PowerDNS 建立一个用户和数据库。因为我是 Docker 用户,所以在主服务器上,直接用 docker-compose 下载镜像并启动:

powerdns:

image: psitrax/powerdns  container_name: powerdns  restart: always  entrypoint: "/entrypoint.sh --cache-ttl=120 --master=yes --slave=yes"  environment:    - MYSQL_HOST=数据库服务器地址    - MYSQL_USER=数据库用户名    - MYSQL_PASS=数据库密码    - MYSQL_DB=数据库名字  ports:    - "DN42 内的 IP 地址:53:53"    - "DN42 内的 IP 地址:53:53/udp"

然后 PowerDNS 可能会启动失败,提示在创建 comments 表时某些列过长。这是因为 MySQL 的一些配置被修改了,导致数据表的行为发生了变化,而这些列最长可达 64000 Bytes,修改后的数据表存不下。

解决这个问题不需要再改数据库配置,只需要把 64000 改小,例如 16000,然后手动创建表即可:

CREATE TABLE domains (    id                    INT AUTO_INCREMENT,    name                  VARCHAR(255) NOT NULL,    master                VARCHAR(128) DEFAULT NULL,    last_check            INT DEFAULT NULL,    type                  VARCHAR(6) NOT NULL,    notified_serial       INT DEFAULT NULL,    account               VARCHAR(40) DEFAULT NULL,    PRIMARY KEY (id)  ) Engine=InnoDB;    CREATE UNIQUE INDEX name_index ON domains(name);    CREATE TABLE records (    id                    INT AUTO_INCREMENT,    domain_id             INT DEFAULT NULL,    name                  VARCHAR(255) DEFAULT NULL,    type                  VARCHAR(10) DEFAULT NULL,    content               VARCHAR(64000) DEFAULT NULL,    ttl                   INT DEFAULT NULL,    prio                  INT DEFAULT NULL,    change_date           INT DEFAULT NULL,    disabled              TINYINT(1) DEFAULT 0,    ordername             VARCHAR(255) BINARY DEFAULT NULL,    auth                  TINYINT(1) DEFAULT 1,    PRIMARY KEY (id)  ) Engine=InnoDB;    CREATE INDEX nametype_index ON records(name,type);  CREATE INDEX domain_id ON records(domain_id);  CREATE INDEX recordorder ON records (domain_id, ordername);    CREATE TABLE supermasters (    ip                    VARCHAR(64) NOT NULL,    nameserver            VARCHAR(255) NOT NULL,    account               VARCHAR(40) NOT NULL,    PRIMARY KEY (ip, nameserver)  ) Engine=InnoDB;    CREATE TABLE comments (    id                    INT AUTO_INCREMENT,    domain_id             INT NOT NULL,    name                  VARCHAR(255) NOT NULL,    type                  VARCHAR(10) NOT NULL,    modified_at           INT NOT NULL,    account               VARCHAR(40) NOT NULL,    comment               VARCHAR(16000) NOT NULL,    PRIMARY KEY (id)  ) Engine=InnoDB;    CREATE INDEX comments_domain_id_idx ON comments (domain_id);  CREATE INDEX comments_name_type_idx ON comments (name, type);  CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);    CREATE TABLE domainmetadata (    id                    INT AUTO_INCREMENT,    domain_id             INT NOT NULL,    kind                  VARCHAR(32),    content               TEXT,    PRIMARY KEY (id)  ) Engine=InnoDB;    CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);    CREATE TABLE cryptokeys (    id                    INT AUTO_INCREMENT,    domain_id             INT NOT NULL,    flags                 INT NOT NULL,    active                BOOL,    content               TEXT,    PRIMARY KEY(id)  ) Engine=InnoDB;    CREATE INDEX domainidindex ON cryptokeys(domain_id);    CREATE TABLE tsigkeys (    id                    INT AUTO_INCREMENT,    name                  VARCHAR(255),    algorithm             VARCHAR(50),    secret                VARCHAR(255),    PRIMARY KEY (id)  ) Engine=InnoDB;    CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

这下 PowerDNS 就能成功启动了,但是它还没有任何记录。

搭建 DNS:安装 PowerAdmin

PowerAdmin 是一个 PowerDNS 的控制面板,可以去 https://github.com/poweradmin/poweradmin 下载安装。安装过程只需要跟着向导走即可,在此略过。

安装完后,进入主界面:

插图

点"Add Master Zone / 添加主区域",这里是添加你要解析的域名的地方。在"Zone Name / 域名"中填入域名,然后直接确定。

返回主界面,点"List Zones / 域名列表",点击域名左边的编辑按钮进行管理,进入如下界面,这里以我的 DN42 域名 lantian.dn42 为例:

插图

最开始装完 PowerAdmin 之后,创建的 SOA 记录开头可能是没有类似 ns1.lantian.dn42 一类的内容的,这样的 SOA 记录就不符合规范。我的 SOA 记录是"ns1.lantian.dn42 lantian.lantian.dn42 0 28800 7200 604800 60",解释如下:

  • ns1.lantian.dn42:主要 DNS 服务器的名字,一般就是你现在在操作的服务器之后要取的域名。
  • lantian.lantian.dn42:DNS 服务器管理者的邮箱,但是 @ 符号被句点代替了,例如这里就是 lantian@lantian.dn42。在 DN42 中不一定需要真实地址。
  • 0:记录编号,如果使用 AXFR 等进行 DNS 记录同步,从 DNS 服务器可能会根据这个编号判断记录有没有更改。我们使用 MySQL 主从复制,所以这里不重要。这里设置为 0 代表 PowerDNS 会自动管理这一项,无需人工操作。
  • 28800:刷新时间,AXFR 从服务器两次拉取的间隔,同样不重要。
  • 7200:重试时间,AXFR 从服务器拉取失败后,再次拉取的时间,同样不重要。
  • 604800:过期时间,AXFR 从服务器拉取失败后,最多用先前最后一次拉取成功的记录继续提供服务这么长时间,之后停止应答。同样不重要。
  • 60:最小 TTL,所有记录的最小刷新时间,至少过了这么长时间才会刷新。

点击 SOA 记录左边的编辑按钮,对应着设置好,保存。

接下来要设置 NS 记录,指明你的域名由这几台 DNS 服务器提供服务。我这次设置 3 台服务器,分别是 ns[1-3].lantian.dn42,需要分别创建相应的 NS 记录,这样填写即可:

插图

一一提交即可。

最后设置 A 记录 指明域名指向某台服务器,这样填写即可:

插图

主 PowerDNS 服务器到此设置完成。因为设置了 MySQL 主从同步,所以你的配置也已经同步到了其它服务器上,在相应的服务器上安装 PowerDNS 即可。

最后 dig 一下自己的服务器测试:

插图

在 DN42 注册域名

DN42 最近进行了一次升级,弃用了原来的 Monotone 管理界面,改用 Git 管理。首先去 https://git.dn42.us/explore/repos 上面注册一个账号,Fork dn42/registry,Clone 到本地。

首先,DN42 要求 Git Commit 经过 GPG 数字签名。我在 Mac 上使用的软件是 GPG Keychain,Windows / Linux 下使用什么软件我并不了解。大致流程是:创建密钥,将公钥提交到 SKS 等公开 GPG 服务器上供查询,然后复制下 Fingerprint。

然后设置 git,打开自动签名每次 commit 的功能:

git config --global user.signingKey [你的 Fingerprint]  git config --global commit.gpgSign true

因为我是 DN42 老用户,已经有了自己的 MNT Handle,就打开 data/mntner/LANTIAN-MNT,加入相应的指纹信息,类似如下:

mntner:             LANTIAN-MNT  admin-c:            LANTIAN-DN42  tech-c:             LANTIAN-DN42  mnt-by:             LANTIAN-MNT  source:             DN42  auth:               pgp-fingerprint 23067C13B6AEBDD7C0BB567327F31700E751EC22

然后创建 data/dns/lantian.dn42:

domain:             lantian.dn42  admin-c:            LANTIAN-DN42  tech-c:             LANTIAN-DN42  mnt-by:             LANTIAN-MNT  nserver:            ns1.lantian.dn42 172.22.76.186  nserver:            ns1.lantian.dn42 fdbc:f9dc:67ad::8b:c606:ba01  nserver:            ns2.lantian.dn42 172.22.76.185  nserver:            ns2.lantian.dn42 fdbc:f9dc:67ad::dd:c85a:8a93  nserver:            ns3.lantian.dn42 172.22.76.187  nserver:            ns3.lantian.dn42 fdbc:f9dc:67ad::18:ca0f:741d  status:             CONNECT  source:             DN42

然后 git add,git commit,git push,然后发 Pull Request 等待合并,并根据管理员的提示修改可能出现的错误。

插图

因为 DN42 中采用 Anycast DNS,每个人都能建立递归 DNS 服务器,而每个人从中心库拉取配置的频率不一,因此可能要等最长一个星期的时间,你的域名才能生效。

插图

到此 DN42 域名就注册成功了,接下来就可以在上面配置网站、邮件、IRC、游戏服务器等等了。


没有评论: