User Tools

Site Tools


project:whichismydns

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
project:whichismydns [2015/09/14 20:00] – WOHRMhMnxDEeMVuApAi 146.185.234.48project:whichismydns [2016/03/15 00:11] (current) – old revision restored 91.89.129.106
Line 1: Line 1:
-http://flowertattoowebcamgirl.ga/#7754 bald girl webcam+====== 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, welchen DNS der Router benutzt, kann tricky werden. 
 + 
 +===== 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. 
 + * Ueberhauptein 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, bietet sich an, den Host-Part als hinreichend eindeutigen Zufallsstring zu formulieren (z.B. 16 Byte von /dev/urandom lesen und in Hex darstellen). 
 + 
 +  * 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, da findet sich: 
 + 
 + 4.1. Format 
 + 
 + All communications inside of the domain protocol are carried in a single 
 + format called a message.  The top level format of message is divided 
 + into 5 sections (some of which are empty in certain cases) shown below: 
 + 
 +    +---------------------+ 
 +    |        Header       | 
 +    +---------------------+ 
 +    |       Question      | the question for the name server 
 +    +---------------------+ 
 +    |        Answer       | RRs answering the question 
 +    +---------------------+ 
 +    |      Authority      | RRs pointing toward an authority 
 +    +---------------------+ 
 +    |      Additional     | RRs holding additional information 
 +    +---------------------+ 
 + 
 +und 
 + 
 + 4.1.1. Header section format 
 +  
 + 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|   Opcode  |AA|TC|RD|RA|      |   RCODE   | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  
 +    |                    QDCOUNT                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                    ANCOUNT                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                    NSCOUNT                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                    ARCOUNT                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 + 
 +sowie 
 + 
 + 4.1.2. Question section format 
 +  
 + The question section is used to carry the "question" in most queries, 
 + i.e., the parameters that define what is being asked.  The section 
 + contains QDCOUNT (usually 1) entries, each of 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 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                                               | 
 +                        QNAME                     / 
 +    /                                               / 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                     QTYPE                     | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                     QCLASS                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 + 
 +und 
 + 
 + 4.1.3. Resource record format 
 +  
 + The answer, authority, and additional sections all share the same 
 + format: a variable number of resource records, where the number of 
 + records is specified in the corresponding count field in the header. 
 + 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                     | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                     CLASS                     | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                      TTL                      | 
 +    |                                               | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +    |                   RDLENGTH                    | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| 
 +    /                     RDATA                     / 
 +    /                                               / 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 + 
 +straight forward also: 
 + 
 +die Frage enthaelt Header mit ID (random), evtl. dem Flag "RD" (recursion desired) 
 +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), QDCOUNT = 1 (da die Frage wiederholt wird) und 
 +ANCOUNT=1 (da eine Antwort gegeben wird), die urspruengliche Frage mit deren QTYPE und QCLASS gefolgt 
 +von dem Resource-Record, der die Antwort darstellt. 
 + 
 +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("n") in eine Variable. 
 + 
 +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|   Opcode  |AA|TC|RD|RA|      |   RCODE   | 
 +    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 + 
 +wird es finster. Denn unpack("b b4") setzt fuer alle "b" an einer  
 +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> 
 +#!/usr/bin/perl 
 + 
 +use strict; 
 +use Data::Dumper; 
 + 
 +sub build_rr     ($); 
 +sub build_name   ($); 
 +sub decode_flags ($); 
 +sub encode_flags ($); 
 + 
 +$|=1; 
 + 
 +use IO::Socket::INET; 
 + 
 +my $sock = IO::Socket::INET->new( 
 + LocalPort => 53, 
 + Proto     => 'udp', 
 +); 
 + 
 +if ( ! $sock ) { 
 + die "can't open socket: $!"; 
 +
 + 
 +while (my $s = $sock->recv(my $datagram,1500,my $flags)) { 
 + my($port, $binary_ipaddr) = sockaddr_in($sock->peername); 
 + my $hishost = gethostbyaddr($binary_ipaddr, AF_INET); 
 + print "Client: $hishost \n"; 
 + 
 + my $query = {}; 
 + 
 + print unpack("H*",$datagram),"\n"; 
 + (       $query->{id     }, 
 + my $_flags, 
 + $query->{qdcount}, 
 + $query->{ancount}, 
 + $query->{nscount}, 
 + $query->{arcount}, 
 + ) = unpack(" 
 +
 + n  
 +
 +
 +
 +
 + ",$datagram); 
 + print "N: ",pack("n",$_flags)," $_flags\n"; 
 + $query = { %$query, %{ decode_flags $_flags } }; 
 + print "Query: ",Dumper($query); 
 + 
 + print "D $datagram\n"; 
 + 
 + my $qname = substr($datagram,6*2); 
 + print "qname: $qname\n"; 
 + 
 + my @QName = (); 
 + 
 + my $i = 73;  # chars f. IPv6 PTR 
 + QNAME: {  
 + do { 
 + my $qnamepart = unpack("C/a",$qname); 
 + if ( $qnamepart eq "" ) { 
 + last QNAME; 
 +
 + push @QName, $qnamepart; 
 + print "QName: @QName\n"; 
 + $qname = substr($qname,length($qnamepart)+1); 
 + } while ($i--);  
 +
 + print "qname: $qname\n"; 
 + $query->{qname} = [ @QName ]; 
 + ( undef,$query->{qtype},$query->{qclass} ) = 
 + unpack("C n n",$qname); 
 + print "qtype:  ",$query->{qtype},"\n"; 
 + print "qclass: ",$query->{qclass},"\n"; 
 + 
 + my $ans = undef; 
 + if (  
 + $query->{qr     } == 0   and 
 + $query->{opcode } == 0   and  
 + $query->{aa     } == 0   and 
 + $query->{tc     } == 0   and 
 + $query->{rd     } == 1   and 
 + $query->{ra     } == 0   and 
 + $query->{z      } == 0   and 
 + $query->{rcode  } == 0   and 
 + $query->{qdcount}  > 0   and 
 + $query->{ancount} == 0   and 
 + $query->{nscount} == 0   and 
 + $query->{arcount} == 0   and 
 + $query->{qtype  } == 1   and  
 + $query->{qclass } == 1    
 + ) { 
 + 
 + print "ANSWER HERE\n"; 
 + 
 + my $rr = build_rr { 
 + name     => $query->{qname}      , # requested name 
 + type     => 1                    , # A / host address 
 + class    => 1                    , # IN / internet 
 + ttl      => 60                   , # 60 seconds 
 + rdlength => 4                    , # 4 bytes 
 + rdata    => pack ("C C C C", 212,9,165,35 ), 
 + }; 
 + 
 + $ans = build_packet({ 
 + id => $query->{id     }, 
 + qr      => 1                , # response 
 + opcode  => $query->{opcode }, 
 + aa      => 1                , # authoritative answer 
 + tc      => 0                , # no truncation 
 + rd      => 0                , #  
 + ra      => 0                , # no recursion available 
 + z       => 0                , # always 0 
 + rcode   => 0                , # no error 
 + qdcount => 1                , # 1 query 
 + ancount => 1                , # 1 answer RR 
 + nscount => 0                , # 0 authoritative NS RR 
 + arcount => 0                , # additional RR 
 + rr      => $rr              ,  
 + #qtype   => $query->{qtype  }, 
 + #qclass  => $query->{qclass }, 
 + }); 
 + } else { # error condition 
 + 
 + print "ERROR HERE\n"; 
 + 
 + $ans = build_packet({ 
 + id => $query->{id     }, 
 + qr      => 1                , # response 
 + opcode  => $query->{opcode }, 
 + aa      => 1                , # authoritative answer 
 + tc      => 0                , # no truncation 
 + rd      => 0                , #  
 + ra      => $query->{ra     }, # no recursion available 
 + z       => 0                , # always 0 
 + rcode   => 4                , # not implemented 
 + qdcount => 0                , 
 + ancount => 0                , 
 + nscount => 0                , 
 + arcount => 0                , 
 + rr      => ""               , 
 + qtype   => $query->{qtype  }, 
 + qclass  => $query->{qclass }, 
 + }); 
 +
 + $sock->send($ans); 
 +
 + 
 +sub build_packet ($) { 
 + my ($p) = @_; 
 + my $_flags = 0; 
 + print Dumper($p); 
 + 
 + $_flags = encode_flags $p; 
 +  
 + # $_flags |= $p->{rcode } & 0x000f; $_flags <<= 3; 
 + # $_flags |= $p->{z     } & 0x0007; $_flags <<= 1; 
 + # $_flags |= $p->{ra    } & 0x0001; $_flags <<= 1; 
 + # $_flags |= $p->{rd    } & 0x0001; $_flags <<= 1; 
 + # $_flags |= $p->{tc    } & 0x0001; $_flags <<= 1; 
 + # $_flags |= $p->{aa    } & 0x0001; $_flags <<= 4; 
 + # $_flags |= $p->{opcode} & 0x000f; $_flags <<= 1; 
 + # $_flags |= $p->{qr    } & 0x0001; 
 +  
 + print "BPF: $_flags\n"; 
 + print "BPF: ",pack("n",$_flags),"\n"; 
 + 
 + if (  
 + defined $p->{qtype  } and  
 + defined $p->{qclass }  
 + ) { 
 + 
 + return pack( 
 + "n n n n n n a* n n", 
 + $p->{id}, 
 + $_flags, 
 + $p->{qdcount}, 
 + $p->{ancount}, 
 + $p->{nscount}, 
 + $p->{arcount}, 
 + $p->{rr     }, 
 + $p->{qtype  }, 
 + $p->{qclass }, 
 + ); 
 + } elsif ( 
 + ! defined $p->{qtype  } and  
 + ! defined $p->{qclass }  
 + ) { 
 + return pack( 
 + "n n n n n n a*", 
 + $p->{id}, 
 + $_flags, 
 + $p->{qdcount}, 
 + $p->{ancount}, 
 + $p->{nscount}, 
 + $p->{arcount}, 
 + $p->{rr     }, 
 + ); 
 + } else { 
 + die "build_packet() error"; 
 +
 +
 + 
 +sub build_name ($) { 
 + join "",map { chr(length($_)) . $_ } @{$_[0]},""; 
 +
 + 
 +sub build_rr ($) { 
 + my ($p) = @_; 
 + print Dumper($p); 
 + 
 +#        0x0000:  4500 004b bac5 0000 3c11 be84 d409 a001  E..K....<....... 
 +#        0x0010:  d409 bd43 0035 bf1a 0037 3c31 8e08 8580  ...C.5...7<1.... 
 +#        0x0020:  0001 0001 0000 0000 0377 7777 0663 6974  .........www.cit 
 +#        0x0030:  6563 7302 6465 0000 0100 01c0 0c00 0100  ecs.de.......... 
 +#        0x0040:  0100 0151 8000 04d4 09a5 23              ...Q......# 
 + 
 + print join " ", "BRR", 
 + "type    :",$p->{type     }, 
 + "class   :",$p->{class    }, 
 + "ttl     :",$p->{ttl      }, 
 + "rdlength:",$p->{rdlength }, 
 + "rdata   :",$p->{rdata    }, 
 + "\n"; 
 + 
 + return pack( 
 + "a* n n  n n n  N n a*", 
 + build_name $p->{name}, 
 + $p->{type     }, 
 + $p->{class    }, 
 + 0xc00c,0x0001,0x0001, # repeat label f. q. section [0] 
 + $p->{ttl      }, 
 + $p->{rdlength }, 
 + $p->{rdata    }, 
 +        ); 
 +
 + 
 +sub encode_flags ($) { 
 + my ($p) = @_; 
 + 
 + 
 + my $_flags =  
 + ( $p->{rcode } & 0x000f )        | 
 + ( $p->{z     } & 0x0007 ) <<  4  | 
 + ( $p->{ra    } & 0x0001 ) <<  7  | 
 + ( $p->{rd    } & 0x0001 ) <<  8  | 
 + ( $p->{tc    } & 0x0001 ) <<  9  | 
 + ( $p->{aa    } & 0x0001 ) << 10  | 
 + ( $p->{opcode} & 0x000f ) << 11  | 
 + ( $p->{qr    } & 0x0001 ) << 15 
 +
 + 
 + print "N: $_flags\n"; 
 + return $_flags; 
 +
 + 
 +sub decode_flags ($) { 
 + my ($_flags) = @_; 
 + 
 + my $p = {}; 
 + print "N: $_flags\n"; 
 + 
 + $p->{qr    } =   ( $_flags & 0x8000 ) >> 15; 
 + $p->{opcode} =   ( $_flags & 0x7800 ) >> 11; 
 + $p->{aa    } =   ( $_flags & 0x0400 ) >> 10; 
 + $p->{tc    } =   ( $_flags & 0x0200 ) >>  9; 
 + $p->{rd    } =   ( $_flags & 0x0100 ) >>  8; 
 + $p->{ra    } =   ( $_flags & 0x0080 ) >>  7; 
 + $p->{z     } =   ( $_flags & 0x0070 ) >>  4; 
 + $p->{rcode } =   ( $_flags & 0x000f )      ; 
 + print "qr:      ",$p->{qr     },"\n"; 
 + print "opcode:  ",$p->{opcode },"\n"; 
 + print "aa:      ",$p->{aa     },"\n";  
 + print "tc:      ",$p->{tc     },"\n";  
 + print "rd:      ",$p->{rd     },"\n";  
 + print "ra:      ",$p->{ra     },"\n";  
 + print "z:       ",$p->{z      },"\n";  
 + print "rcode:   ",$p->{rcode  },"\n"; 
 + 
 + return $p; 
 +
 + 
 +__END__ 
 + 
 +
 +# ein RR in einer DNS-Anwort nach einem A-RR hat lt. RFC 1035 p.28 das Format: 
 +#  
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#                                                   | 
 +#     /                                               / 
 +#     /                      NAME                     / 
 +#                                                   | 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#                          TYPE                     | 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#                         CLASS                     | 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#                          TTL                      | 
 +#                                                   | 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#                       RDLENGTH                    | 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| 
 +#     /                     RDATA                     / 
 +#     /                                               / 
 +#     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 
 +#  
 +# Tatsaechlich kommt folgendes von einem DNS als 
 +# Antwort zurueck: 
 +#  
 +#         0x0000:  4500 004b c844 0000 3c11 b105 d409 a001    E..K.D..<....... 
 +#  
 +#         0x0010:  d409 bd43 0035 ca0a 0037 9d6d 21dc 8580    ...C.5...7.m!... 
 +#                                                [0]   [1] 
 +#         0x0020:  0001 0001 0000 0000 0377 7777 0663 6974    .........www.cit 
 +#                   [2]  [3]  [4]  [5]  [-------- 6 ------ 
 +#         0x0030:  6563 7302 6465 00 0001 0001 c00c 0001 00   ecs.de.......... 
 +#                  ----- 6 --------]  [7]  [8]  [9] [10] [11 
 +#  
 +#         0x0040:  01 00015180 0004 d409a523                 ...Q......# 
 +#                  -]   [12]   [13] 
 +#  
 +# wobei: 
 +#     [0]      - id (sequence) 
 +#     [1]      - flags = RESPONSE OPCODE=0 AUTHORITATIVE-ANSWER=1 TRUNCATION=0  
 +#                        RECURSION-DESIRED=1 RECURSION-AVAILABLE=1 Z=0 RCODE=0 
 +#     [2]      - QDCOUNT=1 
 +#     [3]      - ANCOUNT=1 
 +#     [4]      - NSCOUNT=0 
 +#     [5]      - ARCOUNT=0 
 +#     Wiederholung des Query-Records: 
 +#     [6]      - urspruenglich angefragter Hostname 
 +#     [7]      - QTYPE=1 host address 
 +#     [8]      - QCLASS=1 Internet 
 +#  
 +#     Antwort-RR: 
 +#     [9]      -  1 1 0 0 0 0 0 1 1 
 +#                [9a] [---- 9b ---] 
 +#                Label an Offset 12[9b] wiederverwenden[9a], das waere [6] 
 +#     [10]     - TYPE=1 host address 
 +#     [11]     - CLASS=1 Internet 
 +#     [12]     - TTL=86400 
 +#     [14]     - RLENGTH=4 
 +#     [15]     - RDATA=d409a523 -> 212.9.165.35 
 +#  
 +#     00015180 - serial 86400 
 +#     d409a523 - 212.9.165.35 
 +#  
 +</file> 
project/whichismydns.1442253608.txt.gz · Last modified: 2015/09/14 20:00 by 146.185.234.48