IPv6 only DNS64 server

DNS64

Stejně jako asi všichni ostatní, používáme k přístupu do IPv4 sítě z IPv6 serverů klasickou konfiguraci DNS64 a NAT64. Většinou tato konfigurace funguje stabilně. Narazili jsme však na některé (převážně starší) aplikace, které se snaží připojit k IPv4 serverům, pokud dostanou v DNS odpovědi A záznam i AAAA záznam. Očekávané chování v tomto případě je, že se pokusí připojit přes IPv4 (pokud jí preferují) a v případě nedostupnosti zkusí IPv6 spojení. Bohužel tomu tak nebylo a celá IPv6 síť byla ignorována.

V momentě, kdy jim DNS server vrátil pouze AAAA odpověď, tak připojení funguje v pořádku.

Řešení

Protože se tento případ opakoval napříč několika aplikacemi, rozhodli jsme se situaci řešit globálně na našich DNS64. Tyto DNS servery používáme jen u serverů, které nemají IPv4 a zároveň se do IPv4 sítě potřebují připojovat. Ve výchozím režimu se snažíme tyto DNS (a celý NAT64) na serverech vůbec nepoužívat a nechváme servery používat jen IPv6 síť.

DNS64 servery tedy využívá minorita serverů. Z této minority serverů navíc žádný ze serverů nepotřebuje mít originální DNS záznamy. Rozhodli jsme se proto na DNS64 serverech úplně zahazovat všechny požadavky na A záznamy.

Aplikace, které vyloženě potřebují mít nezměněné DNS odpovědi by stejně DNS64 servery neměly používat a kdykoliv mohou používat jakékoliv jiné DNS servery.

Implementace

Jako DNS64 resolvery používáme PowerDNS recursor, aktuálně ve verzi 4.0. Celou filtraci DNS záznamů včetně DNS64 překladu děláme pomocí LUA scriptu.

/etc/powerdns/recursor.conf

Úpravy, které jsme dělali v konfiguračním souboru:

dnssec=off
forward-zones-recurse=.=[2001:4860:4860::8888];[2606:4700:4700::1111]
allow-from=::/0
query-local-address6=::
lua-dns-script=/etc/powerdns/dns64.lua

dnssec=off

DNSSEC musí být vypnutý, protože přepisujeme odpovědi.

forward-zones-recurse=.=[2001:4860:4860::8888];[2606:4700:4700::1111]

Nadřazené DNS servery, kterých se ptáme (Google a cloudflare)

allow-from=::/0

Povolíme dotazy z celé IPv6 (omezení na naše IP adresy existuje v rámci firewallu)

query-local-address6=::

S verzí 4.0 nám DNS po IPv6 síti nefungovalo, muselo se explicitně povolit. V novějších verzích už může být výchozí hodnota jiná. Od verze 4.4 bude odstraněna

# Source IPv6 address for sending queries. IF UNSET, IPv6 WILL NOT BE USED FOR OUTGOING QUERIES

lua-dns-script=/etc/powerdns/dns64.lua

Nastavíme cestu ke scriptu, kterým filtrujeme odpověďi lua-dns-script=/etc/powerdns/dns64.lua

/etc/powerdns/dns64.lua

prefix = "64:ff9b::"

function nodata ( dq )
  if dq.qtype ~= pdns.AAAA then
    return false
  end  --  only AAAA records

  -- dont fake AAAA records if DNSSEC validation failed
  -- this works on pdns-recursor > 4.1, we use 4.0
  -- if dq.validationState == pdns.validationstates.Bogus then
     -- return false
  -- end

  dq.followupFunction = "getFakeAAAARecords"
  dq.followupPrefix = prefix
  dq.followupName = dq.qname
  return true
end

-- the ip6.arpa address is the reverse of the prefix address above
function preresolve ( dq )
 if dq.qtype == pdns.A then
        return true;
    end

  if dq.qtype == pdns.PTR and dq.qname:isPartOf(newDN("b.9.f.f.4.6.0.0.ip6.arpa.")) then
    dq.followupFunction = "getFakePTRRecords"
    dq.followupPrefix = prefix
    dq.followupName = dq.qname
    return true
  end
  return false
end

Závěr

Tuto změnu už máme na našich DNS64 serverech nasazenou přes půl roku a nesetkali jsme se s žádným problémem.

Dlouhodobě však doufáme, že počet serverů v IPv6 síti bude růst a naše DNS64 a NAT64, které už nyní jsou velmi málo používané, nebudeme používat vůbec nebo jen v okrajovém případě. Dle statistik se aktuálně nejvíce těšíme až bude po IPv6 dostupný github, který u nás na NAT64 serverech dělá nejvíce provozu.