Building a serverless dynamic DNS system with AWS

Wie war dieser Inhalt?

Dieser Beitrag wurde ursprünglich im Dezember 2015 veröffentlicht. Es wurde im Juli 2023 aktualisiert, um die Lösung kostengünstiger und effizienter zu machen. Dieser Beitrag wurde aktualisiert, um Amazon API Gateway durch AWS-Lambda-Funktions-URLs und Amazon Simple Storage Service (Amazon S3) durch Amazon DynamoDB zu ersetzen. Die Verwendung von Lambda-Funktions-URLs reduziert die Gesamtkosten der Lösung. Für diese Funktion fallen keine zusätzlichen Kosten an, wenn Sie den Lambda-Dienst verwenden, und sie bietet einen RESTful-HTTPS-Endpunkt, mit dem unser Kunde interagiert. Das Ersetzen von Amazon S3 durch DynamoDB erhöht die Effizienz der Lösung und reduziert die Gesamtlatenz beim Abfragen von Daten.

Startups in der Frühphase, kleine Unternehmen und Heimnetzwerke verfügen häufig über dynamische öffentliche IP-Adressen, die sich ohne vorherige Ankündigung ändern können. Aufgrund dieser sich ändernden Adresse können Sie von außen nicht zuverlässig auf Systeme in diesen Netzwerken zugreifen. Für Startups in den frühen Phasen ihres Lebenszyklus ist es wichtig, einen zuverlässigen und hochverfügbaren Service bereitzustellen, um das Vertrauen Ihrer ersten Kunden zu gewinnen.

Dynamische DNS-Systeme lösen dieses Problem, indem sie einen Software-Agenten in Ihrem Netzwerk ausführen, um einen DNS-Eintrag mit der neuesten öffentlichen IP-Adresse auf dem neuesten Stand zu halten. Solange der DNS-Eintrag auf dem neuesten Stand ist, können Sie Ihr Netzwerk finden und Kunden können zuverlässig auf Ihren Service zugreifen.

In diesem Beitrag beschreiben wir, wie Sie mithilfe von Serverless-AWS-Services Ihr eigenes dynamisches DNS-System erstellen. Der Aufbau eines Serverless-Systems, das ausschließlich AWS-Services und ein paar Codezeilen verwendet, ist einfach, kostengünstig und skalierbar und ermöglicht es Ihnen, sich auf die Kerngeschäftslogik Ihres Startups zu konzentrieren, anstatt sich Gedanken über die Skalierung und Wartung der zugrunde liegenden Infrastruktur machen zu müssen.

AWS-Services, die wir in unserem dynamischen DNS-System verwenden

In den nächsten Abschnitten zeigen wir Ihnen, wie Sie die folgenden AWS-Services verwenden, um eine dynamische DNS-Lösung zu erstellen:

  • Mit dem AWS Lambda-Service können Sie Code ausführen, ohne die zugrunde liegenden Server verwalten zu müssen. Ihr Code ist immer einsatzbereit, aber Sie zahlen nur pro Funktionsaufruf, in Schritten von 1 Millisekunde. Der Lambda-Service kann über AWS-SDKs mit anderen AWS-Services interagieren.
  • Lambda-Funktions-URLs bieten einen dedizierten HTTPS-Endpunkt für Ihre Lambda-Funktion. Auf diese Weise können Sie die Funktion direkt von Ihrer Client-Anwendung aus aufrufen, ohne dass Sie ein AWS-SDK verwenden oder die Funktion über einen zusätzlichen Proxyservice aufrufen müssen. Für dieses Feature fallen für den Lambda-Service keine zusätzlichen Kosten an.
  • Amazon Route 53 ist ein verwalteter DNS-Service, mit dem Sie Domains und DNS-Zonen über ein globales Netzwerk von DNS-Servern registrieren und hosten können. Wie bei allen AWS-Services kann Route 53 über APIs verwaltet werden.
  • DynamoDB ist eine vollständig verwaltete, NoSQL-Serverless-Datenbank  mit Schlüsselwerten, die für die Ausführung von Hochleistungsanwendungen in jeder Größenordnung entwickelt wurde. DynamoDB bietet integrierte Sicherheit, kontinuierliche Backups, automatische multiregionale Replikation, In-Memory-Caching sowie Tools für den Datenimport und -export.

Logischer Ablauf des dynamischen DNS-Systems

Abbildung 1 zeigt, wie ein Client seine eigene IP-Adresse findet, indem er eine API-Anfrage an einen Service sendet, der mithilfe einer Lambda-Funktion und der zugehörigen Funktions-URL erstellt wurde.

Wie in Abbildung 2 dargestellt, sendet der Client nun, da er seine öffentliche IP-Adresse kennt, eine weitere Anfrage an unseren Service, um einen DNS-Eintrag einzurichten. Die Lambda-Funktion konsultiert zunächst den in unserer DynamoDB-Tabelle gespeicherten Datensatz, um die Anforderung zu validieren. Wenn die Prüfung erfolgreich ist, legt die Lambda-Funktion den DNS-Eintrag in Route 53 über einen API-Aufruf fest. Jetzt befindet sich die aktuelle IP des Netzwerks im öffentlichen DNS und kann durch eine Standard-DNS-Abfrage gefunden werden.

Vorteile von dynamischem DNS mit Lambda und Route 53

Hier sind einige Vorteile, die Sie durch den Betrieb eines dynamischen Serverless-DNS-Systems erzielen werden:

  • Einfacher einzurichten. Es gibt einen Beispiel-Client mit dem gesamten Code, der Konfiguration und den Anweisungen, um dies in Ihrem eigenen AWS-Konto einzurichten.
  • Thin bis Ultrathin Client. Es sind drei Befehle erforderlich, um die API zu aktualisieren. Sie können Ihren eigenen Client in den meisten Sprachen schreiben und ihn auf Plattformen wie Windows, Linux, macOS, Raspberry Pi, Chrome OS und der DD-WRT/Tomato-USB-Routerfirmware ausführen.
  • Unterstützung für eine beliebige Anzahl von Clients, Hostnamen und Domains. Die Servicelimits und Kontingente für Route 53 finden Sie im Abschnitt „Kontingente“ im Route-53-Entwicklerhandbuch.
  • Kostengünstig – 1 bis 2 USD pro Monat. Route-53-Zonen kosten jeweils 0,50 USD pro Monat, 1 000 000 DNS-Abfragen 0,40 USD und 10 000 Lambda-Funktionsanfragen zur DNS-Aktualisierung kosten unter 0,01 USD.
  • Serverless-Architektur. Serverless-Technologien verfügen über eine automatische Skalierung, eine integrierte Hochverfügbarkeit und ein nutzungsabhängiges Abrechnungsmodell, was zur Erhöhung der Agilität und Kostenoptimierung beiträgt.
  • Granulare Berechtigungen ermöglichen es nur autorisierten Kunden, ihren eigenen Hostnamen zu aktualisieren. Kunden können das System nur von der Adresse aus aktualisieren, die zum DNS hinzugefügt wird.
  • Für Ihr aktuelles DNS-Setup sind geringfügige Änderungen erforderlich. Sie können Ihre primäre .com-Zone bei Ihrem aktuellen DNS-Anbieter lassen und eine sekundäre dynamic.example.com-Zone in AWS verwenden. Weitere Informationen zum Erstellen gehosteter Zonen in Route 53 finden Sie unter Erstellen einer öffentlich gehosteten Zone im Route-53-Entwicklerhandbuch.

Voraussetzungen

Sie benötigen zwei Dinge, um diese Lösung zu erstellen:

  1. Ein AWS-Konto. Neue Konten sind für das kostenlose AWS-Kontingent berechtigt.
  2. Eine Domain, die Sie besitzen und die auf Route 53 oder einem anderen Anbieter gehostet wird. Bei Bedarf können Sie Domains über Route 53 ab nur 3,00 USD registrieren. Eine vollständige Preisspanne finden Sie unter Amazon-Route-53-Preise für die Domain-Registrierung.

So erstellen Sie ein dynamisches DNS-System in Ihrem Konto

Zu diesem Zeitpunkt verfügen Sie über genügend Informationen, um mit der Erstellung Ihrer eigenen Kopie des Systems zu beginnen. Wenn Sie mehr darüber erfahren möchten, wie es funktioniert, lesen Sie weiter.

Wenn Sie mit dem Entwickeln beginnen möchten, ist Route 53 Dynamic DNS with Lambda auf GitHub verfügbar. Darin enthalten sind bebilderte Anweisungen sowie der gesamte erforderlichen Code und die Konfiguration.

So funktioniert das neue System

Zunächst muss der Client die öffentliche IP finden, die seinem Netzwerk zugewiesen ist. Wenn Sie eine Anfrage von Ihrem Netzwerk an einen Service im Internet stellen, sieht dieser Service, dass die Anforderung von Ihrer externen IP-Adresse kommt.

Dann stellt der Client eineHTTP POST-Anforderung an die URL der Lambda-Funktion mit einem Anforderungstext von{"execution_mode":"get"} und erhält eine Antwort, die die aktuelle öffentliche IP-Adresse enthält:

HTTP POST
> https://.....lambda-url.eu-west-1.on.aws

{“return_message”:
“176.32.100.36”, “return_status”: “success”}

Während dieses Vorgangs konvertiert die URL der Lambda-Funktion dieHTTP-Anforderung einschließlich aller Anforderungsparameter in JSON und übergibt die Quell-IP-Adresse des Anforderers an eine Python-Lambda-Funktion. Die Lambda-Funktion sendet dann eine JSON-Antwort mit der IP zurück an den Client.

Abbildung 3 zeigt eine Anforderung zum Abrufen einer öffentlichen IP.

Der Client erstellt nun ein Anforderungstoken, indem er die von der HTTP POST-Anforderung zurückgegebene öffentliche IP-Adresse, den DNS-Hostnamen und ein gemeinsames Geheimnis verknüpft. Wenn Ihre IP-Adresse beispielsweise 176.32.100.36 ist, Ihr Hostname host1.dyn.example.com und Ihr geteiltes Secret shared_secret_1 lauten, lautet die verknüpfte Zeichenfolge wie folgt:

176.32.100.36host1.dyn.example.comshared_secret_1

Als Nächstes generiert der Client eine SHA-256-Hash-Funktion aus der Zeichenfolge:

echo -n 176.32.100.36host1.dyn.example.comshared_secret_1 | shasum -a 256

Hash: 96772404892f24ada64bbc4b92a0949b25ccc703270b1f6a51602a1059815535

Der Client fordert dann das DNS-Update an, indem er eine zweite HTTP POST-Anforderung stellt. Er übergibt den Klartext-Hostnamen als Schlüssel und die Hash-Funktion als Authentifizierungstoken im Anforderungstext:

HTTP POST > https://....lambda-url.eu-west-1.on.aws

{“execution_mode”:”set”, “ddns_hostname”:”host1.dyn.example.com”, “validation_hash”:”96772404892f24ada64bbc4b92a0949b25ccc703270b1f6a51602a1059815535”}

Die URL der Lambda-Funktion übergibt dann die Anforderungsparameter zurück an die Lambda-Funktion.

Danach fragt die Lambda-Funktion ihren JSON-Konfigurationsdatensatz mithilfe des AWS-SDK für Python (Boto3) von DynamoDB ab. In diesem System verwenden Interaktionen zwischen dem Lambda-Service, DynamoDB und Route 53 Boto3, das in die Lambda-Service-Laufzeitumgebung vorintegriert ist.

Sobald unsere Lambda-Funktion den Konfigurationsdatensatz von DynamoDB abfragt, verwendet sie den Hostnamen als Schlüssel, um das geteilte Secret und andere mit diesem Datensatz verknüpfte Konfigurationen zu finden, ähnlich dem folgenden Beispieldatensatz:

{
"host1.dyn.example.com.": {
"aws_region": "us-west-2",
"route_53_zone_id": "MY_ZONE_ID",
"route_53_record_ttl": 60,
"route_53_record_type": "A",
"shared_secret": "SHARED_SECRET_1"
},
"host2.dyn.example.com.": {.....

Der Client hat host1.dyn.example.com als Schlüssel übergeben, sodass die Lambda-Funktion SHARED_SECRET_1 aus der Konfiguration liest und das Hash-Funktionstoken mithilfe des Hostnamens, der IP-Adresse des Anforderers und des geteilten Secrets neu erstellt. Wenn die von der Lambda-Funktion berechnete Hash-Funktion und die vom Client empfangene Hash-Funktion übereinstimmen, wird die Anforderung als gültig betrachtet.

Sobald die Anforderung validiert ist, verwendet die Lambda-Funktion die Informationen aus der Konfiguration, um einen API-Aufruf an Route 53 zu tätigen, um festzustellen, ob der DNS-Hostname bereits mit der Client-IP festgelegt ist. Wenn keine Änderung erforderlich ist, reagiert die Lambda-Funktion auf den Client und wird beendet:

{“return_message”: “Your IP address matches the current Route53 DNS record.”,
 “return_status”: “success”}

Wenn kein Datensatz vorhanden ist oder wenn der aktuelle Datensatz und die Client-IP nicht übereinstimmen, tätigt die Lambda-Funktion einen API-Aufruf an Route 53, um den Datensatz festzulegen, antwortet dem Client und wird beendet:

{“return_message”: “Your hostname record host1.dyn.example.com. has been set to 176.32.100.36”,
 “return_status”: “success”}

Abbildung 4 zeigt die Anforderung, den Hostnamen festzulegen.

Wie wird dieses System geschützt?

  • Die gesamte Kommunikation, die Lambda-Funktions-URLs verwendet, ist verschlüsselt.
  • Das geteilte Secret wird niemals über das Internet übertragen.
  • Die Client-Anforderungsrate kann mithilfe des reservierten Parallelitätsfeatures des Lambda-Service gedrosselt werden.
  • Der Authentifizierungsmechanismus ist mehrstufig, da der Client das geteilte Secret („etwas, das er hat“) und seine eigene öffentliche IP-Adresse („etwas, das er ist“) vorlegt.
  • Die Konfigurationsdatei kann im Ruhezustand über die serverseitige DynamoDB-Verschlüsselung verschlüsselt werden.
  • Ihre AWS-Anmeldeinformationen werden nicht verwendet, sodass sie nicht nach außen dringen können.

Fazit

Das dynamische DNS-System, das wir in diesem Beitrag beschreiben, zeigt, wie Sie Ihre eigene Serverless-Lösung in AWS erstellen, um ein reales Problem zu lösen – DNS ist anfällig für Änderungen, und Sie wissen es vielleicht nicht!

Verwenden Sie diese Lösung, um Ihr eigenes dynamisches DNS in AWS auszuführen. Oder verwenden Sie es als Beispiel, um zu erfahren, wie Sie AWS-Services verwenden können, um Ihre eigenen Serverless-Lösungen in jeder Größenordnung zu erstellen.

Besuchen Sie Route 53 dynamic DNS with Lambda auf GitHub, um einen vollständigen Satz an Code, Konfiguration und Anweisungen zur Bereitstellung zu erhalten.

Wie war dieser Inhalt?