systemd-resolvedを利用している環境でclatdのPLAT prefix discoveryが失敗する

[clatd](https://github.com/toreanderson/clatd)では[RFC 7050](https://tools.ietf.org/html/rfc7050 "Discovery of the IPv6 Prefix Used for IPv6 Address Synthesis")に記載されている方法でPLATプレフィックスを検出しますが、systemd-resolvedを利用しているUbuntu 21.04の環境ではプレフィックスを検出できませんでした。

# 環境

```console
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 21.04
Release:	21.04
Codename:	hirsute

$ systemd --version
systemd 247 (247.3-3ubuntu3)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +ZSTD +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether a4:34:d9:36:a5:2e brd ff:ff:ff:ff:ff:ff
    inet6 fd17:c2f7:b096:0:1316:63f8:2293:c8dc/64 scope global temporary dynamic
       valid_lft 604604sec preferred_lft 85889sec
    inet6 fd17:c2f7:b096:0:f551:21ab:cd0e:4613/64 scope global mngtmpaddr noprefixroute
       valid_lft forever preferred_lft forever
    inet6 2001:db8:fc7e:200:a5dc:e067:8e0e:2fcd/64 scope global temporary dynamic
       valid_lft 604604sec preferred_lft 85889sec
    inet6 2001:db8:fc7e:200:b967:1b45:46c2:94e6/64 scope global mngtmpaddr noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::efd9:28cb:4ca8:2083/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
```

# 試したこと

```diff
--- ./clatd/clatd	2021-04-06 23:52:00.236955622 +0900
+++ /usr/sbin/clatd	2021-04-18 17:17:33.196933861 +0900
@@ -347,6 +347,7 @@
     $res->dnssec(0); # RFC 7050 section 3
     my $pkt = $res->query('ipv4only.arpa', 'AAAA');
     if(!$pkt) {
+      d("errorstring: ", $res->errorstring);
       d("No AAAA records was returned for 'ipv4only.arpa'");
       next;
     }
```

```console
# clatd -d
Configuration successfully read, dumping it:
  clat-dev=clat
  clat-v4-addr=192.0.0.1
  clat-v6-addr=<undefined>
  cmd-ip=ip
  cmd-ip6tables=ip6tables
  cmd-tayga=tayga
  debug=1
  dns64-servers=<undefined>
  forwarding-enable=1
  ip6tables-enable=<undefined>
  plat-dev=<undefined>
  plat-prefix=<undefined>
  proxynd-enable=1
  quiet=0
  script-down=<undefined>
  script-up=<undefined>
  tayga-conffile=<undefined>
  tayga-v4-addr=192.0.0.2
  v4-conncheck-delay=10
  v4-conncheck-enable=1
  v4-defaultroute-advmss=0
  v4-defaultroute-enable=1
  v4-defaultroute-metric=2048
  v4-defaultroute-mtu=1260
  v4-defaultroute-replace=0
Starting clatd v1.5 by Tore Anderson <tore@fud.no>
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Looking up 'ipv4only.arpa' using system resolver
errorstring: query timed out
No AAAA records was returned for 'ipv4only.arpa'
No PLAT prefix could be discovered. Your ISP probably doesn't provide NAT64/DNS64 PLAT service. Exiting.

$ dig ipv4only.arpa AAAA

; <<>> DiG 9.16.8-Ubuntu <<>> ipv4only.arpa AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29214
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;ipv4only.arpa.			IN	AAAA

;; ANSWER SECTION:
ipv4only.arpa.		7079	IN	AAAA	64:ff9b::c000:aa
ipv4only.arpa.		7079	IN	AAAA	64:ff9b::c000:ab

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Tue Apr 20 08:07:27 JST 2021
;; MSG SIZE  rcvd: 98
```

loopback以外のインターフェースに適当なIPv4アドレスを設定してみます。

```console
# ip a add 192.168.0.1 dev wlp1s0
# clatd -d
...
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Looking up 'ipv4only.arpa' using system resolver
check_wka(): Testing to see if 64:ff9b:0:0:0:0:c000:aa was DNS64-synthesised
Inferred PLAT prefix 64:ff9b::/96 from AAAA record 64:ff9b:0:0:0:0:c000:aa
check_wka(): Testing to see if 64:ff9b:0:0:0:0:c000:ab was DNS64-synthesised
Inferred PLAT prefix 64:ff9b::/96 from AAAA record 64:ff9b:0:0:0:0:c000:ab
Using PLAT (NAT64) prefix: 64:ff9b::/96
...
```

# 解決方法

`DNSStubListenerExtra=`で[::1]:53をlistenするか、local DNS stub listenerを無効にすれば解決できそうです。

## DNSStubListenerExtra=で[::1]:53をlistenする場合

`DNSStubListenerExtra=`はsystemd 247以降でサポートされています。

```/etc/systemd/resolved.conf
[Resolve]
DNSStubListenerExtra=[::1]:53
```

```/usr/lib/systemd/resolv.conf
nameserver ::1
nameserver 127.0.0.53
options edns0 trust-ad
search .
```

```console
# ln -sf /usr/lib/systemd/resolv.conf /etc/resolv.conf
# systemctl restart systemd-resolved
```

## local DNS stub listenerを無効にする場合

```/etc/systemd/resolved.conf
[Resolve]
DNSStubListener=no
```

```console
# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
# systemctl restart systemd-resolved
```

# 参考

- [Ubuntu 18.04 の systemd-resolved で local DNS stub listener の利用をやめる - Qiita](https://qiita.com/shora_kujira16/items/31d09b373809a5a44ae5)
- [stub listener should support hosts that have no ipv4 at all · Issue #15615 · systemd/systemd · GitHub](https://github.com/systemd/systemd/issues/15615)