summaryrefslogtreecommitdiff
path: root/_posts/2025-06-16-oops-dn42-stops-working.md
blob: 26d4ed76d5649c15fbe7afec7721de49deb5b561 (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
---
layout: post
title: Oops, DN42 stopped working
date: 2025-06-16 20:39 +0200
last_modified_at: 2025-06-17 18:12 +0200
lang: en
categories: tech
---

As you might know, I participate in [DN42]({% link dn42.md %}).
I have a somewhat peculiar setup, in
which some VPS run the routing daemons, and my home router simply has a VPN
connection to them and statically routes everything `fd00::/8` to them. The router
runs OpenWRT, and has dnsmasq setup to resolve DN42 domains via the DN42 anycast
servers. I set this up *months ago*, it worked, I was happy, and didn't need it
since.

Cue last weekend. "Suddenly" the resolution didn't work anymore. It simply timed
out. So I connected to my VPS (which is running DN42
[in a namespace]({%post_url 2025-02-02-dn42-put-it-in-a-box-linux-network-namespace %}))
and took a look at tcpdump. Inside the namespace, I saw the strange lines

```
18:49:05.296629 eth0  In  IP6 fd7a:115c:a1e0::xxx > fd42:d42:d42:53::1.53: 42631+ [1au] AAAA? wiki.dn42. (50)
18:49:05.296679 kioubit Out IP6 fd3e:bc05:2d6::80.50255 > fd42:d42:d42:53::1.53: 42631+ [1au] AAAA? wiki.dn42. (50)
18:49:05.302946 tinc_dn42 In  IP6 fd42:d42:d42:53::1.53 > fd3e:bc05:2d6::80.50255: 42631 1/0/1 AAAA fd42:d42:d42:80::1 (66)
18:49:05.302990 kioubit Out IP6 fd3e:bc05:2d6::80 > fd42:d42:d42:53::1: ICMP6, destination unreachable, unreachable route fd3e:bc05:2d6::80, length 122
```

And all the time I was thinking… "huh??? Why is `fd3e:bc05:2d6::80` unreachable???
It is **clearly** in the `ip -6 a` output!!!".  I looked through all the
iptables statistics and couldn't find the culprit.

A join in the DN42 IRC and some back and forth later, someone suggested
"Hey, what's with the `fd7a:…` address? Is there a route for *that*?".

And of course, no, it wasn't! I was so focused on the ICMP6 message that I
didn't notice the incoming line.  As you can read in my other article linked
above, I perform NAT. Of course in that case it probably wouldn't make sense for the
ICMP6 message to tell someone that there's no route for the original IP (before NAT).

**So, but… where does the `fd7a:…` address come from?**<br/>
The answer is [Tailscale]({% post_url 2024-12-08-trying-out-tailscale %}).
Unfortunately, they decided to use the `fd00::/8` IP range, which collides with DN42.
I didn't do any DN42 stuff since installing it, so I didn't notice that.<br/>
**But… why is that address used at all for the DNS request?**<br/>
Weeeeell… I found out as well. It comes from OpenWRT. I simply set up
a static route there, and Linux does its best to determine the source address for the
DNS request. And it seems the Tailscale one was a closer match than 
the address from my own DN42 prefix.<br/>
**So, how to fix that?**<br/>
[It's not as easy as you think!](https://github.com/openwrt/openwrt/issues/13720).
Merely using the "source" option in the config file would work for IPv4, but
for IPv6 it has a different meaning!<br/>
**But why does it say "no route to host" instead of using a default route?**<br/>
Because I configured bird to insert an "unreachable" route for the `fd::/8` prefix
to avoid leaking traffic.
```
# ip -6 route show fd00::/8 table dn42
unreachable fd00::/8 dev lo proto bird src fd3e:bc05:2d6::1 metric 500 pref medium
```

At this point, it's Monday evening. Unnerved, I threw my hands in the air and
simply put a line of
```
ip -6 route replace fd00::/8 ... src <my-openwrt-dn42-address>
```
in `/etc/rc.local` and called it a day.  My setup
works again, and I learned something again. Don't just look at the last line,
look at the whole picture.  A lesson I actually already learned in the
ubuntuusers forums when asking for help compiling a package and only posted the
last few make output lines, which of course didn't contain the actual
compilation error…