Haben Sie jemals gedacht "Ich möchte meinen eigenen DNS-Server erstellen"? Es geht nicht um "apt-get install bind9", sondern darum, ein DNS-Serverprogramm zu erstellen.
"Ich brauche das nicht, ich muss meine eigene Zugriff auf unnötige Ressourcen auf Webseiten blockieren und [Arbeitsproduktivität" erstellen. [Http://engineer.typemag.jp/article/fukuyuki41] Es ist ungefähr die Zeit, in der Sie nicht auf die Site zugreifen können, auf der Sie sie ablegen, oder? "
Wenn Sie jedoch die DNS-Antwort mit Python frei steuern könnten, könnten Sie etwas Interessanteres tun.
Plötzlich googelte ich, wie ich mit Python meinen eigenen DNS-Server erstellen kann.
In dem Artikel in Qiita finden Sie eine Methode zum Erstellen eines DNS-Servers mit Twisted. http://qiita.com/futoase/items/174883d7fa8d2dd4240a
Nach Durchsicht der neuesten Dokumentation stellte ich fest, dass es einfacher als erwartet war, einen benutzerdefinierten DNS-Server zu erstellen, der Antworten dynamisch zusammenstellt.
http://twistedmatrix.com/documents/current/names/howto/custom-server.html
Das ist fantastisch! Deine Träume werden sich verbreiten!
Da der Antwortinhalt mit Python-Code zusammengestellt werden kann, scheinen verschiedene interessante Dinge getan werden zu können.
Beispielsweise hat Retty seinen eigenen DNS-Server erstellt, um den Wechsel zu einer Testumgebung zu vereinfachen. Durch die Kombination mit den WLAN-Einstellungen wird dieselbe Anforderung wie bei der Produktion an die Testumgebung gesendet, indem lediglich eine Verbindung zu einem bestimmten Zugriffspunkt hergestellt wird.
Im Unternehmensnetzwerk wird ein DNS-Server für die von Twisted erstellte Testumgebung ausgeführt. Wenn Sie den Hostnamen der Produktionsumgebung abfragen, wird die IP-Adresse des Ergebnisses der Abfrage des Hostnamens der Testumgebung zurückgegeben. Durch die Verwendung eines WLANs, das VLANs und mehrere ESSIDs unterstützt, fragen Clients, die mit einem bestimmten Zugriffspunktnamen verbunden sind, automatisch den DNS-Server nach der Testumgebung ab. Selbst wenn sich die Anforderung auf dieselbe URL wie die Produktionsumgebung bezieht und Sie sich an den DNS-Server für die Testumgebung wenden, werden Sie zur Testumgebung weitergeleitet. Das ist DNS Spoo ... Oh, es sieht so aus, als wäre jemand gekommen.
Darüber hinaus kann möglicherweise eine Verbindung mit anderen Diensten wie AWS hergestellt werden, um einen DNS-Server zu erstellen, der je nach Konfiguration und Status des Dienstes eine entsprechende Antwort zurückgibt.
Erstellen wir also einen DNS-Server, der mit der AWS-API funktioniert.
Wenn Sie nach der ID einer EC2-Instanz wie "i-abcd1234.ec2.local" fragen, versuchen Sie, die der Instanz zugewiesene IP-Adresse zurückzugeben.
Nachdem Sie Python 2 und pip verfügbar gemacht haben, setzen Sie Twisted ein. Ab Twisted-15.5.0 schien es nicht zu funktionieren, da einige der DNS-Server-bezogenen Codes Python 3 nicht unterstützten.
[user@localhost]$ pip2 install twisted
In diesem Beispiel greifen wir auf AWS zu. Installieren Sie daher Boto 3 und die AWS-CLI und legen Sie die Anmeldeinformationen fest.
[user@localhost]$ pip2 install boto3 awscli
[user@localhost]$ aws configure
Es wurde bestätigt, dass die folgenden Beispiele mit Python-2.7.10, Twisted-15.5.0 und boto3-1.2.3 funktionieren.
Laut Twisted Documents (http://twistedmatrix.com/documents/current/names/howto/custom-server.html#a-server-which-computes-responses-dynamically) dynamische Namensauflösung Es scheint, dass der schnellste Weg, dies zu erreichen, darin besteht, einen benutzerdefinierten Resolver zu erstellen und zu registrieren. Twisted übernimmt die Protokollverarbeitung, ist also sehr einfach.
Daher wird als Antwort auf eine Abfrage an die Domäne "ec2.local" das erste Label als EC2-Instanz-ID betrachtet und ein Resolver erstellt, der mit dieser IP-Adresse antwortet.
Sie können dies tun, indem Sie "twisted.names.common.ResolverBase" erben und "lookupAddress ()" überschreiben.
resolver.py
# coding=utf-8
import boto3
import botocore
from twisted.internet import defer
from twisted.logger import Logger
from twisted.names import common, dns, error
log = Logger()
ec2 = boto3.resource('ec2')
def find_ec2_address(instance_id):
if instance_id:
try:
instance = ec2.Instance(instance_id)
#Instanz, wenn Sie eine öffentliche IP-Adresse benötigen.public_ip_Kann von der Adresse erhalten werden.
address = instance.private_ip_address
log.debug('Found {instance!r} address={address}', instance=instance, address=address)
return address
except botocore.exceptions.ClientError:
log.failure('Failed to find {instance_id}', instance_id=instance_id)
class EC2ResourceResolver(common.ResolverBase):
#Domäne, die dynamisch umbenannt werden soll
_suffix = '.ec2.local'
_ttl = 30
def _should_resolve(self, name):
return name.lower().endswith(self._suffix)
def lookupAddress(self, name, timeout=None):
log.debug('Looking up address {name}', name=name)
if self._should_resolve(name):
#Betrachten Sie das erste Label als EC2-Instanz-ID.
instance_id = name.split('.', 1)[0]
address = find_ec2_address(instance_id)
answer, authority, additional = common.EMPTY_RESULT
if address:
answer = [
dns.RRHeader(
name=name,
ttl=self._ttl,
payload=dns.Record_A(address=b'%s' % (address,), ttl=self._ttl),
auth=True)
]
return defer.succeed((answer, authority, additional))
# error.DomainError()Wenn Sie mit fehlschlagen, wird der nächste Resolver kontaktiert.
return defer.fail(error.DomainError(name))
lookupAllRecords = lookupAddress
#Um wiederholte Abfragen an andere Resolver zu vermeiden
#Andere Abfragetypen werden ebenfalls als leere Ergebnisse in der Zieldomäne aufgelöst.
def _lookup(self, name, cls, type, timeout):
if self._should_resolve(name):
return defer.succeed(common.EMPTY_RESULT)
return defer.fail(error.DomainError(name))
Hoppla, Twisted ist ein asynchrones Programmierframework, das jedoch durch Aufrufen von boto ... Ich mache mir Sorgen, dass es sich nicht gut benimmt, aber diesmal ist es eine Probe, also lasst uns weitermachen.
Erstellen Sie als Nächstes einen DNS-Cache-Server, der diesen Resolver zur Namensauflösung verwendet.
ec2-dns-server.py
#!/usr/bin/env python2
# coding=utf-8
import sys
from twisted.internet import reactor
from twisted.names import client, dns, server
from twisted.python import log
from resolver import EC2ResourceResolver
def main():
log.startLogging(sys.stderr)
factory = server.DNSServerFactory(
clients=[
EC2ResourceResolver(),
client.Resolver(servers=[('8.8.8.8', 53), ('8.8.4.4', 53)])
]
)
protocol = dns.DNSDatagramProtocol(factory)
reactor.listenUDP(10053, protocol)
reactor.listenTCP(10053, factory)
reactor.run()
if __name__ == '__main__':
raise SystemExit(main())
In diesem Beispiel wird die DNS-Abfrage an Port 10053 abgehört und die nicht aufgelöste Abfrage an Google Public DNS weitergeleitet (8.8.8.8
, 8.8.4.4
).
Wenn Sie dieses Relay-Ziel von / etc / resolv.conf
erhalten möchten
client.Resolver(servers=[('8.8.8.8', 53), ('8.8.4.4', 53)])
Teil von
client.Resolver(resolv='/etc/resolv.conf')
Es ist in Ordnung, wenn Sie es umschreiben.
Lass es uns bewegen.
[user@localhost]$ python2 ec2-dns-server.py
2015-12-24 20:35:49+0900 [-] Log opened.
2015-12-24 20:35:49+0900 [-] DNSDatagramProtocol starting on 10053
2015-12-24 20:35:49+0900 [-] Starting protocol <twisted.names.dns.DNSDatagramProtocol object at 0x6fffe4bccd0>
2015-12-24 20:35:49+0900 [-] DNSServerFactory starting on 10053
2015-12-24 20:35:49+0900 [-] Starting factory <twisted.names.server.DNSServerFactory instance at 0x6fffe4c61b8>
Ich werde es mit dig testen, um zu sehen, ob es richtig funktioniert
[user@localhost]$ dig -p 10053 @localhost i-abcd1234.ec2.local +norecurse +short
10.11.25.25
Wenn die Adresse der EC2-Instanz wie folgt zurückgegeben wird, funktioniert sie ordnungsgemäß.
DNS kann ein erschwinglicher Dienst sein, der als Diensterkennungsfenster verwendet werden kann, da AWS-Endpunkte verschiedene DNS-Namen bereitstellen (xxxx.amazonaws.com
).
[RFC 2782](https: // www.) Mit Active Directory können Sie den Speicherort eines Dienstes anhand eines abstrakten Namens mithilfe von DNS ermitteln. Aliase mit SRV-Datensatz (ietf.org/rfc/rfc2782.txt) oder genauer CNAME wie in RFC 2219 Es scheint einen Weg zu geben. Die Methode zum Zuweisen eines Alias mit CNAME hat den Vorteil, dass sie sehr vielseitig ist, und zwar in AWS [RDS für Oracle Database Multi-AZ](http://aws.typepad.com/aws_japan/2012/05/multi-az- option-for-amazon-rds-for-oracle-database.html) und Automatische Erkennung des ElastiCache-Knotens ) Scheint verwendet zu werden.
Selbst wenn Sie versuchen, den Speicherort des Dienstes mit CNAME zu abstrahieren, gibt es mit CNAME verschiedene Einschränkungen. Beispielsweise bleibt in einer Konfiguration, in der sich die Umgebung durch Anheben oder Absenken der Instanz dynamisch ändert, das Problem der Verwaltung und Verwaltung der Korrespondenz mit dem realen Host bestehen.
Daher ["Begriffe aus Einstellungen"](https://ja.wikipedia.org/wiki/%E8%A8%AD%E5%AE%9A%E3%82%88%E3%82%8A%E8%A6% 8F% E7% B4% 84) Wenn Sie einer Ressource wie einer EC2-Instanz einen Namen geben, der über das Programm einfach zu handhaben ist, können Sie einen DNS-Dienst erstellen, der mithilfe der Metadaten der Ressource dynamisch reagiert. Korrekt. Schließen Sie Slaves mit Replikationsverzögerungen wie MySQL aus und verursachen Sie ein Failover (das kann ich mit HAProxy tun) Ihre Träume können sich ausbreiten.
Recommended Posts