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/14 17:28] – QuHwkOlBDdo 146.185.234.48 | project:whichismydns [2016/03/15 00:11] (current) – old revision restored 91.89.129.106 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | http://maturemomlivehotcam.ml/#8251 mature mom live hot cam, | + | ====== 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.1442244502.txt.gz · Last modified: 2015/09/14 17:28 by 146.185.234.48