Your SlideShare is downloading. ×
DNS协议与应用简介
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

DNS协议与应用简介

1,057
views

Published on


0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,057
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
16
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. DNS - DNS 协议及应用简介 Jeff.Rao chenlin.rao@renren-inc.com 人人网 May 25, 2012
  • 2. 什么是 DNS• 网络的原始时代• We are the cowboys over the WWW(wild wild west)~ BUT• 采用 IP 地址访问——真滴记不住啊有木有 ??!!• 在 NIC 的 hosts.txt 里记录主机名与 IP 地址的映射关系• NIC 互联网信息中心,不是网络适配器 ~~• 几天 NIC 更新一次,大家去下载—— 12306 抢票的感觉有木有 !!• "We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris." -- LarryWall• 大家都想要自己独立的够酷的名字空间• DNS(Domain Name System) 诞生了
  • 3. DNS 设计• 能够指明网络地址、路由等信息• 分布式存储 ( 数据正确性,失败时使用缓存 数据 )• 数据格式支持多协议传输 (FTP/EMAIL/SSH/RSYNC/SQL...)• 支持多协议访问 (TCP/UDP)
  • 4. DNS 组成• 域名空间和资源记录• 域名空间是一个树状结构• 资源记录是和名字相关的数据• 名字服务器• 服务器端程序,用来保留域名空间和资源记录• 一般只保存域名空间的一个子集,作为这个子集的权威。• 一个子集内的信息又算一个区 (zone)• 其他信息通过其他名字服务器查询• 解析器• 客户端程序,可以访问至少一个名字服务器,接收返回的 结果或者转向其他名字服务器查询
  • 5. 域名空间• 树状结构的每个结点都对应一个资源集 ( 可能为空 )• 每个结点的标记为 0-63 字节• 0 字节标记为根记录 (.)• 标记对大小写不敏感• 结点的域名由从结点到根的标记连接组成• 每个域名的结点最多不超过 127 个• 一般实现中域名长度不超过 255 字节
  • 6. DNS 查询过程• 递归查询• 要点:“请对方辩友正面回答!”• 客户端请求必须得到一个 yes or no 的响应—— NXDOMAIN 或 NOERROR• 一般情况下,电脑客户端都会使用递归查询• 迭代查询• 要点:“今人不见古时月,今月曾经照古人”• 服务器端 ( 今人 ) 返回一个可能知道该域名 ( 古 月 ) 解析结果的名字服务器 ( 古人 ) ,然后客户端 重新去那台查询
  • 7. DNS 查询过程• 举例:• 电脑发出“可递归” (RFC1034 中定义的 "recursive") 查询的请求到自己配置的 LDNS 服务器上• LDNS 检查自己的权威认证区——一般是没有的• LDNS 检查自己的非权威缓存信息• 有,返回结果,完毕• 没有,向其他 NS 查询• 配置了 forwarder 的话,只向 forwarder 的 NS 发请求,这个请求依然是“可递归”• 否则向根 DNS 发出“迭代” (RFC1034 中的大多数情况下仅仅把它叫 "non- recursive" ,偶尔叫 iterative) 请求• 全世界只有 13 个根 DNS ,所以根是不会响应递归请求的• 根 DNS 返回顶级域 (.com..net..org. 等等 )DNS 的 IP 给 LDNS• LDNS 向顶级域权威 DNS 发出“迭代”请求• 顶级域权威 DNS 返回对应一级域的权威 DNS 的 IP• LDNS 向一级域权威 DNS 发出“迭代”请求• 一级域权威 DNS 查找到对应主机名的资源记录,返回结果• LDNS 将结果返回给电脑,结束本次“递归”查询
  • 8. DNS 查询过程
  • 9. DNS 查询结构体• 前面讲的是 RFC1034 《 DOMAIN NAMES - DOMAIN CONCEPTS AND FACILITIES 》里关 于 DNS 的概念阐述。• 然后说一下 RFC1035 《 DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION 》里 关于 DNS 的实现阐述。• ftp://ftp.rfc-editor.org/in-notes/rfc1035.txt
  • 10. UDP 报文的结构• 一、报头• 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| Z | RCODE |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+• | QDCOUNT |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+• | ANCOUNT |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+• | NSCOUNT |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+• | ARCOUNT |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+• 这张图大家都用,汗 ~ 顶上一个数字表示这列是 1bit ,后面 10-15bit 分成两行写了, ……
  • 11. UDP 报文的结构• ID :占 2bytes ,客户端生成,服务器端返回时靠这个对应客户端的请求• QR(Question Response) :占 1bit , 0 代表查询, 1 代表响应• Opcode :占 4bits , 0 代表标准查询, 1 代表反向查询, 2 代表服务器状态 查询, 3-15 没啥用,过去还有个完全查询已经废弃了• AA(Authoritative Answer) :占 1bit , 1 代表权威响应, 0 代表非权威响应• TC(TrunCation) :占 1bit ,是否截断报文—— UDP 一个报文只有 512bytes• RD(Recursion Desired) :占 1bit ,客户端生成,服务器端沿袭, 1 代表启用 递归查询• RA(Recursion Available) :占 1bit ,服务器端生成, 1 代表服务器支持递归 查询• 这里我们看到实际没有关于迭代的设置,所以 RFC 中更多的把迭代叫成非递 归• Z :占 3bits ,保留字段,设 0• RCODE :占 4bits ,服务器端生成的响应返回码。 0: 正常, 1: 格式错 误, 2:DNS 错误, 3: 域名不存在, 4: 查询类型不支持, 5: 拒绝查询• QDCOUNT :占 2bytes ,查询记录的个数• ANCOUNT :占 2bytes ,回复记录的个数• NSCOUNT :占 2bytes ,权威记录的个数• ARCOUNT :占 2bytes ,额外记录的个数
  • 12. UDP 报文的结构• 二、查询• 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 |• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • 13. UDP 报文的结构• QNAME :一般就是查询的域名了。被编码成 labels 序列 ,每个 label 包括: 1byte 表示后续字符串长度 + 字符串。 最后一个 label 以 0 长度 + 空字符串表示域名结束• QNAME 可能是奇数个 btyes ,不需要填充完整• 使用 label 的原因是为了压缩报文,因为可能 一个域名查询多个 TYPE ,所以后面的重复 label 可以用 指针代替• 在目前的 DNS 实现中,对一个报文发送多个 查询的情况,要求 QNAME 必须一致,否则递归查询碰上 两个不同 QNAME 权威 NS 不一致的情况就完蛋鸟 ~• QTYPE :查询类型• QCLASS :查询协议
  • 14. UDP 报文的结构• 三、响应• 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 /• / /• +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • 15. UDP 报文的结构• RDLENGTH :占 2bytes ,表示 RDATA 的长度• RDATA :响应记录,长度与格式不定。比如最常见的话 ,如果 TYPE==A , CLASS==IN ,那么 RDATA 就是占 位 4bytes 的 ARPA 网络地址• http://www.iana.org/assignments/dns-parameters• 四、权威• 五、附加• 这两个格式和响应一样,不赘述• 关于附加 (Additional) 资源记录,在 EDNS 和 DNSSEC 中会用来存放 OPT 记录数据,分别用来支持超过 512 字 节的 UDF 包和确认是否支持 DNSSEC 。
  • 16. 资源记录 (Resource Record)• 常见 RR(TYPE) :• SOA(Start Of Authority)• 放在 zone 的最开始,有且仅有一个。用来描述负责这个 zone 的名字服务器,版本信 息等。举例 BIND 配置说明 :• @ IN SOA renren.com. root.renren.com. (• 2012051401 ; Serial• 3600 ; Refresh• 300 ; Retry• 3600000 ; Expire• 3600 ) ; Minimum• @ 代表整个 zone• renren.com. 代表本机主机名• root.renren.com. 代表本机管理员邮箱 root@renren.com• serial 代表 zone 版本,每次变动都应该自增,方便从服务器校验同步• refresh 代表从服务器同步间隔——现在一般采用主服务器 notify 的方式• expire 废弃时间——超过这个时间从依然连不上主,就自杀……• minimum 代表 zone 内记录的默认 TTL ,非权威 DNS 做缓存时不能超过这个时间
  • 17. 资源记录 (Resource Record)• 常见记录 RR(TYPE) :• A(Address)• 主机名对应的 IPv4 地址• AAAA 代表的就是 IPv6 地址,因为 IPv6 是 128 位, 4 倍于 IPv4 的 32 位,所以写 4 个 A• CNAME(Canonical NAME)• 别名• DNAME ,在 RFC2672 中定义, bind9 里已经实现,类似 CNAME 。但 CNAME 之后 对应的是具体主机,而 DNAME 用处是别名掉整个域• TXT• 返回文本信息,可能用来描述这个记录• 但其实有 HINFO 专门做主机信息描述资源记录• MX(Mail Exchanger)• 邮件服务器主机,比 A 记录多一个优先级定义,数值越低越优先
  • 18. 资源记录 (Resource Record)• MX(Mail Exchanger)• 邮件服务器主机,比 A 记录多一个优先级定义,数值越低越优先• NS(Name Server)• 本 zone 的权威名字服务器• PTR(Pointer Record)• 主要用来实现反向解析• 小提示:互联网上, 60% 的 DNS 查询是反向解析,正向只有 40%• 邮件传输等协议都依赖反解, nslookup 默认也有反解,可见附 1 脚本 测试• TSIG(Transaction Signature)• 签名加密动态更新记录
  • 19. 资源记录 (Resource Record)• 协议类 RR(class):• IN(internet)• CS(csnet)• HS(hesiod)• CH(chaos)• 虽然都没见过,不过还是要修正前面 A 记 录的说明, 32 位 IP 地址只是 IN 情况下 的;如果是 CH ,应该是 16 位八进制 Chaos 地址域名
  • 20. 资源记录 (Resource Record)• 查询类 RR(QTYPE):• AXFR(Authoritative Zone Transfer)• 请求传输整个 zone 的资源• IXFR(Increamental Zone Transfer)• AXFR 的改进版,根据 serial 数值传输变更了的资源• MAILA• 废弃了,现在都是用 MX• *• 请求所有记录• http://en.wikipedia.org/wiki/PTR_record
  • 21. DNS 应用• DNS 负载均衡• 因为 A 记录可以返回多个,所以在 LVS 没有诞生的中古时代,人们 是使用 DNS 做负载均衡的• 问题:没有健康检查,没有权重设置,没有哈希分布,没有……• 动态 DNS• 上面这些其实都不是问题。通过自定义函数返回不同的 IP 即 可。 DNS 做负载均衡真正的问题是:• TTL 时间内没办法改变客户端访问路由!• 所以最后动态 DNS 的应用场合就变成了 CDN 系统全局调度器。
  • 22. CDN 系统内的 Dynamtic DNS• 要点:根据 ip 地址段对应的 view ,返回不同的 IP 地址• 常见应用: Bind9 、 TinyDNS 、 WINMyDNS• 运维难点:收集足够准确的 IP 段信息•        F5 的 GTM 首选算法是 RTT ,但是我们注 意到: DNS 首选协议是 UDP 的,只有在 package 大于 512 字节和 zone transfer 的时候采用 TCP 。 UDP 木有 RTT 的概念 ~• 所以我们就知道了 GTM 是被动 RTT 的了。• GTM 工作原理: NS 返回一台 GTM 的 ip 给 LDNS , LDNS 请求到该 ip ; GTM 在就近路由表中查 询,没有的话,联系全网其他 GTM 共同对 LDNS 发起 TCP 请求计算 RTT ,汇总 RTT 结果更新路由表返回最近 结果。
  • 23. CDN 系统内的 Dynamtic DNS• 小设想:一般情况下,我们都说 DDNS 上收到的 localDNS 的 IP ,真的么?• 上面的协议实现部分,我们其实并没有看到 DNS 报文里有哪存放 ip 的,也 就是说: ip 还是 TCP/IP 层的事情。• 实际根据的是迭代查询的原理!• 那么我们如果在上海搭建一个 recursion yes; 的 bind ,然后在北京的 dns 上配置 forwarder 到上海,最终权威 NS 建连的 IP 是上海!• 好吧,正过来想一想:如果每个客户端上都自带一个支持迭代查询的 dnsproxy ,那么 ip 收集也就方便了。• 小提示:关于动态返回 ip ,可见附 2 脚本
  • 24. 偏门武器谱• 一本正经说这么多,最后来几个有趣的 DNS 应用:• 反垃圾邮件白名单• dig TXT 21cn.com• 天天背单词之英汉字典• echo "function j() { dig $1.jianbing.org txt +short | perl -pes/(d{1,3})/chr $1/eg; s/"//g }" >> ~/.bashrc• source !$• j apple• 翻墙• http://code.kryo.se/iodine/• http://blog.codingnow.com/2011/06/dns_tunnel.html
  • 25. • #!/human/mouth• use active;• use ME;• use Topic qw/DNS/;• my $topic = Topic::DNS->new( slide => Spork);• my $me = ME->bind([ qw/mouth ears/ ]);• while( $me->say($topic) or my $ears = $me->listen() ) {• kill STOP => $me->say($topic);• my $question = <$ears>;• say " 这个问题问得好! ";• say $ears $topic->answer($question);• kill CONT => $me->say($topic);• };• say " 真的木问题鸟 ";• $topic->close();• __END__
  • 26. 附1• use 5.014;• use Net::DNS::Nameserver;• my $ns = new Net::DNS::Nameserver( LocalPort => 5353,• ReplyHandler => &reply_handler,• Verbose => 1• );• $ns->main_loop;• sub reply_handler {• my ($qname, $qclass, $qtype, $peerhost, $query, $conn) = @_;• my ($rcode, @ans, @auth, @add);• $query->print;• if ($qtype eq "A" && $qname =~ m/foobar.com$/ ) {• my ($ttl, $rdata) = (3600, "10.1.2.3");• my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");• push @ans, $rr;• $rcode = "NOERROR";• }else{• $rcode = "NXDOMAIN";• }• return ($rcode, @ans, @auth, @add, { aa => 1 });• }
  • 27. 附2• use 5.014;• use Net::IP::Match::Regexp qw/create_iprange_regexp match_ip/;• use Stanford::DNS;• use Stanford::DNSserver;• my $hostmaster = admin.renren-inc.com;• my $hostname = 127.0.0.1;• my $soa = rr_SOA($hostname, $hostmaster, time(), 3600, 1800, 86400, 0);• my $ns = Stanford::DNSserver->new( listen_on => [ $hostname ],• debug => 1,• logfunc => sub { say },• daemon => no,);• my $host = chenlin.rao.som.renren-inc.com;• my $regexp = create_iprange_regexp({ 127.0.0.1/32 => localhost, 10.0.0.0/8 => ethernet,});• my $iplist = { $host => { ethernet => 10.10.10.10, localhost => 12.7.0.10}, };• $ns->add_static( $host, T_SOA, $soa );• $ns->add_static( $host, T_NS, rr_NS($hostmaster) );• $ns->add_dynamic( $host => &dyn_req );• $ns->answer_queries();
  • 28. 附2续• sub dyn_req {• my ($domain,$residual,$qtype,$qclass,$dm,$from) = @_;• my $ttl = 3600;• if ( $qtype == T_A ) {• my $ip = dyn_match($domain, $from);• $dm->{answer} .= dns_answer(QPTR, T_A, C_IN, $ttl, rr_A($ip));• $dm->{ancount} += 1;• return 1;• };• if ( $qtype == T_TXT ) {• if ( $domain =~ m/^(w+.w+).som.(renren-inc.com)/ ) {• $dm->{answer} .= dns_answer(QPTR, T_TXT, C_IN, $ttl, rr_TXT("Email address: $1@$2"));• $dm->{ancount} += 1;• };• };• if ( ! $dm->{ancount} ) {• $dm->{rcode} = NXDOMAIN;• };• };
  • 29. 附 2 再续• sub dyn_match {• my ( $domain, $from ) = @_;• my $area = match_ip($from, $regexp);• return ($1<<24)|($2<<16)|($3<<8)|$4 if $iplist->{"$host"}->{"$area"} =~ m/ (d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})/;• };

×