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

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

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. For Lack of a Better
    Name(server):
    DNS Explained
    Lynn Root | @roguelynn

    View full-size slide

  2. $ whoami
    • Backend Engineer at Spotify
    • Founder/leader of the PyLadies of San Francisco
    • Board Member of the Python Software Foundation

    View full-size slide

  3. tl;dr
    • What it is and why you care about DNS
    • What to do with it
    • Awesomeness I learned along the way

    View full-size slide

  4. rogue.ly/dns

    View full-size slide

  5. 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

    View full-size slide

  6. The Phonebook

    View full-size slide

  7. Domain Name System
    • Distributed storage system for Resource Records
    • Stores records in its cache or local zone file
    • Record: label, class, type, and data

    View full-size slide

  8. >>> from scapy.all import *!
    >>>!
    >>> a=sniff(filter="udp and port 53", count=10)!
    >>> a!
    !
    >>>!
    >>> 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."

    View full-size slide

  9. example.com
    vs
    example.com.

    View full-size slide

  10. ../static
    vs
    /Users/lynnroot/Dev/site/static

    View full-size slide

  11. $ cat /etc/resolv.conf
    $ curl example.com
    DNS Query: example.com.example.net
    $ curl example.com.
    DNS Query: example.com
    search example.net

    View full-size slide

  12. # router's DNS!
    $ host 75.75.75.75!
    75.75.75.75.in-addr.arpa domain name !
    pointer cdns01.comcast.net.

    View full-size slide

  13. # 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

    View full-size slide

  14. $ 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

    View full-size slide

  15. local!
    DNS
    Try one of these:!
    i.root-servers.net
    j.root-servers.net
    h.root-servers.net
    root
    net
    com
    org
    python
    python
    python
    www
    blog
    hg

    View full-size slide

  16. local!
    DNS
    Try one of these:!
    a.org.afilias-nst.org
    b.org.afilias-nst.org
    d.org.afilias-nst.org
    root
    net
    com
    org
    python
    python
    python
    www
    blog
    hg

    View full-size slide

  17. local!
    DNS
    Try one of these:!
    ns1.p11.dynect.net
    ns2.p11.dynect.net
    ns3.py11.dynect.net
    root
    net
    com
    org
    python
    python
    python
    www
    blog
    hg

    View full-size slide

  18. local!
    DNS
    I know!!
    It’s at 140.211.10.69
    root
    net
    com
    org
    python
    python
    python
    www
    blog
    hg

    View full-size slide

  19. local!
    DNS
    CNAME for!
    virt-7yvsjn.psf.osuosl.org.
    root
    net
    com
    org
    python
    python
    python
    www
    blog
    hg

    View full-size slide

  20. $ 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!

    View full-size slide

  21. $ 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.

    View full-size slide

  22. Caching
    • Query:
    • Local Cache
    • “Closer” name server
    • Authoritative name server
    • Response now cached

    View full-size slide

  23. Nerdy things I
    learned

    View full-size slide

  24. Interesting ways to
    interact with DNS

    View full-size slide

  25. $ 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

    View full-size slide

  26. $ sudo killall -INFO mDNSResponder

    View full-size slide

  27. $ 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

    View full-size slide

  28. ###[ 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!

    View full-size slide

  29. 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())

    View full-size slide

  30. ###[ 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

    View full-size slide

  31. ###[ 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'

    View full-size slide

  32. dnsmap
    finding your local DNS cache
    running your own Python DNS
    Interact with DNS

    View full-size slide

  33. Interesting ways
    to use DNS

    View full-size slide

  34. Service Discovery

    View full-size slide

  35. $ 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.

    View full-size slide


  36. search
    user
    storage
    playlist browse
    Web API
    Access
    Point
    Clients

    View full-size slide

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

    View full-size slide

  38. 14
    B
    C
    D
    E
    F
    3f
    68
    9e
    c1
    37 A
    key: bd
    Spotify Song ID:
    spotify:track:foobar
    some hash function

    View full-size slide

  39. tracks.4301.lon-tracks-a1.lon.spotify.net
    14
    B
    C
    D
    E
    F
    3f
    68
    9e
    c1
    37 A

    View full-size slide

  40. Anycast
    DANE
    Service Discovery
    DHT ring
    Use DNS

    View full-size slide

  41. tl;dr:
    DNS is hard

    View full-size slide

  42. rogue.ly/dns
    @roguelynn
    fin

    View full-size slide