Upgrade to Pro — share decks privately, control downloads, hide ads and more …

EuroPython 2014: For Lack of a Better Name(serv...

EuroPython 2014: For Lack of a Better Name(server): DNS Explained

Accompanying writeup: http://rogue.ly/dns

Lynn Root

July 22, 2014
Tweet

More Decks by Lynn Root

Other Decks in Programming

Transcript

  1. $ whoami • Backend Engineer at Spotify • Founder/leader of

    the PyLadies of San Francisco • Board Member of the Python Software Foundation
  2. tl;dr • What it is and why you care about

    DNS • What to do with it • Awesomeness I learned along the way
  3. why DNS? • Visit productive websites like reddit.com • Receive

    critical emails from Groupon and Gilt • Deploy your One-of-a-Kind ToDo™ list application • Allow for your corporate meme generator to not be accessible by non-employees
  4. Domain Name System • Distributed storage system for Resource Records

    • Stores records in its cache or local zone file • Record: label, class, type, and data
  5. >>> from scapy.all import *! >>>! >>> a=sniff(filter="udp and port

    53", count=10)! >>> a! <Sniffed: TCP:0 UDP:10 ICMP:0 Other:0>! >>>! >>> a.show()! 0000 Ether / IP / UDP / DNS Qry "www.google.com." ! 0001 Ether / IP / UDP / DNS Qry "reddit.com." ! 0002 Ether / IP / UDP / DNS Ans "74.125.239.144" ! 0003 Ether / IP / UDP / DNS Ans "96.17.109.11" ! 0004 Ether / IP / UDP / DNS Qry "roguelynn-spy.herokuapp.com." ! 0005 Ether / IP / UDP / DNS Ans "us-east-1-a.route.herokuapp.com." ! 0006 Ether / IP / UDP / DNS Qry "roguelynn.com." ! 0007 Ether / IP / UDP / DNS Ans "81.28.232.189" ! 0008 Ether / IP / UDP / DNS Qry "www.roguelynn.com." ! 0009 Ether / IP / UDP / DNS Ans "roguelynn.com."
  6. $ cat /etc/resolv.conf $ curl example.com DNS Query: example.com.example.net $

    curl example.com. DNS Query: example.com search example.net
  7. # router's DNS! $ whois 75.75.75.75! # snip! Comcast Cable

    Communications Holdings, Inc CCCH-3-34 (NET-75-64-0-0-1) 75.64.0.0 - 75.75.191.255! ! Comcast Cable Communications Holdings, Inc COMCAST-47 (NET-75-75-72-0-1) 75.75.72.0 - 75.75.79.255
  8. $ dig +trace python.org! ; <<>> DiG 9.8.3-P1 <<>> +trace

    python.org! ;; global options: +cmd! .! ! ! 88784! IN! NS! i.root-servers.net.! .! ! ! 88784! IN! NS! h.root-servers.net.! .! ! ! 88784! IN! NS! j.root-servers.net.! .! ! ! 88784! IN! NS! e.root-servers.net.! .! ! ! 88784! IN! NS! g.root-servers.net.! ;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 221 ms! ! org.!! ! 172800! IN! NS! b0.org.afilias-nst.org.! org.!! ! 172800! IN! NS! d0.org.afilias-nst.org.! org.!! ! 172800! IN! NS! b2.org.afilias-nst.org.! ;; Received 430 bytes from 202.12.27.33#53(202.12.27.33) in 469 ms! ! python.org.! ! 86400! IN! NS! ns1.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns3.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns2.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns4.p11.dynect.net.! ;; Received 114 bytes from 199.19.53.1#53(199.19.53.1) in 141 ms! ! python.org.! ! 43200! IN! A! 140.211.10.69! python.org.! ! 86400! IN! NS! ns4.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns2.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns3.p11.dynect.net.! python.org.! ! 86400! IN! NS! ns1.p11.dynect.net.! ;; Received 130 bytes from 208.78.71.11#53(208.78.71.11) in 13 ms
  9. local! DNS I know!! It’s at 140.211.10.69 root net com

    org python python python www blog hg
  10. $ dig +nocmd +noqr +nostats python.org -t ANY! ! ;;

    QUESTION SECTION:! ;python.org.! ! ! IN! ANY! ! ;; ANSWER SECTION:! python.org.! ! 36202! IN! A!140.211.10.69! python.org.! ! 25683! IN! NS! ns3.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns4.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns1.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns2.p11.dynect.net.! ! ;; AUTHORITY SECTION:! python.org.! ! 25683! IN! NS! ns1.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns2.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns3.p11.dynect.net.! python.org.! ! 25683! IN! NS! ns4.p11.dynect.net.! ! ;; ADDITIONAL SECTION:! ns1.p11.dynect.net.!16710! IN! A!208.78.70.11! ns2.p11.dynect.net.!16710! IN! A!204.13.250.11! ns3.p11.dynect.net.!16710! IN! A!208.78.71.11! ns4.p11.dynect.net.!16710! IN! A!204.13.251.11!
  11. $ dig +nocmd +noqr +nostats pyladies.com -t ANY! ! ;;

    QUESTION SECTION:! ;pyladies.com.!! ! IN! ANY! ! ;; ANSWER SECTION:! pyladies.com.! ! 130!IN! MX! 10 ASPMX.L.GOOGLE.com.! pyladies.com.! ! 130!IN! SOA!ns1qsy.name.com. ! ! ! support.name.com. 1 10800 3600 604800 300! pyladies.com.! ! 1!! IN! A!81.28.232.189! pyladies.com.! ! 130!IN! NS! ns2fkr.name.com.! pyladies.com.! ! 130!IN! NS! ns3jkl.name.com.! pyladies.com.! ! 130!IN! NS! ns4kpx.name.com.! pyladies.com.! ! 130!IN! NS! ns1qsy.name.com.! ! ;; AUTHORITY SECTION:! pyladies.com.! ! 130!IN! NS! ns3jkl.name.com.! pyladies.com.! ! 130!IN! NS! ns4kpx.name.com.! pyladies.com.! ! 130!IN! NS! ns1qsy.name.com.! pyladies.com.! ! 130!IN! NS! ns2fkr.name.com.
  12. Caching • Query: • Local Cache • “Closer” name server

    • Authoritative name server • Response now cached
  13. $ dnsmap pyladies.com! dnsmap 0.30 - DNS Network Mapper by

    pagvac (gnucitizen.org)! ! [+] searching (sub)domains for pyladies.com using built-in wordlist! [+] using maximum random delay of 10 millisecond(s) between requests! ! dc.pyladies.com! IP address #1: 81.28.232.189! ! sf.pyladies.com! IP address #1: 81.28.232.189! ! tw.pyladies.com! IP address #1: 23.23.245.47! ! www.pyladies.com! IP address #1: 81.28.232.189
  14. $ tail -n 500 /var/log/system.log! ! SOA 60 spotify.net. SOA

    ns2.spotify.net. dns-! ! ! ! ! ! admin.spotify.com. 2014040507 60 25 3628800 900! AAAA 0 isa.spotify.net. AAAA! SOA 60 spotify.net. SOA ns2.spotify.net. dns-! ! ! ! admin.spotify.com. 2014040507 60 25 3628800 900! Addr 0 isa.spotify.net. Addr! SOA 60 spotify.net. SOA
  15. ###[ Ethernet ]###! dst = 04:a1:51:90:af:d4! src = 14:10:9f:e1:54:9b! type

    = 0x800! ###[ IP ]###! ttl = 255! proto = udp! chksum = 0x12ee! src = 192.168.1.7! dst = 192.168.1.1! ###[ UDP ]###! sport = 54929! dport = domain! ###[ DNS ]###! id = 11102! opcode = QUERY! rcode = ok! qdcount = 1! ancount = 0! nscount = 0! arcount = 0! \qd \! |###[ DNS Question Record ]###! | qname = 'zr.spotify.net.'! | qtype = A! | qclass = IN!
  16. from twisted.internet import reactor! from twisted.names import client, dns, server!

    ! def main():! """! Run the server.! """! factory = server.DNSServerFactory(! clients=[client.Resolver(resolv=‘/etc/resolv.conf')]! )! ! protocol = dns.DNSDatagramProtocol(controller=factory)! ! reactor.listenUDP(10053, protocol)! reactor.listenTCP(10053, factory)! ! reactor.run()! ! if __name__ == '__main__':! raise SystemExit(main())
  17. ###[ Ethernet ]###! dst = 04:a1:51:90:af:d4! src = 14:10:9f:e1:54:9b! type

    = 0x800! ###[ IP ]###! ttl = 64! proto = udp! chksum = 0x4a0c! src = 192.168.1.7! dst = 192.168.1.1! \options \! ###[ UDP ]###! sport = 33408! dport = domain! ###[ DNS ]###! opcode = QUERY! rcode = ok! \qd \! |###[ DNS Question Record ]###! | qname = 'python.org.'! | qtype = A! | qclass = IN
  18. ###[ Ethernet ]###! dst = 14:10:9f:e1:54:9b! src = 04:a1:51:90:af:d4! type

    = 0x800! ###[ IP ]###! ttl = 64! proto = udp! chksum = 0xb74c! src = 192.168.1.1! dst = 192.168.1.7! ###[ UDP ]###! sport = domain! dport = 54438! ###[ DNS ]###! qr = 1L! opcode = QUERY! \qd \! |###[ DNS Question Record ]###! | qname = 'python.org.'! | qtype = A! | qclass = IN! \an \! |###[ DNS Resource Record ]###! | rrname = 'python.org.'! | type = A! | rclass = IN! | ttl = 39777! | rdlen = 4! | rdata = '140.211.10.69'
  19. $ dig +short ! _spotify-client._tcp.spotify.com SRV! ! 10 12 4070

    AP1.spotify.com.! 10 12 4070 AP2.spotify.com.! 10 12 4070 AP3.spotify.com.! 10 12 4070 AP4.spotify.com.
  20. 14 B C D E F 3f 68 9e c1

    37 A key: bd Spotify Song ID: spotify:track:foobar some hash function