PowerDNS IPv6

From Eric's wiki
Jump to: navigation, search

Als je met IPv6 aan de gang gaat, zal je vroeg of laat ook een IPv6 enabled DNS server nodig hebben.

Omdat PowerDNS voor mij altijd prima heeft gefunctioneerd was dit mijn eerste keus toen ik mijn eigen DNS ging opzetten.

Al snel bleek dat IPv6 vreemde problemen met zich mee kan brengen, afhankelijk van de software implementatie. Je hebt dus wat achtergrond informatie nodig voor alles probleemloos werkt.

Luisteren op IPv6 en IPv4 (Dual stack)

Het eerste probleem dat ik tegenkwam, hoe zorg ik ervoor dat de server zowel op IPv6 als IPv4 beschikbaar is. In de configuratie kan je dit aangeven met de volgende opties:

#################################
# local-address	Local IP address to which we bind
#
local-address=0.0.0.0

#################################
# local-ipv6	Local IP address to which we bind
#
#local-ipv6=
#################################

In bovenstaand voorbeeld zal hij alleen op IPv4 luisteren. Passen we nu local-ipv6 aan naar :: krijgen we een ander probleem.

Als je in linux een port bind aan :: (ipv6 versie van 0.0.0.0) luistert hij standaard ook op IPv4. Dat kan niet want PowerDNS luistert daar al vanwege de local-address optie. Je krijgt dus een leuke 'Port is already in use' melding.

Dit is op verschillende manieren op te lossen, 1 van de methoden welke ik tegen kwam met google is:

local-address=
local-ipv6=::

Dit zorgt ervoor dat hij niet expliciet op IPv4 luistert, maar door de 2e optie wel op beide.

UDPv6 server bound to [::]:53
TCPv6 server bound to [::]:53

Master/Slave replicatie

Dit leek een poosje een prima oplossing tot ik tegen het volgende liep. Bij het aanmaken van een nieuw domain werd de 1e AXFR (zonetransfer) naar de slave prima verzonden maar ik kreeg geen updates meer!

1e AXFR:

Domain axfr.lan is stale, master serial 2011021700, our serial 0
Initiating transfer of 'axfr.lan' from remote '10.0.2.14'
AXFR started for 'axfr.lan', transaction started
AXFR done for 'axfr.lan', zone committed

Updates:

Received NOTIFY for axfr.lan from ::ffff:10.0.2.14 which is not a master

Het gaat hier mis omdat in de database een IPv4 adres is opgenomen als Master, terwijl technisch gezien geen IPv4 socket open staat voor verzoeken. Als Linux luistert op '::' zullen inkomende verbindingen worden vertaald naar 'IPv6-like' adressen en deze matchen niet met de data in database.

Kernel optie aanpassen

Een alternatief is om een kernel optie aan te passen, sys.net.ipv6.bindv6only is een boolean waarmee het gedrag aangepast kan worden van het binden van poorten aan '::'. Wanneer deze optie aanstaat zal hij niet tegelijk op IPv4 binden. Hierdoor kan je apart op IPv4 en IPv6 gaan binden. Dit wordt dan echter voor alle software toegepast wat misschien niet altijd wenselijk is:

echo 1 > /proc/sys/net/ipv6/bindv6only
local-address=0.0.0.0
local-ipv6=::
UDP server bound to 0.0.0.0:53
UDPv6 server bound to [::]:53
TCP server bound to 0.0.0.0:53
TCPv6 server bound to [::]:53

Hierna werkt alle functionaliteit weer naar behoren.

Selectief luisteren

Er is nog 1 alternatieve manier om DNS dual stack te draaien zonder problemen en zonder de bindv6only optie. Door gewoon de publieke adressen op te geven luistert PowerDNS niet op alle IP's, maar alleen op de opgegeven adressen. Daardoor zal hij ook onderscheid kunnen maken tussen IPv4 en IPv6:

local-address=178.239.60.98
local-ipv6=2a00:dd0:0:14:216:3eff:fe52:3af

Deze laatste optie heb ik uiteindelijk gekozen.