summaryrefslogtreecommitdiff
path: root/_drafts/migrating-dns-servers.md
blob: 20916c0ec64e6552550ee43d5e58a7237af05b3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
---
layout: post
title: Migrating DNS servers
date: 2025-01-10 19:37 +0100
lang: en
categories: tech
---

[As I posted on Mastodon](https://furry.engineer/@uvok/113780013806190576), 

* the DNS registrar (where you register the domain at),
* the DNS hoster / provider (which is responsible for answering DNS requests for
  your domain) and
* the (web) hosting service

can be three different entities / providers, even though for most beginner
projects these are the same.

I migrated my domain over to [INWX](https://www.inwx.de/en). Quite some while
ago, actually (iirc I bought it at a different registrar even further back).
However, their web interface for editing records is a bit clunky. And while they
do provide an API, it's a bit awkward (XML based, and yes, there are ready-made
packages for various programming languages). [1]

With [DN42](https://blog.uvokchee.de/dn42.html), I already used
[PowerDNS](https://doc.powerdns.com/authoritative/) a lot. I actually just use
edit-zone and edit the zone [2] in an editor, that's my preferred way.

So, why not migrate my domain over to my PowerDNS setup? Well, I want some
availability, and I don't trust myself enough not to fuck things up. When my
server is shut down, DNS requests should still be answered. But hey, that's
where secondaries come in! So, I manage the zone, and let another provider
mirror its contents.

Now, only… there's the "problem" of DNSSEC. In conjunction with the DNS
propagation time and TTLs. If I simply set the nameservers (in the de. zone) to
a newly created zone by PowerDNS, the DNSSEC keys will be either not present,
or different. I can't set *additional* keys at INWX easily, I can only switch
to manual keys (by switching off DNSSEC first). Which would lead to a downtime
of up to one day, because people requesting records from my domain (such as
myself) would receive "bogus replies" (invalid signature).

But, I think I found a solution for that. This is my plan, for the registrar
INWX.

1. Download the zone data from the INWX web interface
1. Create the zone in PowerDNS and set various settings

        #!/bin/bash
        zone="example.com"
        pdnsutil create-zone $zone
        pdnsutil set-kind $zone primary
        pdnsutil secure-zone $zone
        pdnsutil set-presigned $zone
        pdnsutil set-meta $zone ALLOW-AXFR-FROM <whatever servers are \
          secondaries>
1. Filter and import the zone. PowerDNS will actually complain about the NSEC3
   records otherwise once you open the zone in your editor.

        grep -vw NSEC3 ./dl-zone.txt > imp-zone.txt 
        pdnsutil load-zone $zone ./imp-zone.txt

1. Set up the secondaries. I went with [Hurricane
   Electric](https://dns.he.net/), but I had to write them an e-mail. I couldn't
   add the zone as secondary myself, because the web interface requires the
   nameservers in the parent zone (?) already to be set to HE, but I wanted a
   zero-downtime migration.
1. Wait for the DNS provider to AXFR. [3]
1. (optional) check with [dnsviz](https://dnsviz.net/) whether you get any
   errors.  You should set the nameserver on the "Analyze" tab, and then set the
   "Additional trusted keys:" to what `dig example.com DNSKEY` tells you. At
   this point, I got warnings/errors regarding the "Denial of existence" /
   NSEC3 records, and some errors because the RRSIGs can't be checked. (Once
   you set a manual nameserver, the tool doesn't seem to check for the parent
   zone anymore? I'm unclear on that).
1. Try to set the new nameservers (nsx.he.net) in the registry (e.h. DENIC) via
   the INWX web interface ("external nameservers").
1. Receive an "UPDATE FAILED". Read the error message. Realize you fucked up.
   You need to set the new nameservers within your own zone first.
1. Add the NS entries to the HE nameservers within your zone in the INWX web
   interface. [4]
1. Download and import the zone file again. Wait for the AXFR.
1. Retry sending the nameservers to the registry. Wait until success.
1. At this point, I checked again with dnsviz. With the default options,
   everything was fine. However, when I enabled the "Denial of existence:"
   option, I received some *extremely scary looking error messages*. I can only
   guess this is because PowerDNS can't generate these records? I *have no
   clue*. Any useful information will be gladly accepted. I choose to ignore it.

        NSEC3 proving non-existence of l2v1y.7t5is.uvokchee.de/A: No RRSIG covering the RRset was returned in the response. See RFC 4035, Sec. 3.1.1. (216.218.130.2, 216.218.131.2, 216.218.132.2, 2001:470:100::2, 2001:470:200::2, 2001:470:300::2, UDP_-_EDNS0_4096_D_KN)
        NSEC3 proving non-existence of uvokchee.de/CNAME: No RRSIG covering the RRset was returned in the response. See RFC 4035, Sec. 3.1.1. (216.218.130.2, 216.218.131.2, 216.218.132.2, 2001:470:100::2, 2001:470:200::2, 2001:470:300::2, UDP_-_EDNS0_4096_D_KN)

1. Wait at least 24 hours (TTLs, DNS propagation time). \
   *I am currently at this step. Further steps are guesswork*.
1. Let PowerDNS output its own keys it generated for the zone.  Unfortunately,
   `pdnsutil export-zone-dnskey $zone $keynr` *does not output a completely
   valid record*, neither does `pdnsutil export-zone-ds $zone`. These outputs
   are missing the TTLs. At least with PowerDNS 4.7.3 in the Debian stable
   repos. I saw some tools like dnsviz break when you enter the records as-is.
   No idea what would happen with INWX.
1. Have a copy of the *current* DS / DNSKEY records as well (`dig` is your
   friend).
1. Set the DNSSEC from "auto" to "manual" in the INWX web interface. Enter *both
   the old and the new* DNSKEY (and DS? Depends on the registrar / registry, I
   guess) records. \
   As far as I know, this will be sent to the parent zone.
1. Wait at least 24 hours (TTLs, DNS propagation time).
1. `pdnsutil unset-presigned $zone`. I guess at this point you must or should
      * stop PowerDNS, [5]
      * edit the zone (e.g. clearing out the RRSIGs you imported, I guess if
        you don't, there'll be trouble. Oh, and the NSEC3PARAM), while also
        increasing the serial. (Otherwise the AXFR might not take place),
      * start PowerDNS,
      * notify the secondaries
1. At this point, you should be done.

By the way, I'll choose to use NSEC instead of NSEC3, seems like too much of a
headache for me.

[1] Okay, it's not like I edit my records that often. \
[2] For the purposes of this blog article, I think you can freely substitute
zone with domain in your head, I probably won't use the words correctly 100% of
the time either. \
[3] DNS zone transfer. \
[4] I think that shouldn't to any damage. DNS recursion should always ask the
parent zone? \
[5] Avoiding a spurious notify or AXFR directly after editing? No idea if
needed.