Wir haben eine Reihe von ASAs im Einsatz, die auf Kundenwunsch gepflegt werden. Wie immer betreffen Änderungswünsche nur die Einrichtung von Freischaltungen, aber nie das Wegräumen von Altlasten. Für diesen Fall gibt es zwei Tools, die ich vorstellen möchte.

Information des Kunden

Zunächst ist es wichtig, den Kunden regelmäßig über die aktuelle Konfiguration zu informieren. Trivialerweise würde man ihm die Konfiguration zugänglich machen.

Aber das ist eine schlechte Idee, da die ASAs einiges an Konfiguration enthalten, die man nicht ständig durch die Gegend reichen möchte. Es gibt auch genug Fälle, wo eine ASA mehrere Kunden bedient (z.B. mehrere Hosting-VLANs). Dann darf natürlich keine Information über die Konfiguration für andere Kunden leaken.

Es ist also notwendig, sich auf die wesentlichen und interessanten Teile zu beschränken. In diesem Fall interessiert den Kunden, welche ACLs und welche NAT Regeln für ihn aktiv sind. Was den Kunden interessiert, hängt von den Interfaces ab, die ihm zugeordnet sind.

Das Script mkacl-from-asaconfig.pl liest auf Standardeingabe eine komplette abgespeicherte ASA-Konfig ein, erwartet als Argument die Liste der interessanten Interfaces (nameif) und gibt aus:

  • die den Interfaces zugeordneten access-groupKommandos
  • die den access-group zugeordneten access-list Einträge
  • die den Interfaces zugeordneten nat Kommandos
  • die dabei referenzierten object-group Definitionen
  • die dabei referenzierten object Definitionen

Ganz praktisch sieht das dann so aus:

$ zcat /archiv/cf.asa.20180111.gz | mkacl-from-asaconfig.pl iks-lab
: Written by enable_15 at 11:13:55.766 CET Thu Jan 11 2018
!
!!!!!!
! active ACLs at interfaces
!!!!!
access-group to_lab out interface iks-lab
!!!!!
! ACLs
!!!!!
access-list to_lab extended permit ip object-group iks any 
access-list to_lab extended permit tcp any object obj-lab1 object-group http_s 
access-list to_lab extended permit tcp any object obj-lab2 object-group http_s 
!
!!!!!!
! extra NATs
!!!!!
!!!!!
! Object groups
!!!!!
object-group network iks
 network-object object o4-iks
 network-object object o6-iks
!
object-group service http_s tcp
 port-object eq www
 port-object eq https
!
!!!!!
! Objects
!!!!!
object network obj-lab1
 host 192.168.91.10
 nat (iks-lab,outside) static o4-lab1-public
!
object network obj-lab2
 host 192.168.91.11
 nat (iks-lab,outside) static o4-lab2-public
!
...
!
!!!!!
! Generated at Thu, 11 Jan 2018 13:35:03 +0100

Diese Auszüge können dem Kunden auf definiertem Wege (z.B. Kundenportal) zur Verfügung gestellt werden.

Es gestattet dem Kunden, sich selbst die aktuelle Konfiguration anzusehen und entlastet die Hotline bei uns.

Inkonsistenzen

Ein ganz anderer Teil des Problem sind Inkonsistenzen und Altlasten. Die Definition eines Objektes, das nicht verwendet wird, ist eine Inkonsistenz. Die Verwendung einer IP Adresse, die nicht mehr in Benutzung ist, ist eine Altlast. Beides soll gefunden werden.

Wie eine Konfiguration auszusehen hat, ist selbstverständlich Ansichtssache. Bei uns hat es sich als günstig herausgestellt, sämtliche IP Adressen in Objekten und Objektgruppen zu sammeln, damit diese schon allein anhand ihrer Benennung oder description auch noch Jahre später zugeordnet werden können. Nur mit klarer Zuordnung ist ein späterer Rückbau überhaupt möglich.

Das Script clean-asa-config.pl liest von der Standardeingabe eine komplette Konfigurationsdatei und listet auf, was unstimmig erscheint:

  • Nicht mehr benutzte access-list, object, object-group. name, tunnel-group, class-map, transform-set, crypto map, ...
  • Elemente, die verwendet werden, aber nicht definiert wurden, werden aufgelistet.
  • Es wird das Anlegen von object oder name Definitionen empfohlen, wenn IPs direkt in der Konfiguration stehen.
  • Ist bei Objekten ein DNS-Name zur IP hinterlegt, so wird geprüft, ob der Name noch zu dieser IP auflöst. Es ist nicht empfehlenswert, direkt mit fqdn statt host zu arbeiten, wenn man feststellen will, ob die intendierte Eintragung noch korrekt ist. fqdn sollte man nur bei dynamischen IPs benutzen.
  • Bei name Definitionen wird geprüft, oben IP und Name noch per DNS zusammen passen.
  • Da name Definitionen agnostisch gegenüber der Protokollfamilie sind, wird für IPv4 ein trailing dot am Namen empfohlen, bei IPv6 nicht.
  • Ausgelaufene Zertifikate führen zur Empfehlung, den trust-point zu löschen.
  • Ebenso soll man unvollständige crypto map Einträge löschen.

Die Ausgabe enthält:

  • die Empfehlung incl, Begründung
  • die direkt ausführbaren Kommandos, um die Empfehlung umzusetzen, ohne den Betrieb zu gefährden
  • alle anderen Verwendungen des Namens oder der IP in der Konfiguration

Wenn Euch etwas auffällt, was man noch testen sollte oder könnte ...

VPNs dienen der geschützten Kommunikation, entsprechend einfach sollte ihre Einrichtung sein. Unglücklicherweise ist aber schon die Festlegung, was genau schützenswert ist, Ergebnis einer komplexen Abstimmung. Deswegen werden zunehmend VPNs global aufgemacht und nur bei Bedarf genutzt. Ein striktes Gerät, wie die ASA, mag das gar nicht. Ein Endkundengerät lieb es …

IPSec klassisch

Der klassische Ansatz ist es, für jedes Paar von geschützten Netzen einen Tunnel anzulegen, der je nach Bedarf aufgebaut und abgebaut werden kann. Diese Tunnel nennt man Security Association, sie definieren sich über die IP-Adressen der beteiligten Netze.

vpn-policy

Durch die dynamischen Tunnel muss jedes beteiligte Gerät wissen, welche Paare von Netzen zu schützen sind und notfalls einen Tunnelaufbau initiieren. Es ist unzulässig, Pakete unverschlüsselt zu übertragen, wenn die Policy Verschlüsselung vorschreibt.

Man kann eine solche Policy also auch so verstehen, das es eine ACL gibt, die festlegt, welcher Datenverkehr verschlüsselt ist oder nicht. Konsequenterweise enthalten die Tunnel dann auch Protokoll und Portnummern, wenn nicht rein auf IP Ebene selektiert wird.

Umgekehrt wird die Policy-ACL auch bei eingehendem Verkehr angewendet. Was laut Policy verschlüsselt zu sein hat, muss verschlüsselt ankommen. Pakete, die am VPN vorbei eintrudeln, werden kommentarlos verworfen.

Das offenkundige Problem mit dem Ansatz ist der Koordinierungsaufwand:

  • Beide Seiten müssen sich über die exakten Policy-ACLs klar sein.
  • Änderungen sind nur beidseitig und gleichzeitig möglich.

IPSec simplified

Die offenkundige Verbesserung besteht darin, dem Tunnel nicht mehr mit den IP-Adressen zu verknüpfen. Stattdessen wird ein generischer Tunnel aufgebaut, der beliebige Datenpakete verschlüsselt transportieren kann.

Jede Seite legt für sich fest, welche Ziele durch den Tunnel und welche unverschlüsselt übertragen werden sollen.

vpn-routing

Da man die Entwicklung eines neuen Protokolls scheute, wird ein klassischer IPSec Tunnel genutzt, der jedoch maximal breit arbeitet: Beliebige Quell- und Ziel-Adressen passen in den Tunnel.

Selbstverständlich kann man nun nicht mehr mit (Policy-)ACLs arbeiten, denn dann müsste sämtlicher Datenverkehr zwangsweise in den Tunnel geschoben werden. Stattdessen verzichtet man komplett auf die ACLs und routet die Ziel-Adressen entweder in den Tunnel oder ins Internet.

Auf diese Weise können Tunnel nach Bedarf auf jeder Seite einzeln konfiguriert werden: Es gibt einen existenten Tunnel und da wirft man rein, was wichtig scheint. Die Gegenseite muss nicht mehr informiert werden.

Eine Konsequenz aus dem Verzicht auf die ACLs, ja auf den Verzicht auf Abstimmung, ist, dass das empfangende Gerät nicht mehr feststellen kann, ob das ankommende Paket verschlüsselt hätte sein sollen oder nicht. Bei Fehlkonfigurationen kann ein Teil des Traffics unverschlüsselt laufen.

vpn-routing-fail

Die Vorteile liegen auf der Hand:

  • Einfaches Setup (nur Gegenstelle und Schlüssel notwendig)
  • Verschlüsselung nach Bedarf (des Senders) beliebig erweiterbar
  • Bei Fehlkonfiguration bleibt die Funktion bestehen, nur die Sicherheit ist weg.

Mischbetrieb

Der vereinfachte Ansatz ist gerade im Endkundenbereich beliebt, weil sich der Kunde so schnell seine Lan-Kopplung zusammen klicken kann. Der striktere Ansatz ist eher im Firmenumfeld zu finden, wo man traditionell nur mit abgestimmten Konfigurationen zu tun hat.

In meinem Fall habe ich nun ein Endkundengerät (CPE), das ausschließlich nach der vereinfachten Methode arbeitet, und eine ASA, die ausschließlich nach der traditionellen Methode konfiguriert werden will.

vpn-mixed-fail

Aufgrund der Policy-ACL würde eine ASA keinen unverschlüsselten Traffic annehmen, wenn der durch den Tunnel kommen müsste. Das will ich nicht aufgeben.

An der CPE sind die Wechselmöglichkeiten zu beschränkt, um überhaupt einen anderen Typ von Verbindung hinzubekommen. Also konzentriere ich mich auf das eigentliche Problem: Den VPN Tunnel und die dazu passende Policy-ACL.

vpn-mixed

Da die CPE den Tunnel vorgibt, muss er offensichtlich ein 0.0.0.0/0.0.0.0 Tunnel werden. Das führt zur sofortigen Funktionsunfähigkeit der ASA.

Schaut man genauer auf die ACLs, so stellt man fest, dass diese mehrfach benutzt werden:

  • Jedes Paket, dass von der ACL erlaubt wird, kommt in den Tunnel oder muss daraus kommen.
  • Jedes Paket, dass von der ACL abgelehnt wird, darf nicht in den Tunnel oder daraus kommen.
  • Die Tunnel-Konfiguration ergibt sich aus den Permit-Regeln der ACL.

Der Trick besteht also darin, allen Traffic abzulehnen, der nicht in den Tunnel soll, um anschließend alles zuzulassen.

access-list vpn deny ip object-group og-not-local any 
access-list vpn deny ip any object-group og-not-remote
access-list vpn permit ip any any 

Die Objektgruppen, die den Kehrwert der eigentlich zulässigen Netze bilden, sind am einfachsten aus zwei Bereichen zu bauen, die bis an das gewünschte Netz ran gehen.

object-group network og-not-local
 network-object object o-not-local-higher
 network-object object o-not-local-lower

object network o-not-local-lower
 range 0.0.0.0 198.51.99.255
object network o-not-local-higher
 range 198.51.101.0 255.255.255.255

In gleicher Weise werden die inversen Bereiche für das Remote-Netz definiert.

Es kann nun noch vorkommen, dass die ASA sich zickig hat beim annehmen des Verbindungsaufbaus. Dann genügt es die Basisadressen der Netze zu erlauben.

access-list vpn line 1 perm ip host 0.0.0.0 host 0.0.0.0

Tut.

Eine Appliance, die in einer fremden Umgebung Daten einsammelt, soll von extern angesprochen werden. Zum einen muss der Hersteller Fernwartung machen und zum anderen gibt es eine Gruppe von Stellen, die auf die gesammelten Daten zugreifen sollen. Völlig unerwartet wird das geschützte Netzwerk dieser Stellen ebenfalls mit öffentlichen IP Adressen betrieben, so dass für beide Zwecke eine Default Route benötigt wird. Das Ganze soll trotzdem nur mit einer ASA funktionieren. Eine Aufsplittung in mehrere Kontexte (ASA-Virtualisierung) scheitert am fehlenden Support für Remote-Access. Es muss also anders gehen.

Aufgabenstellung

Die Appliance arbeitet in einem anderen, größeren Netzwerk und benutzt selbst nur private IP Adressen (hier 192.0.2.x). Um alle Messstellen erreichen zu können, zeigt die Default Route dieses Gerätes in das fremde Netzwerk (hier grau).

Der Remote-Access Teil (hier grün) ist ein einfaches Setup. Um die vorab unbekannten Clients erreichen zu können, muss die Default Route ins Internet zeigen. Dieser Uplink der ASA benutzt öffentliche IPs (PA-space, hier 189.51.100.x). Die Remote-Access Clients bekommen aus einem Adresspool des lokalen Netzes IPs, so dass sie ohne weiteres Routing auf die Appliance zugreifen können. Von Seiten der Appliance aus erscheint der Client im LAN.

Die ursprüngliche Annahme war, dass die abfragenden Stellen, die über ein extra gesichertes Netzwerk zugeführt werden, ebenfalls in koordinierter Weise mit nicht-öffentlichen Adressen arbeiten würden. In diesem Fall hätte eine spezifische Route zu all diesen Netzen genügt. Allerdings haben die Planer dieses Netzes den Koordinationsaufwand gescheut und verlangen stattdessen, öffentliche IP-Adressen aus dem lokalen PA-Space zu benutzen, der auch normal über Internet erreichbar ist.

ASA multiple default routes

Die Gegenstellen hinter dem geschützten Netzwerk (hier rot) sind vorab ebenso wenig bekannt, wie die Fernwartungs-Clients (grün). In dem hier skizzierten Bild, soll eine solche Gegenstelle eine ganz andere öffentliche IP Adresse haben (hier 203.0.113.133). Um solche Adressen zu erreichen, müsste eine Default Route ins rote Netz gesetzt werden.

Angefasst werden darf nur die ASA, alle anderen Geräte unterliegen fremder Verfügungsgewalt.

Remote-Access

Die Konfiguration für das Remote-Access VPN gemäß Lehrbuch:

interface Ethernet0/0
 nameif green
 security-level 0
 ip address 198.51.100.25 255.255.255.192
!
interface Ethernet0/1
 nameif gray
 security-level 100
 ip address 192.0.2.5 255.255.255.0
!
route green 0.0.0.0 0.0.0.0 198.51.100.1 1
!
ip local pool vpnippool 192.0.2.101-192.0.2.102 mask 255.255.255.0
!
crypto map vpn_outside 999 ipsec-isakmp dynamic vpn_dyn
crypto map vpn_outside interface green
...

Erwartungsgemäß tut das seinen Dienst:

  • Der entfernte Supportmitarbeiter kann per Default Route erreicht werden.
  • Der entfernte Supportmitarbeiter bekommt über das VPN eine IP aus dem inside-LAN.
  • Die Appliance redet mit ihm über das lokale Netzwerk. Extra Routen werden nicht benötigt.

Einmal hin ...

Um die Stellen, die mit öffentlichen IP Adressen aus dem geschützten Netz kommen, versorgen zu können, sind einige Überlegungen notwendig.

Zuerst fällt auf, dass der Verbindungsaufbau bei unbekannten Gegenstellen nur von extern kommen kann. Die Clients werden ausschließlich eine öffentliche IP au dem Netz 198.51.100.248/29 zugreifen können. Von dem privaten Netz hinter der ASA wissen sie nichts.

Damit die Appliance nichts von den fremden Adressen merkt, braucht es eine Doppel-NAT:

interface Ethernet0/2
 nameif red
 security-level 0
 ip address 198.51.100.254 255.255.255.248
!
object network o-server
 host 192.0.2.4
!
nat (red,green) source dynamic any interface destination static interface o-server

Eingehende Pakete über das rote Interface von beliebiger Quelle an die Interface-IP werden so genanntet, dass die Quell-IP zur grünen Interface-Adresse und die Zieladresse, die der Appliance wird. Damit sieht die Appliance nur Anfragen aus ihrem LAN.

Um zu testen, dass diese Idee auch tut, wird ein Testaufbau erstellt:

ASA multiple default routes Test

Anstelle des roten Netzwerkes, steht ein Linux-Rechner, den man passend konfiguriert:

# ip addr add 198.51.100.254/29 dev eth_rot
# ip addr show eth_rot
1: eth_rot: <BROADCAST,MULTICAST,UP,10000>
    inet 198.51.100.254/29 scope global eth_rot
       valid_lft forever preferred_lft forever 

Zusätzlich bekommt er die fremde IP Adresse. Damit er diese auch als Quelladresse benutzt, gibt es eine spezielle extra Route:

# ip addr add 203.0.113.133/32 dev lo
# ip route add 198.51.100.249/32 src 203.0.113.133 dev eth_rot

Wenn man testweise versucht eine Verbindung zur Appliance herzustellen, scheint es erst einmal zu tun.

# ssh 198.51.100.249
15:42:02  IP 203.0.113.133.35158 > 198.51.100.249.22: S 3034099253:3034099253(0)
15:42:03  IP 203.0.113.133.35158 > 198.51.100.249.22: S 3034099253:3034099253(0)
15:42:05  IP 203.0.113.133.35158 > 198.51.100.249.22: S 3034099253:3034099253(0)

Wie man sieht, geht die Anfrage mit der richtigen Absende-IP raus.

Allerdings kommt keine Antwort zurück. Aber warum?

... und zurück

Ein Blick auf die ASA zeigt, das die Datenpakete korrekt nattet und sogar Antworten bekommt.

 16: 15:42:02   192.0.2.5.35158 > 192.0.2.4.22: S 3034099253:3034099253(0) win 14600
 17: 15:42:02   192.0.2.4.22 > 192.0.2.5.35158: S 2009198346:2009198346(0) ack 3034099253 win 14480
 18: 15:42:03   192.0.2.5.35158 > 192.0.2.4.22: S 3034099253:3034099253(0) win 14600
 19: 15:42:03   192.0.2.4.22 > 192.0.2.5.35158: S 2009198346:2009198346(0) ack 3034099253 win 14480
 20: 15:42:05   192.0.2.5.35158 > 192.0.2.4.22: S 3034099253:3034099253(0) win 14600
 21: 15:42:05   192.0.2.4.22 > 192.0.2.5.35158: S 2009198346:2009198346(0) ack 3034099253 win 14480

Warum kommen die Datenpakete nicht wieder zurück? Weil die Default Route fehlt!

Glücklicherweise ist die ASA kein Router. Genauer gesagt die Routingentscheidung wird in zwei Schritten vorgenommen:

  • Steht das ausgehende Interface nicht fest, so wird die generische Routingtabelle befragt, um das Interface zu ermitteln.
  • Ist allerdings klar, auf welchem Bein ausgesendet werden muss, so wird nur der Teil der Routingtabelle betrachtet, der diesem Interface zugeordnet ist.

Eine der Konsequenzen aus diesem Ansatz erklärt die seltsame Anforderung, bei jeder statische konfigurierten Route immer das Interface mit angeben zu müssen: Um so eine schräge Logik umsetzen zu können, muss man erst mal die Angaben dafür haben.

In diesem Fall genügt es also eine weitere Default Route einzutragen, die eine höhere Metrik hat. Dies stellt sicher, dass die ASA keine zwei gleichberechtigten Routen erhält, mit denen sie nicht umgehen kann. Die Situation für die ASA bleibt also eindeutig.

(conf)# route red 0.0.0.0 0.0.0.0 198.51.100.254 2

An der Standard-Routingtabelle ändert sich damit ja nichts:

C    198.51.100.248 255.255.255.248 is directly connected, red
C    198.51.100.0 255.255.255.192 is directly connected, green
C    192.0.2.0 255.255.255.0 is directly connected, gray
S*   0.0.0.0 0.0.0.0 [1/0] via 198.51.100.1, green

Ganz anders ist nun aber die Situation für die Pakete dar, die aus dem (reverse)-NAT heraus fallen.

  • Der NAT Eintrag enthält die Quell- und Ziel-Interfaces, sowie die IP-Adressen und Ports.
  • Pakete bestehender Flows werden also nicht normal behandelt, sondern anhand des vorhandenen NAT-Eintrags.
  • Damit umgehen sie sämtliches konfiguriertes Routing, ACLs etc. insbesondere die Standard-Routingtabelle.
  • Da das Zielinterface fest steht, greift nur noch die Routingtabelle dieses Interfaces, also die niedrig priorisierte Default Route.

Und siehe an:

# ssh  198.51.100.249 
16:38:20  IP 203.0.113.133.51310 > 198.51.100.249.22: S 3979383937:3979383937(0)
16:38:20  IP 198.51.100.249.22 > 203.0.113.133.51310: S 3186400021:3186400021(0) ack 3979383938
16:38:20  IP 203.0.113.133.51310 > 198.51.100.249.22: . ack 1 win 115
16:38:20  IP 198.51.100.249.22 > 203.0.113.133.51310: P 1:22(21) ack 1 win 114
16:38:20  IP 203.0.113.133.51310 > 198.51.100.249.22: . ack 22 win 115
16:38:20  IP 203.0.113.133.51310 > 198.51.100.249.22: P 1:21(20) ack 22 win 115
16:38:20  IP 198.51.100.249.22 > 203.0.113.133.51310: . ack 21 win 114
 136: 16:38:20    192.0.2.5.51310 > 192.0.2.4.22: S 1381971035:1381971035(0) win 14600
 137: 16:38:20    arp who-has 192.0.2.5 tell 192.0.2.4 
 138: 16:38:20    arp reply 192.0.2.5 is-at e8:b7:48:fd:89:81 
 139: 16:38:20    192.0.2.4.22 > 192.0.2.5.51310: S 2009198346:2009198346(0) ack 1381971036 win 14480
 140: 16:38:20    192.0.2.5.51310 > 192.0.2.4.22: . ack 2009198347 win 115
 141: 16:38:20    192.0.2.4.22 > 192.0.2.5.51310: P 2009198347:2009198368(21) ack 1381971036 win 114
 142: 16:38:20    192.0.2.5.51310 > 192.0.2.4.22: . ack 2009198368 win 115
 143: 16:38:20    192.0.2.5.51310 > 192.0.2.4.22: P 1381971036:1381971056(20) ack 2009198368 win 115
 144: 16:38:20    192.0.2.4.22 > 192.0.2.5.51310: . ack 1381971056 win 114
 145: 16:38:20    192.0.2.5.51310 > 192.0.2.4.22: P 1381971056:1381971848(792) ack
 146: 16:38:20    192.0.2.4.22 > 192.0.2.5.51310: . ack 1381971848 win 126

Hurra!

Nachdem Google mit dem Public-DNS Dienst unter 8.8.8.8 zum Standard in allen Fragen der DNS-Problembehebung geworden ist, springen nun immer mehr Firmen auf. Aktuell treibt 9.9.9.9 die Sau durch Dorf. Dabei generiert diese Idee massive Probleme, wettbewerbsrechtlich und technisch.

Wettbewerb

Zunächst gibt es eine massive Beschränkung von leicht merkbaren IP-Adressen. Der IPv4 Adressraum läßt nur 220 Adressen der Form x.x.x.x zu.

Davon benutzen schon einige die IPs für DNS Dienste:

  • 8.8.8.8 PTR google-public-dns-a.google.com.
  • 9.9.9.9 PTR dns.quad9.net.
  • 75.75.75.75 PTR cdns01.comcast.net.
  • 79.79.79.79 PTR public-dns-a.as9105.net.
  • 99.99.99.99 PTR dnsr4.sbcglobal.net.
  • 108.108.108.108 PTR 108-108-108-108.pools.spcsdns.net.
  • 114.114.114.114 PTR public1.114dns.com.

Einige benutzen die IPs für ihre eigenen Nameserver:

  • 77.77.77.77 PTR ns3.hiweb.ir.
  • 93.93.93.93 PTR ns.ngenix.net.
  • 199.199.199.199 PTR NS1.Shane.co.
  • 208.208.208.208 PTR ns1648.ztomy.com.

Andere haben eigene Ideen:

  • 16.16.16.16 PTR ldtools.gre.hp.com.
  • 23.23.23.23 PTR select.zone.
  • 76.76.76.76 PTR lo0-rtc-svw.nco.riseb.net.
  • 145.145.145.145 PTR Multicast-RendezvousPoint.surf.net.
  • 192.192.192.192 PTR medmgmt-192.tajen.edu.tw.

Der Rest macht sich gar keine Gedanken und gibt die IPs an Kunden raus. 69 davon haben einen entsprechenden Reverse-DNS Eintrag.

Nehmen wir einfach mal an, es liese sich mit diesen Adressen ein DNS-Geschäft machen. Dann kommt die Frage auf, ob diese extrem knappe Ressource gerecht verteilt ist und zukünftige Marktteilnehmer mit ihren innovativen Idee auch die Chance auf Teilnahme bekommen können.

Die Antwort der zuständigen (nationalen) Wettbewerbsbehörde liegt auf der Hand: Natürlich nicht.

Damit bedürfen diese Adressen der Regulierung bzw. der Versteigerung wie bei Funkfrequenzen.

Eigenbedarf

Die offenkundigste Schlussfolgerung des Theaters um 9.9.9.9 ist, selbst weiter zu machen. Ich habe kurzerhand die IP 10.10.10.10 als DNS-Anycast konfiguriert und in Betrieb genommen.

$ dig AAAA lutz.donnerhacke.de @10.10.10.10 +dnssec +multiline
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 727
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 3, ADDITIONAL: 1

;; ANSWER SECTION:
lutz.donnerhacke.de.    CNAME   pro.donnerhacke.de.
lutz.donnerhacke.de.    RRSIG   CNAME 5 3 57600 ...
pro.donnerhacke.de.     AAAA    2001:4bd8:1:1:209:6bff:fe49:79ea
pro.donnerhacke.de.     RRSIG   AAAA 5 3 57600 ...

;; AUTHORITY SECTION:
donnerhacke.de.         NS      avalon.iks-jena.de.
donnerhacke.de.         NS      broceliande.iks-jena.de.
donnerhacke.de.         RRSIG   NS 5 2 57600 ...

;; Query time: 11 msec
;; SERVER: 10.10.10.10#53(10.10.10.10)
;; WHEN: Fri Nov 17 21:04:34 CET 2017
;; MSG SIZE  rcvd: 672

Die Antwort kommt mit dem AD-Flag, das eine erfolgreich mit DNSSEC validierte Auskunft bekundet. Damit ist schon mal Sicherheit abgehakt.

Da 10.0.0.0/8 ein privater IP-Bereich ist, der nicht öffentlich erreicht werden kann, ist ausgeschlossen, dass der Kunde einen Nameserver irgendwo im Internet befragt. Stattdessen befragt er einen nächstgelegenen Server im Zuständigkeitsbereich seines ISP. Er hat damit die Gewährleistung, dass niemand die IP per Routingtricks im Internet entführt hat. In Konsequenz hat er damit sichergestellt ausschließlich mit seinem Vertragspartner zu kommunizieren und diesen haftbar machen zu können.

Die Verwendung eines lokalen Servers gestattet dem DNS Betreiber, auf die Weitergabe von Kundeninformationen zu verzichten. Ein angenehmer Nebeneffekt davon ist, dass alle Antworten für alle Anfragenden passen und somit effektiv gecached werden können. Zusammen mit der kurzen Laufzeit zwischen Server und Kunde kann so eine DNS Anfrage deutlich schneller beantwortet werden.

Da auf diese Weise die lokal günstig erreichbaren CDNs bevorzugt werden, wir das Surferlebnis insgesamt fluffiger. Regionale Datenquellen entlasten auch die Außenleitungen des ISP und erlauben so auch anderen Nutzern ein besseres Internet.

Was noch zu tun ist, ist der Hotline beizubringen, bei DNS Problemen nicht mehr auf die 8.8.8.8 zu verweisen, sondern stattdessen die 10.10.10.10 zu empfehlen. Das wird Zeit brauchen. Ebenso wird es dauern, bis die Techniker vor Ort nicht beim ersten Problem die DNS Einstellungen verändern, und wenn, dann auch die 10.10.10.10.

Es ist abzusehen, dass Kunden die 10er IPs auch intern verwenden. Für diese Kunden wird es dann die 100.100.100.100 geben. Ich bin ja nicht so.

Und wenn Du kein Kunde von uns bist? Dann tritt Deinen ISP, dass er auch einen solchen Service aufbaut! Es wäre Best Current Practice, diese IPs überall mit den o.g. Garantien erreichen zu können.

Das FreeBSD Handbuch für Portierungen ist eigentlich ziemlich klar. Allerdings funktionieren die Aktionen nur als root. Entwickeln mit solchen Rechnten mag ich nicht. Im IRC und den Mailinglisten heißt es, das sei halt so. Man könne ja mit pourdriere testen. Allerdings benötigt das ebenfalls root-Rechte.

Folgt man dem Handbuch, so ist das alles sehr einfach: Directory anlegen, Makefile schreiben und pkg-descr ausfüllen.

Der nächste Schritt ist das Herunterladen der Quellen. Schon da hatte ich erste Probleme, denn eigentlich wollte ich die Software nicht nochmal separat veröffentlichen. Aber die Idee des Ports ist halt, dass es um die Einbindung von Fremdsoftware geht. Und die liegt halt an anderer Stelle. Also lege ich eine extra Veröffentlichung an.

Damit der Port weiß, dass er die richtigen Dateien läd, werden Prüfsummen erstellt.

$ make makesum
=> parpd-1.1.tgz doesn't seem to exist in /usr/ports/distfiles/.
=> /usr/ports/distfiles/ is not writable by you; cannot fetch.
*** Error code 1

Logisch. Ich bin ja nicht root auf dem System. Und in das Standardverzeichnis darf ich nicht schreiben. Was nun?

In /usr/ports/Mk/bsd.port.mk steht:

# DISTDIR               - Where to search for and store copies of original sources
#                                 Default: ${PORTSDIR}/distfiles

Das kann ich ja umstellen, vielleicht geht's dann?

$ export DISTDIR=/tmp/myport
$ make makesum
=> parpd-1.1.tgz doesn't seem to exist in /tmp/myport/.
=> Attempting to fetch ftp://ftp.iks-jena.de/pub/mitarb/lutz/parpd/parpd-1.1.tgz
parpd-1.1.tgz                                 100% of   16 kB   10 MBps 00m00s
$ cat distinfo
TIMESTAMP = 1510327772
SHA256 (parpd-1.1.tgz) = 95318905767c1123eab87efa4fa664a57e5ed8f697802c6b7d5d0799ad8ea6e6
SIZE (parpd-1.1.tgz) = 17197

Na also! Geht doch.

Alle weiteren Schritte funktionieren dann als Nutzer ohne weitere Probleme.

Nunja, ein Problem gibt es doch noch. Hat man nämlich DEVELOPER=yes in dem make Optionen gesetzt, so erscheint bei jeden Aufruf von make

/!\ parpd-1.1: Makefile warnings, please consider fixing /!\

Not validating first entry in CATEGORIES due to being outside of PORTSDIR.
Please ensure this is proper when committing.

Ist ja auch klar. Natürlich bin ich als normaler Nutzer nicht im originalen PORTSDIR tätig. Die Meldung kann man getrost ignorieren.

Kaputtes xDSL ist ein nervendes Problem hier. Wir haben die Schmerzen gemildert, indem wir die Netzmasken verkleinerten. Während der letzten Monate verschärfte sish die Situation wieder, weil rigide Filter auf den DSLAM ausgerollt wurden und Geräte hinzu kamen, die nicht in der Lage waren mit den kleinen Netzmasken umzugehen. Wir hatten das Problem grundsätzlich zu lösen.

Problem

Große Netzwerke haben eine große Anzahl an sichtbaren MAC Adressen. Einige Geräte (z.B. DSLAMs) verhalten sich seltsam, wenn sie zuviele MACs zu sehen bekommen. Deshalb versuchen die Netzwerkbetreiber ihre Netze zu segmentieren, so dass keine Frames mehr von einer entfernten, kleinen Lokation zu eienr anderen gelangen können. Die Blockade von Quertraffic zuwischen Kunden heißt split-horizon. Kunden in verschiedenen Teilen des Netzwerkes können dabei nicht mehr miteinander kommunizieren.

local proxy arp1

Große Netzwerke sind schwer zu betreiben. Deswegen wird möglichst nahe am Endkunden, also am DSLAM gefiltert. Diese "Fist-Hop-Security" Filter sind nur für einfache Anwendungsfälle gedacht und neigen dazu Pakete in nicht-standard-Situationen zu verwerfen. Man kann dann diese Filter nur abschalten oder damit leben.

Meistens lesen diese Geräte die DHCP-Kommunikation mit und passen danach ihre Filter an. Nutzer mit statischen IP Adressen machen aber oft gar kein DHCP, so dass diese Filter nicht zu lernen haben. Andere Nutzer haben mehr als ein Endgerät oder ganze Netzbereiche zugeteilt bekommen. In all dieses Fällen versagen die DLSAM-Filter.

Eine weitere Sicherheitsmaßnahme besteht darin, den Broadcast-Verkehr zu unterbinden, so er nicht dazu dient, die MAC Adresse zur dem Filter bekannten IP zu ermitteln. Die Idee hinter diesem Filter ist, dass jeder, der die MAC Adresse des Endgeräts kennt, dann automatisch berechtigt ist, mit diesem zu kommunizieren. Es genügt also, die Broadcasts von Endkunden zu Endkunden zu blockieren, um effektiv nur noch erlaubte Kommunikation zu haben.

Setzt man DHCP-Sniffing, Broadcast-Filter und Split-Horizon zusammen ein, erhält man ein typisches xDSL-Netzwerk, in dem die Nutzer nur mit dem zentralen Router reden können. Sämtliche darüber hinaus gehende Kommunikation ist nicht möglich.

Einfache Lösung

Gibt es nur einen einzelnen Router im Netz, so genügt es dort local-proxy-arp anzuschalten: Jede ARP-Anfrage (eines Endgeräts) wird vom Router mit der MAC-Adresse des Router-Interfaces beantwortet. Auf diese Weise können die Kunden im Umweg über den Router miteinander reden (hair pinning).

local proxy arp3

Da der Router die MAC-Adresse des Endgeräts schon bei der ARP-Anfrage dieses Geräts nach seinem Default-Router lernt, muss der Router oft gar nicht selbst ARP-Anfragen per Broadcast stellen. Einige Routermodelle erneuern die auslaufenden Cache Einträge per Unicast-Anfrage, die von den DSLAM-Filtern durchgelassen werden. Auf diese Weise kann man ein solches Netz ohne merkbare Störungen betreiben.

Gibt es allerdings mehrere Router oder Server an zentraler Stelle,. so wird es kompliziert. Local-proxy-arp kann nun nicht mehr eingesetzt werden, da die Router sonst sich gegenseitig die ARP-Anfragen beantworteten und anschließend die Pakete im Kreis laufen.

Andererseits bekommen DHCP-Server Probleme, weil sie auf den ARP-Test "Ist die IP noch frei?" Fake-Antworten vom Router bekommen. Local-proxy-arp stört alle Arten dieser Anwendungen erheblich.

Anderer Ansatz

Um unser Netz hier trotzdem am Laufen zu halten, stellt eine neue Software (parpd) die notwendigen ARP-Antworten. In Abhängigkeit von frei konfigurierbaren Regeln antwortet der Daemon auf ARP-Anfragen mit einer passenden Antwort. Dies kann die reale MAC des Endgeräts sein oder auch die MAC-Adresse eines Routers (redirect).

Die Software lernt durch passives Zuhören die realen MAC-IP Paare. Selbstverständlich ignoriert sie dabei Antworten von anderen Instanzen, beschränkt sich also auf die originalen Quellen. parpd erneuert auslaufende ARP Cache-Einträge mit Unicast-Anfragen. Nur um die Redirect-MAC zu ermitteln, darf sie auf Broadcast zurück greifen.

Antworten können aber auch verzögert werden, d.h. die ersten Anfragen eines Gerätes nach einer bestimmten IP werden innerhalb einer gewissen Zeit ignoriert. Auf diese Weise kann ein DHCP-Server seine Überprüfungen vornehmen, bekommt aber dann doch eine Antwort, wenn er auf direkter Kommunikation besteht.

Die frei konfigurierbaren Regeln gestatten die Anpassung an komplexere Aufbauten, z.B. überlappenden Netzen.

Beispiel

Wie sieht das in der Praxis aus? So:

cache
 timeout       302     # seconds
 tablesize     3499    # expecting about 10000 entries
 refresh       3*5     # 3 retries a 5 seconds each
 delay         4*3     # respond at 4th retry in 3 seconds
end

interface em0
 timeout       1.011
 # do not respond for queries to our own infrastructure
 rule          0.0.0.0/0        198.51.100.0/29    ignore
 # delay queries from the DHCP server
 rule          198.51.100.4/32  198.51.100.0/24    delay tell
 # help the routers/servers to reach the clients
 rule          198.51.100.0/29  198.51.100.0/24    tell
 # interclient communication through hairpinning at the default gateway
 rule          198.51.100.0/24  198.51.100.0/24    198.51.100.1
 # help erroneous clients arping for everything
 rule          198.51.100.0/24  0.0.0.0/0          verbose 198.51.100.1
 # multihomed server with weak host model
 rule          192.0.2.0/24     198.51.100.0/24    tell
 # show missing entries
 rule          0.0.0.0/0        0.0.0.0/0          verbose ignore
end

Seit Wochen nervt eine bestimmte Kiste mit Bind, dass die Hints für den Startup von der Realität abweicht. Und erstaunlicherweise hat sie recht.

Das Problem

Oct  2 17:07:27 named[1117]: checkhints: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints
Oct  2 17:07:39 named[1117]: checkhints: b.root-servers.net/AAAA (2001:500:84::b) missing from hints
Oct  2 17:07:39 named[1117]: checkhints: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints
Oct  2 17:08:17 named[1117]: checkhints: b.root-servers.net/AAAA (2001:500:84::b) missing from hints
Oct  2 17:08:17 named[1117]: checkhints: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints

Ich kann den Cache löschen, aber das Problem kommt einige Tage später wieder.

Auch die originale Quelle der Hint-Files bestätigt, dass ich nichts falsch konfiguriert habe.

Der Fehler

Wie immer bei DNS-Problemen schaut man bei DNSviz nach.

b.root-servers.net-2017-10-02-15_17_03-UTC

Alles OK? Nein, da ist doch ein kleines Warndreieck!

2017-10-02-172109_238x422_scrot

Das ist exakt die Beschreibung meines Problems: Es gibt im Internet noch Einträge, die die alte, fehlerhafte IP enthalten.

Die Ankündigung passt auch prima zu dem ersten Auftreten des Problems:

As previously announced, B-Root’s IPv6 addresswas renumbered
to 2001:500:200::b, effective 2017-06-01.
(Or IPv6 address previously was 2001:500:84::b; we will continue to
operate service onthe old address for at least 6 months.)

Problem solved?

Die Lösung

Natürlich ist das Problem nicht gelöst. Es muss jemand benachrichtigt werden, der das Problem fixed. Aber wer?

$ dig ns net +short | while read a; do
   echo -n "$a ";
   dig +nottl +nocl aaaa b.root-servers.net @$a |
     egrep -i '^b.root-servers.net.*AAAA';
 done | sort

a.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
b.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
c.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
d.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
e.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
f.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
g.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
h.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
i.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
j.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
k.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
l.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b
m.gtld-servers.net. b.root-servers.net. AAAA    2001:500:84::b

Also alle. Die gesamte Delegation von NET ist kaputt.

Verantwortlich für .net ist Versign. Und die verweisen für die Delegierung auf Verisign (im Auftrag IANA). (Ja, das hatte ich anfangs falsch.)

Domain Name: ROOT-SERVERS.NET
Registry Domain ID: 2751247_DOMAIN_NET-VRSN
Registrar WHOIS Server: whois.networksolutions.com
Registrar URL: http://www.networksolutions.com
Updated Date: 2017-03-05T17:07:51Z
Creation Date: 1995-07-04T04:00:00Z
Registrar Registration Expiration Date: 2020-07-03T04:00:00Z
Registrar: NETWORK SOLUTIONS, LLC.
Registrar IANA ID: 2
Registrar Abuse Contact Email: abuse@web.com
Registrar Abuse Contact Phone: +1.8003337680
Reseller: 
Domain Status: 
Registry Registrant ID: 
Registrant Name: VERISIGN INC.
Registrant Organization: VERISIGN INC.
Registrant Street: 12061 BLUEMONT WAY
Registrant City: RESTON
Registrant State/Province: VA
Registrant Postal Code: 20190-5684
Registrant Country: US
Registrant Phone: +1.7039481212
Registrant Phone Ext: 
Registrant Fax: +1.7039483670
Registrant Fax Ext: 
Registrant Email: noc@verisign.com
Registry Admin ID: 
Admin Name: IANA Root Management, ICANN
Admin Organization: ICANN
Admin Street: 12025 Waterfront Drive #300
Admin City: Los Angeles
Admin State/Province: CA
Admin Postal Code: 90094
Admin Country: US
Admin Phone: +1.13103015800
Admin Phone Ext: 
Admin Fax: +1.13108238649
Admin Fax Ext: 
Admin Email: kim.davies@icann.org

Also schreibe ich die beide mal an.

Beim Erstellen eines Programms, das Daten aus einem Puffer kratzt, stolperte ich über einen sehr seltsamen Fehler in C. Es kostet mich ernstlich Mühe, das Problem auch nur zu verstehen.

Das Programm

Zuerst habe ich das Problem eingedampft auf ein minimales Beispiel:

#include <stdio.h>

int main(void) {
   int len, step;
   char data[5];

   for(len = 27; sizeof(data) < len; len -= step) {
      step = sizeof(data) + 2; 
      printf("len = %3d, taking %d away.\n", len, step);
   }
}

Was tut das Programm?

  • Es gibt einen Puffer mit einer initialen Länge von 27 Byte.
  • Passt die Struktur nicht mehr in den Restpuffer, brich ab.
  • Solange die gesuchte Struktur aber noch rein passt, verarbeite sie (fehlt im Beispiel).
  • Nach der Verarbeitung verkleinere die Rest-Datenmenge um die verarbeitete Struktur plus ein passendes Alignment (hier fest 2).

Der benutzte Puffer, das Verschieben des Arbeitszeigers und die eigentliche Datenverarbeitung sind in dem Beispiel entfallen.

Überraschung

Und hier die Ausgabe:

len =  27, taking 7 away.
len =  20, taking 7 away.
len =  13, taking 7 away.
len =   6, taking 7 away.
len =  -1, taking 7 away.
len =  -8, taking 7 away.
len = -15, taking 7 away.
len = -22, taking 7 away.
len = -29, taking 7 away.
len = -36, taking 7 away.

Wow! Warum beendet sich das Programm denn nicht?

Die Größe der Struktur ist "5". Das ist ganz bestimmt nicht kleiner als "-1", oder etwa doch?

Ganz offensichtlich ist der Vergleich "5" ist kleiner als  "-1" wahr, aber warum?

Evtl. hab' ich ja irgendwelche Warnungen des Compilers übersehen?

$ cc -O2 -Wall -o t t.c
[ ... nichts ... ]
$ cc --version
FreeBSD clang version 3.9.1 (tags/RELEASE_391/final 289601) (based on LLVM 3.9.1)
Target: x86_64-unknown-freebsd11.0
Thread model: posix
InstalledDir: /usr/bin

Nein, auch nicht.

Erklärung

Wenn der C-Compiler den Wert des "signed int" mit dem Namen "len" in einen "unsigned int" verwandeln würde, dann wäre das Ergebnis erklärt. Der Vergleichwert wäre dann also bei mehr als 4 Mrd., also deutlich größer als die Länge der Struktur.

Aber warum sollt der Compiler eine solche Umwandlung durchführen?

Es bleibt nur ein Blick in die Norm:

  • In 6.5.8 "Relational operators" heißt es: If both of the operands have arithmetic type, the usual arithmetic conversions are performed.
  • In 6.3.1.8 "Usual arithmetic conversions" heißt es: If the operand that has unsigned integer type has  rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with  unsigned integer type.
  • In 6.3.1.1 "Boolean, characters, and integers" heißt es: The rank of any unsigned integer type  shall equal the rank of the corresponding signed integer type.

Für den Vergleich zwischen zwei normalen Integer-Typen – der eine mit, der andere ohne Vorzeichen – gilt also, dass beide Operatoren nach unsigned konvertiert werden: In diesem Fall also von -1 auf 4 Mrd.

Voraussetzung für diese Interpretation ist allerdings, dass der sizeof-Operator einen vorzeichenlosen Integer-Typ liefert. Also wieder die Norm lesen:

  • In 6.5.3.4 "The sizeof operator" heißt es: The result is an integer constant. Huch? Keine Aussage zu Vorzeichen?
  • Etwas später liest man: The value of the result is implementation-defined, and its type (an unsigned integer type) is size_t.

Man müsste also das Spiel gewinnen, wenn man die Variable "len" einen größeren Rank verpasst. Leider klappt das weder mit "long" noch mit "long long".

Erst eine beherzter Cast des sizeof-Operators nach "int" löst das Problem:

#include <stdio.h>

int main(void) {
   int len, step;
   char data[5];
   
   for(len = 27; (int)sizeof(data) < len; len -= step) {
      step = sizeof(data) + 2; 
      printf("len = %3d, taking %d away.\n", len, step);
   }
}

Und das ergibt:

len =  27, taking 7 away.
len =  20, taking 7 away.
len =  13, taking 7 away.
len =   6, taking 7 away.

Ende der Geschichte.

Wer mag, kann mal herausbekommen, ob der Umgang des Compilers im Falle von "long" und "long long" standardkonform ist. Ich habe da meine Zweifel.

Heute Nachmittag zeigte eine Kundenmaschine einen spontanen Anstieg der Auslastung. Auf den ersten Blick sah es so aus, dass einfach viel los war, Es gab so viele Anfragen auf die Webseite, dass die Limits erreicht wurden. Diese Grenzen verhindern, dass die Maschine unbenutzbar langsam wird. Dann meldete sich der Kunde und erklärte die Hintergründe.

Lastanstieg

httpd-anfragen

Ein wunderbarer Anstieg an Anfragen zu einem bestimmten Zeitpunkt. Es klingt dann exponentiell ab.

httpd-prozesse

Und er reißt das Limit der kleinen Maschine.

Mehr Prozesse zu starten, würde nur die Bearbeitung der anderen Prozesse noch weiter verlangsamen. Der dadurch entstehende Rückstau aus Datenbank, Platte etc. verschlimmert das Problem nur.

Wenn die Kiste voll beschäftigt ist, nimmt sie keine weiteren Anfragen an. Also meldet sich der Kunde.

Erklärung

Die Webseite sei jetzt genau ganz wichtig, weil man doch einen Projekttag machen würde. Und dazu habe man an sehr viele Schulen in den letzten Wochen Informationen gegeben. Da die Plätze pro Veranstaltung beschränkt sind, habe man sich eine zentrale Anmeldung eingerichtet.

Die Anmeldewebseite sieht so aus:

2017-09-14-190938_777x202_scrot

Wir hatten also eine Menge Schüler, die in einer Menge Schulen darauf warteten, zu einem festen Zeitpunkt auf eine Webseite zu klicken, deren Inhalt aus einer Datenbank generiert wird und dabei komplett fair ACID-Prinzipen ausführen will.

Kurz: Der Kunde hat einen distributed Denial of Service Angriff bestellt und bekommen.

Ich hatte heute ein längeres Gespräch mit einer Journalistin, die fragen zur DDR-Top-level-domain ".dd" hatte. Das Gespräch war lang. Allerdings stellte sich schnell heraus, dass sie zu jung ist, um sich die Realität von vor 30 Jahren vorstellen zu können.

Probleme beim Telefonat

Zuerst kam es zu einem Verständnisproblem der gesellschaftlichen Situation. Sie konnte sich nicht vorstellen, dass man nicht einfach mal in den USA bei Jon Postel anruft, um eine Länderdomain zu registrieren.

Insbesondere gelang es mir nicht, ihr begreiflich zu machen, welche politische Dimension diese Anfrage hat. Ein Mitarbeiter an einer Universität kann nicht im Namen des gesamten Landes sprechen und handeln.

Wesentlich schwerwiegender waren allerdings die inzwischen eingefahrenen Gedankenwege der "Digital Natives". Sie können es sich schlicht nicht vorstellen, ohne Internet und Smartphone zu agieren.

Eine der Fragen war, ob ich ein spontanes Foto hätte, wie ich in der Uni an einem Rechner (es war damals PC-10) sitze. Ganz abgesehen davon, ob diese Aufnahme auf Papier/Film vorliegen könnte, zeigt es das Selbstverständnis eines "Ich dokumentiere mein Leben mit Selfies"-Typs.

Erklärungen im Nachgang

Kurz danach kam eine Liste von Fragen, die es wert sind, halbwegs ernsthaft beantwortet zu werden. Es sind Fragen, die aus der Sicht meiner Kinder gestellt werden könnten. Deswegen veröffentliche ich hier meine Antworten.

Andererseits kann man schon die Frage stellen, ob nicht jemand, der das beruflich macht, mehr vom Telefonat hätte mitnehmen können. Vielleicht sind die Fragen aber auch nur zur Einholung von Zitaten erneut gestellt und pointiert überhöht. Möglicherweise habe ich auch nicht sauber genug erklärt.

Gab es in der DDR bei diesen „internetähnlichen“ Kommunikation auch Dienste, die mit heutiger „GOOGLE“ Suchmaschine zu vergleichen sind? Wenn ja, erklären Sie mir wie und wer dieses Verfahren genutzt hat.

Ja, es gab (und gibt) an den Bibliotheken der Städte, Universitäten und Firmen die Möglichkeit der Katalogrecherche (https://de.wikipedia.org/wiki/Bibliothekskatalog). War die gewünschte Information nicht lokal in der Bibliothek vorrätig, so bediente man sich der Fernleihe (https://de.wikipedia.org/wiki/Fernleihe).

Benennen Sie die drei wichtigsten Gründe, warum die DDR nicht ins World Wide Web gestartet ist und erklären Sie warum.

Der allerwichtigste Grund warum die DDR nicht ins WWW gestartet ist, ist die historische Kausalität. Die DDR ist untergegangen (1990 siehe https://de.wikipedia.org/wiki/Wende_und_friedliche_Revolution_in_der_DDR), bevor das WWW erfunden wurde (1991 siehe https://de.wikipedia.org/wiki/World_Wide_Web). Lediglich die rechtzeitige Erfindung einer Zeitmaschine (https://de.wikipedia.org/wiki/Zeitmaschine) hätte der DDR das WWW bringen können. Dazu ist es aber bis jetzt nicht gekommen.
Der zweite Grund ist, dass für den Betrieb eines Servers (https://de.wikipedia.org/wiki/Server) am Internet eine Standleitung (https://de.wikipedia.org/wiki/Standleitung) benötigt wird, die zu einem anderen Knoten des Internets reicht. Zu dem damaligen Zeitpunkt waren Leitungen (insbesondere Weitverkehrsleitungen) ein sehr rares Gut. Das dauerhafte Belegen einer Telefonwählleitung wurde (und wird) als Fehler behandelt und die Verbindung amtsseitig getrennt. Eine grenzüberschreitende Leitung ins NSW (https://de.wikipedia.org/wiki/Nichtsozialistisches_Wirtschaftsgebiet) stellte eine unüberwindliche politische Hürde da.
Der dritte Grund ist, dass zu dem Zeitpunkt das Internet (https://de.wikipedia.org/wiki/Internet#Ab_1989_Kommerzialisierung_und_das_WWW) als nicht relevant eingestuft wurde. Stattdessen beschäftigten sich die an Netzwerken interessierten Personen mit OSI (https://de.wikipedia.org/wiki/OSI-Modell), i.d.R. also mit X.25 Netzwerken (https://de.wikipedia.org/wiki/X.25). Wer sich mit Internet beschäftigte, war ein akademischer Außenseiter.
Bonus-Info: Zu den ersten deutschen Webseiten *nach der Wende* gehört das Sekteninformationssystem Religio (http://www.religio.de/) aus Thüringen, dass ab 1992 startete.

Beschreiben Sie mir wie sich das  „Surfen“ in Alltag der DDR gestaltete? Was hat man dafür gebraucht und wie funktionierte es. (Sie haben bereits erwähnt, es gab Bastler, die diese Technik zuhause ausgetestet haben).

Da das "Surfen" in der angefragten Zeit noch gar nicht möglich war (mangels WWW), benutzte man andere Formen der elektronischen Kommunikation. Die einzige nennenswerte Verbreitung hatten die Mailbox-Netze (https://de.wikipedia.org/wiki/Mailbox_(Computer)) die nur kurze Telefonverbindungen benötigten. Der Betreiber einer Mailbox musste den Familien-Telefonanschluss (wenn der überhaupt vorhanden war) zweckentfremden. Es war also während der Kommunikation eines Mailboxnutzers oder der Mailbox selbst nicht möglich, das Telefon zu benutzen. Auch musste die Familie lernen, mit dem kurzen Anklingeln durch andere Rechner klar zu kommen. So durfte man nicht sofort ans Telefon gehen, sondern erst, wenn das Klingeln nicht aufhörte.
Daneben gab es erste Internet-Experimente von Enthusiasten in einzelnen Laboren einzelner Universitäten. Dabei wurde höchstens eine Handvoll Rechner lokal zusammen geschaltet. Diese Netze verließen den Laborraum praktisch nicht.

Gibt es offizielle Zahlen, wie viele Bürger damals das „interne“ Internet genutzt haben?

Mangels Internet gab es gar keine Nutzer.

Welche Reaktionen und Folgen hätte das Internet in der DDR, wenn die Domain offiziell genehmigt worden wäre und die Bürger hätten auch „außerhalb“ kommunizieren können?

Die Existenz der Top-Level-Domain ".dd" (https://de.wikipedia.org/wiki/.dd) ist allein durch den reservierten Eintrag in der internationalen Liste der offiziellen Abkürzungen von Ländernamen (https://de.wikipedia.org/wiki/ISO-3166-1-Kodierliste) gerechtfertigt. Die bei einzelnen Experimenten an einzelnen Universitäten benötigten Namen wurden von den Beteiligten durchaus mit dem kanonischen Namen "kiste.uni-xxx.dd" benutzt. Eine über solche Testaufbauten hinaus gehende Verwendung ist nicht bekannt.
Aus der Geschichte der Mailboxnetze vor allem im Zusammenhang mit den Friedensbibliotheken im Vorfeld der Wende zeigt, dass eine aktive Kommunikation aus kleinen Gruppen große Bewegungen machen kann.
Die Kommunikation der DDR-Bürger mit dem Ausland entsprach durchaus den damals üblichen Standards: Es wurden Briefe geschrieben, telefoniert und sich getroffen. Alles natürlich im Rahmen der geltenden Möglichkeiten.