DNS 域名解析系统,可以根据域名查出对应的IP

层级

  • 根域名: .root 或者 .,通常是省略的
  • 顶级域名:如.com .cn
  • 次级域名:如 baidu.com 里的baidu,这个是用户可以进行注册购买的
  • 主机域名:如 baike.baidu.com里的baike,这个是用户可分配的

    DNS解析过程

  1. 先查找本地的DNS缓存(自己的电脑上)
  2. 查看本地的hosts文件有没有相应的映射记录
  3. 向本地DNS服务器(网络接入服务器商)发送请求进行查询,本地DNS收到请求后,会先查自己的缓存记录,查到了就返回,没查到,本地DNS服务器就会向根域名服务器发起查询,
  4. 根域名服务器收到请求后,查看到.com的域名,就会提供.comDNS服务器的地址,让本地DNS服务器去查询
  5. 然后.comDNS服务器会提供.163.com的DNS服务器,让本地DNS服务器去查
  6. 163.com收到请求,确认是自己的域名后,会返回www.163.com的地址
  7. 本地DNS服务器收到后,将DNS地址返回,并记录到缓存

总结:

  1. 从”根域名服务器”查到”顶级域名服务器”的NS记录和A记录(IP地址)
  2. 从”顶级域名服务器”查到”次级域名服务器”的NS记录和A记录(IP地址)
  3. 从”次级域名服务器”查出”主机名”的IP地址

image.png

DNS的缓存时间

在配置DNS解析时,会有一个TTL参数,就是这个缓存可以存活多长时间,过了这个时间,本地DNS就会删除这条记录

DNS的记录类型

  • A:地址记录(Address),返回域名指向的IPv4地址。
  • AAAA: 将域名指向一个IPv6地址
  • NS:域名服务器记录(Name Server),返回保存下一级域名信息的服务器地址。该记录只能设置为域名,不能设置为IP地址。
  • MX邮件记录(Mail eXchange),返回接收电子邮件的服务器地址。
  • CNAME:规范名称记录(Canonical Name),返回另一个域名,即当前查询的域名是另一个域名的跳转
  • PTR逆向查询记录(Pointer Record),只用于从IP地址查询域名

    DNS报文结构

    image.png

  • 事务 ID:DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。

  • 标志:DNS 报文中的标志字段。
  • 问题计数:DNS 查询请求的数目。
  • 回答资源记录数:DNS 响应的数目。
  • 权威名称服务器计数:权威名称服务器的数目。
  • 附加资源记录数:额外的记录数目(权威名称服务器对应 IP 地址的数目)。

    DNS是应用层协议,传输层使用的协议是UDP,端口53

DNS劫持与http劫持

如果访问www.baidu.com,却返回www.google.com的ip,这就是DNS劫持

如果访问www.baidu.com,却多了一些广告弹窗,这就是http劫持

DNS劫持产生的方法

  1. 本机DNS劫持,通过某些手段给用户计算机染上病毒,恶意修改本地DNS解析/缓存等
  2. 路由DNS劫持,修改路由器的默认配置
  3. 攻击DNS服务器,对DNS进行DDOS攻击,使服务器宕机,

    工具

  4. dig
    ```bash

    追踪DNS解析的详细过程

    $ dig +trace www.163.com

只看结果

$ dig +short www.163.com

指定DNS查询

$ dig @114.114.114.114 www.163.com

查看指定的记录类型

$ dig cname www.163.com

  1. 2. host
  2. ```bash
  3. $ # dig的简化版本,返回当前请求域名的各种记录
  4. $ host www.163.com
  1. whois
  2. nslookup

    手动清理本地DNS缓存

    ```bash

    使用NSCD的DNS缓存

    $ /etc/init.d/nscd restart

服务器或者路由器使用DNSMASQ

$ dnsmasq restart

  1. <a name="f98HC"></a>
  2. # FQDN
  3. 首先我们需要了解一个概念`FQDN(Fully qualified domain name)`即完整域名。一般来说如果一个域名以`.`结束,就表示一个完整域名。比如`www.abc.xyz.`就是一个`FQDN`,而`www.abc.xyz`则不是`FQDN`。
  4. <a name="f2i3x"></a>
  5. # K8S中操作
  6. <a name="fOS5M"></a>
  7. ## 添加host记录
  8. ```bash
  9. ...
  10. hostAliases: # 在spec下的hostAliases 处添加
  11. - ip: "172.31.6.56"
  12. hostnames:
  13. - "bridge4sms"
  14. ...

而在docker中

  1. --add-host test1.a:1.2.3.4

k8s的DNS策略

  • defaultPod从运行所在的节点继承名称解析配置
  • ClusterFirst 与配置的集群域后缀不匹配任何的DNS查询,都将转发到节点继承上游服务器。
  • ClusterFirstWithHostNet 对于以hostNetwork 方式运行的Pod,应显示设置其DNS策略为这个
  • None 允许Pod忽略k8s环境中的DNS设置,pod会使用dnsConfig字段所提供的DNS解析

    k8s默认使用clusterFirst,域名解析优先使用集群DNS,如果k8s的DNS解析失败,会转发到宿主机的DNS进行解析

k8s的resolv.conf

  1. nameserver 10.96.0.10
  2. search jplat.svc.cluster.local svc.cluster.local cluster.local localhost
  3. options ndots:5
  • nameserver即为k8s集群中kube-dnsServiceCLUSTER-IP,该集群中容器的nameserver均为kube-dns的ip。
  • 如果我们的pod使用的是默认的DNS策略,即ClusterFirst,那么如果一个域名是FQDN,那么这个域名会被转发给DNS服务器进行解析。如果域名不是FQDN,那么这个域名会到search搜索解析。比如访问abc.xyz这个域名,因为它并不是一个FQDN,所以它会和search域中的值进行组合而变成一个FQDN,以上文的resolv.conf为例,这域名会这样组合:

    1. abx.xyz.jplat.svc.cluster.local.
    2. abc.xyz.svc.cluster.local.
    3. abc.xyz.cluster.local.
    4. ...
  • ndots是用来表示一个域名中.的个数在不小于该值的情况下会被认为是一个FQDN。简单说这个属性用来判断一个不是以.结束的域名在什么条件下会被认定为是一个FQDN。还是通过我们另一个pod的resolv.conf为例,如下:

    1. nameserver 10.96.0.10
    2. search oms-dev.svc.cluster.local svc.cluster.local cluster.local localhost
    3. options ndots:2 edns0

    在这个resolv.confndots为2,也就是说如果一个域名中.的数量大于等于2,即使域名不是以.结尾,也会被认定为是一个FQDN。比如:域名是abc.xyz.xxx这个域名就是FQDN,而abc.xyz则不是FQDN

知识链接

  1. 超全总结!关于 DNS 看这一篇就够了
  2. 从一次k8s容器内域名解析失败了解k8s的DNS策略