DNS
Konzept
Für die interne Nutzung im Freifunknetz besitzt F3 Netze e.V. die Domain fff.community. Im Gegensatz zu anderen Communites verwenden wir keine eigene Toplevel-Domain, um Kollisionen vorzubeugen und Probleme mit DNSSEC zu vermeiden.
Die Zone wird in einem Git [1] verwaltet und über Skripte [2] auf die für diese Zone authoritativen Nameserver einiger Freifunker synchronisiert.
Wenn jemand eine Domain für seinen Service haben möchte, kann dies mit einen Pull Request angefragt werden: [3]
Die Delegation von Subdomains ist ebenfalls möglich.
Da es sich bei der Namensauflösung für unsere Adressbereiche um Bereiche des privaten Adressraums handelt, sollten diese IP-Adressen nicht bei eigenen global auflösbaren Domains gesetzt werden. Da einige DNS Server gegen rebind Attacken aus dem globalen DNS geschützt sind, kann es vorkommen, dass die eigene globale Domain nicht auf die fd43:[..] oder 10.[..] IPs aufgelöst werden kann. Sollte dennoch gern eine globale Domain verwendet werden, dann bitte den jeweiligen Eintrag als CNAME auf einen [..].fff.community hostname setzen und die IP im Git [4] setzen.
Funktionsfähigkeit auf allen Gateways
Um sicher zu stellen, dass das DNS im ganzen Netz funktioniert, müssen alle Gateways korrekt konfiguriert sein. Dabei sollte man immer beachten, dass der DNS nicht aus dem Internet sondern nur aus dem Freifunknetz erreichbar ist. Es gibt mehrere Möglichkeiten um dies zu erreichen:
Andere DNS Server nutzen
Es muss nicht zwingend ein eigener DNS-Server betrieben werden. Es sollte aber möglichst nicht einer der großen bekannten öffentlichen (z.B. 1.1.1.1 oder 2606:4700:4700::1111) verwendet werden, sondern besser einer unserer eigenen Server. Somit braucht man sich um die Konfiguration keine Gedanken machen.
Aktuell wären das folgende:
IPv4-Adresse | IPv6-Adresse | Betreiber | Bemerkung |
---|---|---|---|
10.50.40.10 | – | Mayosemmel | |
10.50.252.0 | fd43:5602:29bd:ffff::252 | RedDog | |
10.83.252.0 | fd43:5602:29bd:ffff::42 | fblaese | |
10.83.252.11 | fd43:5602:29bd:ffff:a:a:a:a | ChristianD | Statistik: https://homeserver.dresel.it:3001/d/7_2CgErWk/bind?orgId=1&from=now-6h&to=now&refresh=1m |
10.83.252.62 | fd43:5602:29bd:ffff::62 | Adrian Schmutzler |
Anycast
Unter der Anycast Adresse antwortet immer der am besten zu erreichende Server:
IPv4-Adresse | IPv6-Adresse | Bemerkung |
---|---|---|
- | fd43:5602:29bd:ffff:1:1:1:1 | Anycast DNS |
- | fd43:5602:29bd:ffff:1:1:1:64 | Anycast DNS64 |
DoH/DoT
Im Freifunk Franken Netz werden auch DoT/DoH DNS Server betrieben. Aktuell gibt es folgende Server:
IPv4-Adresse | IPv6-Adresse | Service | Domain für Zertifikat |
---|---|---|---|
10.50.250.1 | fd43:5602:29bd:62::1 | DoT | dns.herpf.fff.community |
- | fd43:5602:29bd:62::3 | DoT DNS64 | dns64.herpf.fff.community |
eigener DNS Server als Cache mit forwarding
Es kann auch ein eigener DNS Server betrieben werden und auf einen Freifunk DNS Server gefordwardet werden.
siehe hier:
unbound als Cache mit forwarding
unbound als Cache mit forwarding auf DoT
eigener rekursiver Resolver mit Static-Stub
Wenn der Server die angefragten Domains nicht vorkonfiguriert weiterleitet, sondern den Namen selbst über die DNS Root Server auflöst, spricht man von einem rekursiven Resolver. Da aber unsere IP-Adressen nicht global aufgelöst werden können muss man die verantwortlichen Server selbst eintragen. Aktuell sind es 3 Reversezonen die eingetragen werden müssen. Optional kann man auch die Domain selbst eintragen, das beschleunigt die Namensauflösung ein bisschen.
Hierbei ist zu beachten, dass die rekursiven Anfragen (IPv4 und IPv6) immer aus dem FFF-Netz heraus kommen sollten. Ansonsten bekommt man bei Subdomains von fff.community nicht die internen IP-Adressen ausgeliefert. Da man dies in bind9 nicht direkt konfigurieren kann, muss man dies sicherstellen (metric, o.ä.) oder man muss unsere drei Reversezonen und fff.community auf einen unserer Server forwarden (nicht static-stub). Daher bietet sich hier eher unbound an.
Hinweis: Wenn ein eigener DNS-Server betrieben werden soll, sollte man unbedingt in Betracht ziehen auch die deutschlandweiten Freifunk-Zonen zu übernehmen. Wie das geht, steht hier: https://wiki.freifunk.net/DNS
siehe hier:
bind9 als rekursiver Resolver
unbound als rekursiver Resolver
eigener rekursiver Resolver als authorativer DNS
Die Grundfunktionalität ist wie beim Static-Stub, nur werden unsere eigenen Zonen hier auf dem Server selbst gespeichert. Bei dieser Konfiguration kann man auch eigene Subdomains von fff.community hosten.
siehe hier:
bind9 als authorativer DNS mit DNS64 und Split-View
Beispielhafte Installation
Die Installation könnte dann etwa so aussehen:
cd /etc/bind cat <<EOF >> named.conf.local zone "50.10.in-addr.arpa" { type static-stub; server-addresses { 10.50.40.10; 10.83.252.11; 10.50.252.0; 10.83.252.62; }; }; zone "fff.community" { type static-stub; server-addresses { 10.50.40.10; 10.83.252.11; 10.50.252.0; 10.83.252.62; }; }; EOF aptitude install python-yaml git clone https://github.com/freifunk/icvpn-scripts.git git clone https://github.com/freifunk/icvpn-meta.git echo 'include "/etc/bind/named.conf.icvpn";' >> named.conf cat <<EOF > update-icvpn.sh #!/bin/bash cd /etc/bind/icvpn-meta git pull cd .. icvpn-scripts/mkdns -x franken -f bind -s icvpn-meta > named.conf.icvpn /usr/sbin/rndc reload EOF chmod +x update-icvpn.sh # falls das sich wg. fehlendem yaml beschwert wird python3 für das script verwendet - dann python3-yaml nachinstallieren! ./update-icvpn.sh echo "10 2 * * * root /etc/bind/update-icvpn.sh" >> /etc/crontab
Der DHCP sollte natürlich auch angepasst werden:
In der dhcpd config:
- option domain-name "fff.community";
- Bitte auch keine Freifunk Fremden DNS Server verteilen, wenn kein eigener DNS betrieben werden soll, lieber einige vorhandene Freifunk DNS Server announcen.
Danach:
- /etc/init.d/isc-dhcp-server restart
Konfigurationsbeispiele
In den aufgeführten Beispielen müssen die <XXXXX> jeweils durch selbst gewählte DNS Server und/oder eine der Anycast Adressen ersetzt werden. Vorzugsweise IPv6 vorrangig und IPv4 als sekundäre.
unbound als Cache mit forwarding
server: access-control: 10.0.0.0/8 allow access-control: 127.0.0.0/8 allow access-control: 192.168.0.0/16 allow access-control: fc00::/7 allow cache-max-ttl: 14400 cache-min-ttl: 1200 hide-identity: yes hide-version: yes interface: 0.0.0.0 interface: ::0 rrset-roundrobin: yes # Enable or disable whether TCP queries are answered or issued. do-tcp: yes # Enable or disable whether the upstream queries use TCP only for # transport. Useful in tunneling scenarios. #tcp-upstream: yes # If enabled id.server and hostname.bind queries are refused. hide-identity: yes # If enabled version.server and version.bind queries are refused. hide-version: yes # If yes, Unbound doesn't insert authority/additional sections # into response messages when those sections are not required. minimal-responses: yes # If yes, message cache elements are prefetched before they expire # to keep the cache up to date. prefetch: yes # Send minimum amount of information to upstream servers to # enhance privacy. qname-minimisation: yes # Enabled or disable whether the upstream queries use SSL only for # transport. # ACHTUNG! Nur einschalten wenn als Forwarder DoT Server verwendet werden # ansonsten auskommentieren! #ssl-upstream: yes # Use 0x20-encoded random bits in the query to foil spoof # attempts. use-caps-for-id: no forward-zone: name: "." forward-addr: <XXXXX> forward-addr: <XXXXX> [optional noch mehr]
unbound als Cache mit forwarding auf DoT
folgende Parameter müssen zur Konfiguration ohne DoT geändert werden:
tcp-upstream: yes ssl-upstream: yes forward-zone: name: "." forward-addr: <XXXXX-DNS64>@853#<XXXXX-DNS64-Servername>
bind9 als rekursiver Resolver
named.conf oder named.conf.options und named.conf.local; je nach Betriebssystem
acl icvpnlocal { 10.0.0.0/8; 172.16.0.0/12; fc00::/7; }; options { directory "/tmp"; auth-nxdomain no; listen-on port 53 { any; }; listen-on-v6 port 53 { any; }; recursion yes; allow-query-cache { icvpnlocal; localhost; }; allow-recursion { icvpnlocal; localhost; }; dnssec-validation no; zone "." { type hint; file "/etc/bind/db.root"; }; zone "50.10.in-addr.arpa" { type static-stub; server-addresses { <XXXXX>; <XXXXX>; }; }; zone "83.10.in-addr.arpa" { type static-stub; server-addresses { <XXXXX>; <XXXXX>; }; }; zone "d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa" { type static-stub; server-addresses { <XXXXX>; <XXXXX>; }; }; zone "fff.community" { type static-stub; server-addresses { <XXXXX>; <XXXXX>; }; }; include "/etc/bind/icvpn-zones.conf"; // be authoritative for the localhost forward and reverse zones, and for // broadcast zones as per RFC 1912 zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127"; }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; };
unbound als rekursiver Resolver
zu beachten ist, dass man die Anfragen (IPv4 und IPv6) immer aus dem FFF-Netz heraus stellt. Ansonsten bekommt man bei Subdomains von fff.community nicht die internen IP-Adressen ausgeliefert. folgende Parameter müssen zur forwarding Konfiguration hinzugefügt/entfernt werden:
# file to read root hints from. # get one from https://www.internic.net/domain/named.cache root-hints: "/var/lib/unbound/root.hints" auto-trust-anchor-file: /var/lib/unbound/root.key do-ip4: yes do-ip6: yes prefer-ip6: yes outgoing-interface: <public Freifunk IPv6> outgoing-interface: <lokale 10er Netz IPv4> stub-zone: name: 50.10.in-addr.arpa stub-addr: <XXXXX> stub-addr: <XXXXX> stub-zone: name: 83.10.in-addr.arpa stub-addr: <XXXXX> stub-addr: <XXXXX> stub-zone: name: d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa stub-addr: <XXXXX> stub-addr: <XXXXX> stub-zone: name: fff.community stub-addr: <XXXXX> stub-addr: <XXXXX>
forward-zone: name: "." forward-addr: <XXXXX> forward-addr: <XXXXX> [optional noch mehr]
randomisierte Upstream IPv6
Um DNS spoofing zu erschweren bietet es sich an für den Upstream einen IPv6 Netzwerkblock anstelle einer einzelnen Adresse zu verwenden. Dafür muss man sich ein eigens dafür genutztes IPv6/64er Netz klicken, routing einrichten und im ifup an das lo interface hängen. Dann benutzt unbound für jede Abfrage (welche via IPv6 gemacht werden kann) eine zufällige Adresse aus diesem Netzblock.
ifup
ip -6 addr add <public IPv6 Präfix>/64 dev lo ip -6 ro add local <public IPv6 Präfix>/64 dev lo
unbound config
outgoing-interface: <public IPv6 Präfix>/64 outgoing-interface: <lokale 10er Netz IPv4>
bind9 als authorativer DNS mit DNS64 und Split-View
Hinweis: Diese Konfiguration ist WIP! Die dafür benötigten Scripte sind noch nicht reviewed.
Bei dieser Konfiguration ist der Server authorativ für die fff.community Domain und beantwortet Anfragen für diese und unsere Reversezonen direkt. Da der Server authorativ ist muss er auch Anfragen aus dem Internet beantworten. Diese Anfragen landen dann im external-view und es werden dort hin nur Anfragen für unsere Zonen gegeben und auch nur öffentlich erreichbare IPs herausgegeben.
Die hier nicht aufgeführten include Dateien werden von den Scripten erstellt.
named.conf
acl icvpnlocal { 10.0.0.0/8; 172.16.0.0/12; fc00::/7; }; include "/etc/bind/icvpn-acl.conf"; acl listenv6ifs { !fe80::/48; any; }; options { directory "/tmp"; auth-nxdomain no; listen-on port 53 { any; }; listen-on-v6 port 53 { listenv6ifs; }; recursion no; notify no; check-names master warn; minimal-responses yes; }; view "icvpn-internal-dns64-view" { match-destinations { <separate IPv6 für dns64>; <anycast-dns64>; }; dns64 64:ff9b::/96 { break-dnssec yes; }; include "/etc/bind/internal-view.conf"; }; view "icvpn-internal-view" { match-destinations { <anycast-dns>; any; }; include "/etc/bind/internal-view.conf"; }; view "external-view" { match-clients { any; }; dnssec-validation no; rate-limit { responses-per-second 20; }; include "/etc/bind/fff.community-external.conf"; };
internal-view.conf
match-clients { icvpnrange; localhost; }; recursion yes; dnssec-validation no; allow-query-cache { any; }; include "/etc/bind/fff.community-internal.conf"; zone "0.8.e.f.ip6.arpa" { type master; file "/etc/bind/db.fe80"; }; zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127"; }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; zone "." { type hint; file "/etc/bind/db.root"; };
Alternativ kann die "." Zone auch an unbound geforwarded werden. Dann kann im unbound dnssec aktiviert werden und funktioniert dann wenigstens fürs Internet.
zone "." { type forward; forward only; forwarders { ::1 port <unbound port>; }; };
um doppeltes Cachen zu unterbinden muss man in den bind9 optionen dann noch folgendes setzen:
max-cache-size 0;
Testen
Testen können wir, indem wir vom DNS Server des Gateways (localhost/127.0.0.1) eine DNS-Auflösung abfragen.
Ein DNS Resolve für freifunk-franken.de ...
dig @127.0.0.1 freifunk-franken.de
...sollte von uns selber (Server localhost; 127.0.0.1) beantwortet werden:
;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5819 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;freifunk-franken.de. IN A ;; ANSWER SECTION: freifunk-franken.de. 3599 IN A 31.172.113.113 . . . ;; Query time: 117 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Tue Sep 08 14:16:32 EEST 2015 ;; MSG SIZE rcvd: 275
Script um die Reverse DNS Zone zu erstellen
Viel Magie, liegt jetzt im Git: [5]