project:whichismydns
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
project:whichismydns [2015/09/13 18:20] – HgvsfhKbT 146.185.234.48 | project:whichismydns [2016/03/15 00:11] (current) – old revision restored 91.89.129.106 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | http://stolenteenwebcams.ga/#3645 sex girl cams, | + | ====== Which is my DNS ? ====== |
+ | |||
+ | ===== Problem ===== | ||
+ | |||
+ | Es gibt schraege Setups, da moechte man doch mal wissen, welcher DNS | ||
+ | da letztlich als Resolver genutzt wird. | ||
+ | |||
+ | Beispielsweise wird vom ISP einem Dialuprouter ein DNS zugewiesen | ||
+ | und der Router meldet sich selbst als DNS fuer die angeschlossenen | ||
+ | Rechner. Herauszufinden, | ||
+ | |||
+ | ===== Idee ===== | ||
+ | |||
+ | Wenn man einen authoritative DNS betreibt, kann man die Anfragen | ||
+ | der Resolver sichtbar machen. | ||
+ | |||
+ | Das ganze fuer Leute ohne eigenen DNS als Webservice. | ||
+ | |||
+ | ===== Plan ===== | ||
+ | |||
+ | * Auf einem authoritative DNS kann man die Anfragen der Resolver (per querylog oder tcpdump) sichtbar machen. | ||
+ | * Das Querylog kann ziemlich gross und unhandlich werden, Log-Rotation bringt bei Ablaeufen, die Log-Dateien folgen, so ihre eigenen Probleme mit. | ||
+ | * tcpdump zerparsen muss vllt. auch nicht sein. | ||
+ | * Ueberhaupt: ein ganzer Nameserver mit viel mehr Funktionalitaet als hier benoetigt und dann doch nicht mit der, die erforderlich ist? | ||
+ | * Es sollte doch moeglich sein, fuer den Kleinkram (Antwort auf einen Request) das selbst zu coden. Das koennte einem die Daten direkt so liefern, wie sie benoetigt werden. | ||
+ | |||
+ | * Damit man den Request zuverlaessig wiederfindet, | ||
+ | |||
+ | * Um den Einfluss von DNS-Caching klein zu halten, wird eine TTL von 60s gewaehlt. | ||
+ | |||
+ | * Der Ablauf: | ||
+ | * HTTP-RQ auf die Website | ||
+ | * Die aufgerufene Seite liefert per HTTP-Server-Push zwei Seiten. | ||
+ | * Die erste zurueckgelieferte Seite enthaelt ein <IMG> in dessen URL ein variabler, eindeutiger Hostname angegeben ist. | ||
+ | * Der Browser fragt diesen Hostname beim DNS an. | ||
+ | * da der Name erstmalig auftaucht, wird die komplette Delegationskette traversiert und die Query trifft beim selbst implementierten DNS ein. | ||
+ | * Der protokolliert die anfragende IP zusammen mit dem angefragten Hostname und | ||
+ | * liefert die IP des Systemes zurueck, auf dem der Webservice laeuft. | ||
+ | * Die zweite zurueckgelieferte Seite enthaelt das Ergebnis. | ||
+ | * Fuer den Prozess ist es egal, ob der DNS was zurueckliefert und ob das <IMG> ausgeliefert wird. Es muss nur der Request der IMG-URL beim DNS ankommen. | ||
+ | |||
+ | ===== DNS ===== | ||
+ | |||
+ | RFC1035 angeschaut. Zunaechst hat mich der Paketaufbau interessiert, | ||
+ | |||
+ | 4.1. Format | ||
+ | |||
+ | All communications inside of the domain protocol are carried in a single | ||
+ | | ||
+ | into 5 sections (some of which are empty in certain cases) shown below: | ||
+ | |||
+ | +---------------------+ | ||
+ | | Header | ||
+ | +---------------------+ | ||
+ | | | ||
+ | +---------------------+ | ||
+ | | Answer | ||
+ | +---------------------+ | ||
+ | | Authority | ||
+ | +---------------------+ | ||
+ | | Additional | ||
+ | +---------------------+ | ||
+ | |||
+ | und | ||
+ | |||
+ | | ||
+ | |||
+ | The header contains the following fields: | ||
+ | |||
+ | 1 1 1 1 1 1 | ||
+ | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | ID | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |QR| | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | QDCOUNT | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | ANCOUNT | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | NSCOUNT | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | ARCOUNT | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |||
+ | sowie | ||
+ | |||
+ | | ||
+ | |||
+ | The question section is used to carry the " | ||
+ | i.e., the parameters that define what is being asked. | ||
+ | | ||
+ | |||
+ | 1 1 1 1 1 1 | ||
+ | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | | ||
+ | | ||
+ | / / | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |||
+ | und | ||
+ | |||
+ | | ||
+ | |||
+ | The answer, authority, and additional sections all share the same | ||
+ | | ||
+ | | ||
+ | Each resource record has the following format: | ||
+ | 1 1 1 1 1 1 | ||
+ | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | | ||
+ | / / | ||
+ | / NAME / | ||
+ | | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | TYPE | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | TTL | | ||
+ | | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | | | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| | ||
+ | / | ||
+ | / / | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |||
+ | straight forward also: | ||
+ | |||
+ | die Frage enthaelt Header mit ID (random), evtl. dem Flag " | ||
+ | und QDCOUNT = 1. Es folgt die Question mit dem Hostnamen, dem Query Type 1 (A-Record) | ||
+ | und der Query Class 1 (Internet, da gibt's noch CHAOS und HESIOD, never mind). | ||
+ | |||
+ | Die Antwort enthaelt Header mit ID (aus der Frage), den Flags QR=1 (Antwort), AA=1 (Authoritative Answer), | ||
+ | RA=0 (Recursion Available - hier nicht implementiert), | ||
+ | ANCOUNT=1 (da eine Antwort gegeben wird), die urspruengliche Frage mit deren QTYPE und QCLASS gefolgt | ||
+ | von dem Resource-Record, | ||
+ | |||
+ | Im Falle einer Anfrage, die nicht beantwortet werden kann, wird der RCODE=4 (Not Implemented) | ||
+ | mitgegeben. Alles uebrige wird 0. | ||
+ | |||
+ | ==== Hassle mit den Bits ==== | ||
+ | |||
+ | Ich hab' das Ganze in perl gemacht, weil a.) kann ich fliessend perl, | ||
+ | b.) hab' ich keine Lust auf die Untiefen von Pointern und null-terminierten Strings. | ||
+ | |||
+ | ABER: die Bitfickerei - das ist rettungslos verloren. | ||
+ | |||
+ | Die Bits sind im RFC1035 so notiert: | ||
+ | 1 1 1 1 1 1 | ||
+ | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |||
+ | Bit 0 ist dabei das hoechstwertige Bit (MSB) 0x8000 (2^15) und | ||
+ | Bit 15 das geringwertigste (LSB) 0x0001 (2^0). | ||
+ | |||
+ | So einen 16-Bit-Wert bekommt man in perl mit unpack(" | ||
+ | |||
+ | ABER: fuer einen Bitvektor wie: | ||
+ | 1 1 1 1 1 1 | ||
+ | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |QR| | ||
+ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ||
+ | |||
+ | wird es finster. Denn unpack(" | ||
+ | Bytegrenze neu auf. Also sind auch diese 16 Bit am Stueck in eine | ||
+ | Variable zu packen und wie schon zu Assembler-Zeiten mit AND zu maskieren | ||
+ | und zu shiften. Echt. | ||
+ | |||
+ | ==== Dummy-DNS ==== | ||
+ | |||
+ | Der erste Wurf des dummy-dns. | ||
+ | * kann A-Records zurueckliefern. | ||
+ | * erzeugt viel Debug-Output | ||
+ | |||
+ | <file txt dummy-dns> | ||
+ | #!/ | ||
+ | |||
+ | use strict; | ||
+ | use Data:: | ||
+ | |||
+ | sub build_rr | ||
+ | sub build_name | ||
+ | sub decode_flags ($); | ||
+ | sub encode_flags ($); | ||
+ | |||
+ | $|=1; | ||
+ | |||
+ | use IO:: | ||
+ | |||
+ | my $sock = IO:: | ||
+ | LocalPort => 53, | ||
+ | Proto | ||
+ | ); | ||
+ | |||
+ | if ( ! $sock ) { | ||
+ | die " | ||
+ | } | ||
+ | |||
+ | while (my $s = $sock-> | ||
+ | my($port, $binary_ipaddr) = sockaddr_in($sock-> | ||
+ | my $hishost = gethostbyaddr($binary_ipaddr, | ||
+ | print " | ||
+ | |||
+ | my $query = {}; | ||
+ | |||
+ | print unpack(" | ||
+ | ( | ||
+ | my $_flags, | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | ) = unpack(" | ||
+ | n | ||
+ | n | ||
+ | n | ||
+ | n | ||
+ | n | ||
+ | n | ||
+ | ", | ||
+ | print "N: ", | ||
+ | $query = { %$query, %{ decode_flags $_flags } }; | ||
+ | print " | ||
+ | |||
+ | print "D $datagram\n"; | ||
+ | |||
+ | my $qname = substr($datagram, | ||
+ | print " | ||
+ | |||
+ | my @QName = (); | ||
+ | |||
+ | my $i = 73; # chars f. IPv6 PTR | ||
+ | QNAME: { | ||
+ | do { | ||
+ | my $qnamepart = unpack(" | ||
+ | if ( $qnamepart eq "" | ||
+ | last QNAME; | ||
+ | } | ||
+ | push @QName, $qnamepart; | ||
+ | print " | ||
+ | $qname = substr($qname, | ||
+ | } while ($i--); | ||
+ | } | ||
+ | print " | ||
+ | $query-> | ||
+ | ( undef, | ||
+ | unpack(" | ||
+ | print " | ||
+ | print " | ||
+ | |||
+ | my $ans = undef; | ||
+ | if ( | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | $query-> | ||
+ | ) { | ||
+ | |||
+ | print " | ||
+ | |||
+ | my $rr = build_rr { | ||
+ | name | ||
+ | type | ||
+ | class | ||
+ | ttl | ||
+ | rdlength => 4 , # 4 bytes | ||
+ | rdata | ||
+ | }; | ||
+ | |||
+ | $ans = build_packet({ | ||
+ | id => $query-> | ||
+ | qr => 1 , # response | ||
+ | opcode | ||
+ | aa => 1 , # authoritative answer | ||
+ | tc => 0 , # no truncation | ||
+ | rd => 0 , # | ||
+ | ra => 0 , # no recursion available | ||
+ | z => 0 , # always 0 | ||
+ | rcode | ||
+ | qdcount => 1 , # 1 query | ||
+ | ancount => 1 , # 1 answer RR | ||
+ | nscount => 0 , # 0 authoritative NS RR | ||
+ | arcount => 0 , # additional RR | ||
+ | rr => $rr , | ||
+ | # | ||
+ | # | ||
+ | }); | ||
+ | } else { # error condition | ||
+ | |||
+ | print "ERROR HERE\n"; | ||
+ | |||
+ | $ans = build_packet({ | ||
+ | id => $query-> | ||
+ | qr => 1 , # response | ||
+ | opcode | ||
+ | aa => 1 , # authoritative answer | ||
+ | tc => 0 , # no truncation | ||
+ | rd => 0 , # | ||
+ | ra => $query-> | ||
+ | z => 0 , # always 0 | ||
+ | rcode | ||
+ | qdcount => 0 , | ||
+ | ancount => 0 , | ||
+ | nscount => 0 , | ||
+ | arcount => 0 , | ||
+ | rr => "" | ||
+ | qtype | ||
+ | qclass | ||
+ | }); | ||
+ | } | ||
+ | $sock-> | ||
+ | } | ||
+ | |||
+ | sub build_packet ($) { | ||
+ | my ($p) = @_; | ||
+ | my $_flags = 0; | ||
+ | print Dumper($p); | ||
+ | |||
+ | $_flags = encode_flags $p; | ||
+ | |||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | # $_flags |= $p-> | ||
+ | |||
+ | print "BPF: $_flags\n"; | ||
+ | print "BPF: ", | ||
+ | |||
+ | if ( | ||
+ | defined $p-> | ||
+ | defined $p-> | ||
+ | ) { | ||
+ | |||
+ | return pack( | ||
+ | "n n n n n n a* n n", | ||
+ | $p-> | ||
+ | $_flags, | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | ); | ||
+ | } elsif ( | ||
+ | ! defined $p-> | ||
+ | ! defined $p-> | ||
+ | ) { | ||
+ | return pack( | ||
+ | "n n n n n n a*", | ||
+ | $p-> | ||
+ | $_flags, | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | ); | ||
+ | } else { | ||
+ | die " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub build_name ($) { | ||
+ | join "", | ||
+ | } | ||
+ | |||
+ | sub build_rr ($) { | ||
+ | my ($p) = @_; | ||
+ | print Dumper($p); | ||
+ | |||
+ | # 0x0000: | ||
+ | # 0x0010: | ||
+ | # 0x0020: | ||
+ | # 0x0030: | ||
+ | # 0x0040: | ||
+ | |||
+ | print join " ", " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | return pack( | ||
+ | "a* n n n n n N n a*", | ||
+ | build_name $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | 0xc00c, | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | sub encode_flags ($) { | ||
+ | my ($p) = @_; | ||
+ | |||
+ | |||
+ | my $_flags = | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ( $p-> | ||
+ | ; | ||
+ | |||
+ | print "N: $_flags\n"; | ||
+ | return $_flags; | ||
+ | } | ||
+ | |||
+ | sub decode_flags ($) { | ||
+ | my ($_flags) = @_; | ||
+ | |||
+ | my $p = {}; | ||
+ | print "N: $_flags\n"; | ||
+ | |||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | $p-> | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | print " | ||
+ | |||
+ | return $p; | ||
+ | } | ||
+ | |||
+ | __END__ | ||
+ | |||
+ | # | ||
+ | # ein RR in einer DNS-Anwort nach einem A-RR hat lt. RFC 1035 p.28 das Format: | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # / | ||
+ | # / | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # / | ||
+ | # / | ||
+ | # | ||
+ | # | ||
+ | # Tatsaechlich kommt folgendes von einem DNS als | ||
+ | # Antwort zurueck: | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # [0] [1] | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # ----- 6 --------] | ||
+ | # | ||
+ | # | ||
+ | # -] | ||
+ | # | ||
+ | # wobei: | ||
+ | # | ||
+ | # | ||
+ | # RECURSION-DESIRED=1 RECURSION-AVAILABLE=1 Z=0 RCODE=0 | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # [9a] [---- 9b ---] | ||
+ | # Label an Offset 12[9b] wiederverwenden[9a], | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | </ |
project/whichismydns.1442161235.txt.gz · Last modified: 2015/09/13 18:20 by 146.185.234.48