SLAAC and local IPv6 AAAA records in DNS forwarder

I have a fairly simple home network with both IPv4 and IPv6. I get a IPv6 prefix from my ISP and advertise it to local devices on my LAN through RA. Each device configures itself using SLAAC.

I have also configured a DNS forwarder in VyOS to cache DNS requests and provide DNS for LAN devices. All devices are informed about the DNS through either DHCP or RA. The local devices identify with the home.arpa domain. This works well for local IPv4 devices which advertise their hostname to the IPv4 DHCP server. The DHCP server writes the resulting hostname and IPv4 address to /etc/hosts such that the VyOS DNS forwarder picks it up. I can lookup mydevice as mydevice.home.arpa from any device on the network.

I can not figure out how to get this kind of local DNS resolution for the IPv6 addresses. Does SLAAC even inform VyOS about the resulting IP? And is there a way I can feed those dynamic IPv6 addresse into the DNS forwarder? What is the recommended way to get the IPv6 address of local devices when using SLAAC?

I am fairly new with VyOS. I have used an EdgeRouter 4 for the last eight years without really touching the tree config, and now I have a new box with VyOS. I am pretty sure that I got DNS resolution of IPv6 addresses on EdgeRouter, but I do not know how it did it.

Below is the sanitized config for VyOS (eth0 is WAN, eth1 is LAN):

firewall {
    group {
        interface-group WAN {
            interface "eth0"
        }
    }
    ipv4 {
        name LAN-LOCAL {
            default-action "accept"
        }
        name LAN-WAN {
            default-action "accept"
            rule 6 {
                action "drop"
                state "invalid"
            }
        }
        name LOCAL-LAN {
            default-action "accept"
        }
        name LOCAL-WAN {
            default-action "accept"
        }
        name WAN-LAN {
            default-action "drop"
            rule 5 {
                action "accept"
                description "Allow Established/Related traffic from WAN to LAN"
                state "established"
                state "related"
            }
            rule 6 {
                action "drop"
                state "invalid"
            }
            rule 10 {
                action "accept"
                connection-status {
                    nat "destination"
                }
                description "Allow all destination NAT (DNAT) port forwarding connections."
            }
            rule 20 {
                action "accept"
                protocol "icmp"
            }
        }
        name WAN-LOCAL {
            default-action "drop"
            rule 5 {
                action "accept"
                description "Allow Established/Related traffic to LOCAL from WAN."
                state "established"
                state "related"
            }
            rule 6 {
                action "drop"
                state "invalid"
            }
            rule 10 {
                action "accept"
                connection-status {
                    nat "destination"
                }
                description "Allow all estination NAT (DNAT) port forwarding connections."
            }
            rule 20 {
                action "accept"
                protocol "icmp"
            }
        }
    }
    ipv6 {
        name LAN-LOCAL {
            default-action "accept"
        }
        name LAN-WAN {
            default-action "accept"
            rule 6 {
                action "drop"
                state "invalid"
            }
        }
        name LOCAL-LAN {
            default-action "accept"
        }
        name LOCAL-WAN {
            default-action "accept"
        }
        name WAN-LAN {
            default-action "drop"
            rule 5 {
                action "accept"
                state "established"
                state "related"
            }
            rule 6 {
                action "drop"
                state "invalid"
            }
            rule 20 {
                action "accept"
                protocol "ipv6-icmp"
            }
        }
        name WAN-LOCAL {
            default-action "drop"
            rule 5 {
                action "accept"
                state "established"
                state "related"
            }
            rule 6 {
                action "drop"
                state "invalid"
            }
            rule 20 {
                action "accept"
                protocol "ipv6-icmp"
            }
            rule 30 {
                action "accept"
                description "Allow DHCPv6 configuration"
                destination {
                    port "546"
                }
                protocol "udp"
                source {
                    port "547"
                }
            }
            rule 40 {
                action "accept"
                description "Allow Wireguard to router."
                destination {
                    port "51820"
                }
                protocol "udp"
            }
        }
    }
    zone LAN {
        default-action "drop"
        description "Zone for LAN"
        from LOCAL {
            firewall {
                ipv6-name "LOCAL-LAN"
                name "LOCAL-LAN"
            }
        }
        from WAN {
            firewall {
                ipv6-name "WAN-LAN"
                name "WAN-LAN"
            }
        }
        member {
            interface "eth1"
            interface "wg1"
        }
    }
    zone LOCAL {
        default-action "drop"
        description "Zone for LOCAL (router-internal)"
        from LAN {
            firewall {
                ipv6-name "LAN-LOCAL"
                name "LAN-LOCAL"
            }
        }
        from WAN {
            firewall {
                ipv6-name "WAN-LOCAL"
                name "WAN-LOCAL"
            }
        }
        local-zone
    }
    zone WAN {
        default-action "drop"
        description "Zone for WAN (big internet)"
        from LAN {
            firewall {
                ipv6-name "LAN-WAN"
                name "LAN-WAN"
            }
        }
        from LOCAL {
            firewall {
                ipv6-name "LOCAL-WAN"
                name "LOCAL-WAN"
            }
        }
        member {
            interface "eth0"
        }
    }
}
interfaces {
    ethernet eth0 {
        address "dhcp"
        address "dhcpv6"
        description "WAN"
        dhcp-options {
            default-route-distance "10"
        }
        dhcpv6-options {
            pd 0 {
                interface eth1 {
                    address "1"
                    sla-id "16"
                }
                length "48"
            }
        }
        hw-id "00:d0:b4:05:c5:90"
        ipv6 {
            address {
                autoconf
            }
        }
        mac "fc:ec:da:43:fd:b8"
        offload {
            gro
            gso
            sg
            tso
        }
    }
    ethernet eth1 {
        address "192.168.10.1/24"
        address "fd00:10::1/64"
        description "LAN"
        hw-id "00:d0:b4:05:c5:91"
        ipv6 {
            address {
                autoconf
            }
        }
        offload {
            gro
            gso
            sg
            tso
        }
    }
    loopback lo {
    }
}
nat {
    source {
        rule 100 {
            description "NAT of regular LAN traffic to WAN."
            outbound-interface {
                group "WAN"
            }
            source {
                address "192.168.10.0/24"
            }
            translation {
                address "masquerade"
            }
        }
    }
}
service {
    dhcp-server {
        hostfile-update
        shared-network-name LAN {
            authoritative
            option {
                domain-name "home.arpa"
                domain-search "home.arpa"
                name-server "192.168.10.1"
            }
            subnet 192.168.10.0/23 {
                lease "86400"
                option {
                    bootfile-name "netboot.xyz-snponly.efi"
                    bootfile-server "192.168.10.10"
                    default-router "192.168.10.1"
                    tftp-server-name "192.168.10.10"
                }
                range 0 {
                    start "192.168.10.64"
                    stop "192.168.10.250"
                }
                static-mapping myfixeddevice {
                    ip-address "192.168.10.10"
                    mac "f8:b1:56:a3:b3:4d"
                }
                subnet-id "1"
            }
        }
    }
    dns {
        forwarding {
            allow-from "192.168.10.0/24"
            allow-from "fd00:10::/64"
            listen-address "192.168.10.1"
            listen-address "fd00:10::1"
            system
        }
    }
    ntp {
        allow-client {
            address "127.0.0.0/8"
            address "169.254.0.0/16"
            address "10.0.0.0/8"
            address "172.16.0.0/12"
            address "192.168.0.0/16"
            address "::1/128"
            address "fe80::/10"
            address "fc00::/7"
        }
        server time1.vyos.net {
        }
        server time2.vyos.net {
        }
        server time3.vyos.net {
        }
    }
    router-advert {
        interface eth1 {
            dnssl "home.arpa"
            name-server "fd00:10::1"
            prefix ::/64 {
            }
            prefix fd00:10::/64 {
            }
        }
    }
}
system {
    console {
        device ttyS0 {
            speed "115200"
        }
    }
    domain-name "home.arpa"
    host-name "vyos-router"
    name-server "1.1.1.1"
    name-server "8.8.8.8"
    name-server "2606:4700:4700::1111"
    name-server "2001:4860:4860::8888"
    option {
        kernel {
            disable-mitigations
        }
        keyboard-layout "no"
        reboot-on-upgrade-failure "5"
        startup-beep
    }
    syslog {
        local {
            facility all {
                level "info"
            }
            facility local7 {
                level "debug"
            }
        }
    }
    time-zone "Europe/Oslo"
}

No, when using router-advertisements the router has no way of knowing wat clients are there so it cannot updates your DNS forwarder. They just pick up the RA, create their config and start using it.

I guess if you want the DNS part to work you have to use DHCPv6, but I never tried if that works.

No, when using router-advertisements the router has no way of knowing wat clients are there so it cannot updates your DNS forwarder. They just pick up the RA, create their config and start using it.

I guess if you want the DNS part to work you have to use DHCPv6, but I never tried if that works.

That is not entirely true, there might be no automatism (at least not in the exact same way as with IPv4), but every host in an IPv6 subnet is well aware of its neighbors and their addresses via NDP.

Regarding the original question: This setup is also something I want to achieve in the long run; it is of quite low priority though, thus I haven’t investigated too much yet. In short it should work via mDNS. How one would implement that with VyOS (so that mDNS announcements are taken over into static DNS) I can’t tell (yet) :confused:

EDIT: At least 2024 it was not yet possible to resolve mDNS from VyOS, IMHO implying VyOS can’t do anything with it (besides relaying).

Thanks for the suggestions. It would be cool if NDP could feed link-local IPv6 into DNS. When I look at show ipv6 neighbors state reachable I see a bunch of LL addresses. However, it does not show hostname. Is hostname a part of NDP, or is NDP limited to only MAC and LL address?

I will look a bit more into mDNS to see if I can get something to work. The strange thing is that I feel that this was working well on the EdgeRouter 4. Perhaps I should poke a bit around in that one as well to see which services it runs.

It would be cool if NDP could feed link-local IPv6 into DNS.

Depending on your actual layout, that might not even be that useful :confused: Such hosts would only be reachable within the same L2 domain, besides that, what name would they be given?

Is hostname a part of NDP, or is NDP limited to only MAC and LL address?

I don’t think so, IPv6 got quite strict in separation of concerns. It takes care of quite some basic stuff, but names ain’t one of them. Without mDNS you’ll probably have a hard time. If you did some research and are able to confirm my assumption about VyOS being unable to do much with mDNS, you could open a feature request to change that. It would be really great to allow VyOS to ingest any mDNS info from networks attached to it.

The strange thing is that I feel that this was working well on the EdgeRouter 4.

Is that running VyOS as well? I’m not too familiar with proprietary networking stuff, I focus more on the OSS side of things. :sweat_smile:

Edgerouter series are just like VyOS a fork of Vyatta.

As I recall it Ubiquiti forked it to add support for MIPS64 as CPU architecture or something like that while VyOS forked due to misbehaviour from Brocade who tried to kill the Vyatta community.

Interesting, I was unaware of that!

On the other hand, this must mean for EdgeRouter there was some mDNS handling added, which is still missing on the VyOS side of things :confused:

Broadcom has a habit of doing that, they also killed the free VMware ESXi hypervisor.

When you use DHCP, you have a central service in charge of issuing IP adresses or IPv6 prefixes and hostnames. It can update a DNS server with this information, providing the DNS server supports RFC 2136.

The DHCP server in VyOS, kea, supports that (via set service dhcp-server dynamic-dns-update), but the DNS in VyOS is only a recursor, it can emulate authorative zones, but it is not a full authorative DNS server. So you need an external DNS server with RFC2136 support.

SLAAC has no central component, so you will have to rely on mDNS. Which is a local segemnt broadcast mechanism, so it works without a central service, as long as clients support mDNS (which apart from Windows all do). VyOS has an mDNS repeater to deal with the “local segment only” issue of mDNS.