golang具有内置go解析器以及基于cgo的系统解析器两种DNS解析方式

其中在Linux下默认是go内置go解析器

DNS是什么?有什么?做什么?

域名系统( DNS)是一种用于 TCP/IP 应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息

从应用的角度上看,对 DNS的访问是通过一个地址解析器( resolver )来完成的。解析器并不像 TCP/IP 协议那样是操作系统的内核。

当nameResolver发出查询请求,并且返回响应中的TC(删减标准)为1时,意味着响应长度超过了512字节,而仅返回前512字节。那么在这种情况下,nameResolver通常使用TCP重发原来的查询请求(TCP允许响应超过512字节)。

不过多数还是UDP更多,这也意味着对于DNS客户程序,一个好的重传和超时程序显得更重要了

报文格式

该报文由12bytes首部和4个长度可变字段组成

  • 标识:由client设置并由server返回结果,用以确认响应和查询是否匹配

  • 标志:

    • OR: 0代表查询,1代表响应报文

    • opcode: 0标准查询,1方向查询,2服务器状态请求

    • AA: 标识授权回答

    • TC: 可截断的。使用UDP时,表示应答总长度超过512字节,只返回前512字节

    • RD: 期望递归。

      该比特能在一个查询中设置 ,并在响应中返回。这个标志告诉名字服务器必须处理这个查询,也称为一个递归查询。如 果该位为 0,且被请求的名字服务器没有一个授权回答,它就返回一个能解答该查询的 其他名字服务器列表,这称为迭代查询

    • RA: 可用递归。nameServer支持递归查询

    • rcode: 返回码字段。通常为0(没有差错)和3(名字差错,表示查询域名不存在)

  • 问题数、资源记录数、授权资源记录数和额外资源记录数分别对应最后 4 个可变长字段中包含的条目数

    对于查询报文,问题数通常是 1,而其他 3 项均为 0;对于应答报文,回答数至少为 1,剩下的两项可以是 0 或非 0;

  • 查询问题:

    • 查询名: 要查找的DNS名,本质为分段带长度的字符序列。

      如baidu.com.就表示为字符序列5 b a i d u 3 c o m 0

    • 查询类型: 对应资源记录类型。比如A记录,记为1

    • 查询类:通常为1,指互联网地址(IP)

  • 回答:

    域名是记录中资源数据对应的名字。它的格式和前面介绍的查询名字段格式(图 相同。

    类型说明 R R 的类型码。它的值和前面介绍的查询类型值是一样的。类通常为Internet数据。

    生存时间字段是客户程序保留该资源记录的秒数。资源记录通常的生存时间值为 2天。

    资源数据长度说明资源数据的数量。该数据的格式依赖于类型字段的值。对于类型 1(A 记录)资源数据是 4 字节的 I P 地址。

资源记录

  • A: 32bit二进制数,记录ipv4地址
  • AAAA: ipv6地址
  • cname: 表示规范名字(canonical name)。用来表示一个域名

go dns流程

  1. 读取/etc/resolv.conf
  2. 判断解析的network类型。默认ipv4、ipv6都解析,若指定了ip类型,则只解析该类型。
  3. 根据/etc/resolv.conf中single-request和single-request-reopen参数,决定是否串行或者并行请求ip类型
  4. 遍历nameserver以及解析ip类型,以获取cname、ip信息

cgo vs go

cgo调用的是getaddrinfo。

int getaddrinfo(const char *restrict node,const char *restrict service,const struct addrinfo *restrict hints,struct addrinfo **restrict res);

相比而言,go的好处在于在堵塞情况下,只会消耗一个协程,而cgo则会堵塞系统线程

DNS相关配置介绍

/etc/resolv.conf文件介绍

resolv.conf用于设置DNS服务器的ip地址以及DNS域名,还包含主机域名搜索顺序

主要有以下参数

  • nameserver: 定义DNS服务器IP地址
  • domain: 定义本地域名
  • search: 定义域名搜索列表。指明域名查询顺序,当没有domain会用search
  • sortlist: 对返回域名进行排序

以及可选参数

  • ndots: 若请求域名参数点的个数比ndots小,则会按照配置的search内容,依次添加相应后缀知道获取域名解析后的地址

比如请求www.baidu.com时,因为www.baidu.com有两个点小于配置的3个点,那就会

nameserver 169.254.20.10
nameserver 172.16.0.10
search meipian-test.svc.cluster.local svc.cluster.local cluster.local
options ndots:3
解析域名 查询类型 dns server
www.baidu.com.meipian-test.svc.cluster.local. A 169.254.20.10
www.baidu.com.meipian-test.svc.cluster.local. A 172.16.0.10
www.baidu.com.meipian-test.svc.cluster.local. AAAA 169.254.20.10
www.baidu.com.meipian-test.svc.cluster.local. AAAA 172.16.0.10
www.baidu.com.svc.cluster.local. A 169.254.20.10
www.baidu.com.svc.cluster.local. A 172.16.0.10
www.baidu.com.svc.cluster.local. AAAA 169.254.20.10
www.baidu.com.svc.cluster.local. AAAA 172.16.0.10
www.baidu.com.cluster.local. A 169.254.20.10
www.baidu.com.cluster.local. A 172.16.0.10
www.baidu.com.cluster.local. AAAA 169.254.20.10
www.baidu.com.cluster.local. AAAA 172.16.0.10
www.baidu.com. A 169.254.20.10
www.baidu.com. A 172.16.0.10
www.baidu.com. AAAA 169.254.20.10
www.baidu.com. AAAA 172.16.0.10

看看上面一长串,我们不禁要问为什么需要这样的拼接,并且最后的为什么多出来一个点

这又要引出一个新概念——FQDN(fully qualified domain name)。FQDN是完整域名,以.结束表示是FQDN

对于FQDN系统会直接查询DNS server

而对于非FQDN则会用到ndots结合search组合为FQDN

go内置DNS默认解析ipv6

由于现在很多域名都不支持ipv6,并且对于不支持的处理策略并不一致。

比如使用114.114.114.114 DNS服务器查询baidu ipv6会得到noerror,说是查询成功,可是却只有soa

再比如同样使用114.114.114.114 DNS服务器查询oauth-login.cloud.huawei.com ipv6,却得到servfail,并且查询时间实在感人。所以很多场景禁用ipv6解析还是很有意义

在go1.17之后,我们可以通过指定网络类型,达到查询host ip时禁用ipv6目的。

r:=net.Resolver{PreferGo: true}
ip, err := r.LookupIP(context.Background(), "ip4", host)
if err != nil {t.Fatal(err)
}
fmt.Println(ip)

DNS攻击

DDOS

分布式拒绝服务攻击(distributed denial-of-service, DDoS)是一种恶意攻击,目的是通过大量的Internet流量,使目标服务器或其周围的基础设施无法承受,从而破坏目标服务器、服务或网络的正常流量。

DDoS攻击是通过利用多个被破坏的计算机系统作为攻击流量的来源来实现的。被利用的机器可以包括计算机和其他联网资源,如物联网设备。

从高级别上看,DDoS攻击就像高速公路上突发的交通堵塞,使正常的交通无法到达目的地。

攻击者利用僵尸网络创建不同端口,在同一时间段向受害者域名服务器发送海量DNS请求。

为了应对,我们可以限制攻击者ip

ip欺骗

IP 欺骗是指创建源地址经过修改的 Internet 协议 (IP) 数据包,目的要么是隐藏发送方的身份,要么是冒充其他计算机系统,或者两者兼具。恶意用户往往采用这项技术对目标设备或周边基础设施发动 DDoS 攻击

DNS默认依赖UDP,不过由于UDP没有像TCP的握手过程,这使得ip欺骗变的更加容易。

并且对于很多基于UDP应用程序可能会被愚弄以使用更大UDP响应来回复小UDP查询,这将导致更大带宽浪费。这种现象称之为放大效应。

应对ip欺骗可以通过

  • DNS缓存:通过缓存吸收DNS流量。不过值得注意的是攻击者也可能利用这点,在缓存中添加大量错误ip地址
  • 入口过滤:在网络边缘设备检查传入ip数据包是否是其源头

DNS隧道

DNS隧道通过DNS解析器在攻击者和目标之间创建隐藏连接,可绕过防火墙,用于实施数据泄露等攻击。在大多数情况下,DNS隧道需要借助能够连接外网的受感染系统作为跳板,来访问具有网络访问权限的内部DNS服务器。

DNS挟持

在 DNS 劫持中,攻击者将查询重定向到其他域名服务器。这可通过恶意软件或未经授权的 DNS 服务器修改来实现。尽管其结果与 DNS 欺骗的结果相似,但这是一种截然不同的攻击,因为其目标是域名服务器上网站的 DNS 记录,而不是解析器的高速缓存。

Ref

  1. https://studygolang.com/topics/15021
  2. https://blog.csdn.net/mybelief321/article/details/10049429
  3. https://ieevee.com/tech/2019/06/22/ndots.html
  4. 《TCP/IP 详解》
  5. https://zhengyinyong.com/post/go-dns-library/
  6. https://juejin.cn/post/6948469896007122974
  7. https://www.infoq.cn/article/99agzwzlewtvqjvgrtth
  8. https://www.cloudflare.com/en-gb/learning/ddos/what-is-a-ddos-attack
  9. https://www.cloudflare.com/zh-cn/learning/ddos/glossary/ip-spoofing/
  10. https://security.stackexchange.com/questions/155082/how-realistic-is-it-to-spoof-a-specific-udp-ip-address

Golang DNS 随便写写相关推荐

  1. Python 新手杂谈(随便写写)

    从接触Python开始,也过去了半年多了吧,个人觉得Python真是一门很好的语言. 为什么呢? 对于我这种没有正式接触过编程世界的我来说,之前看到都是符号和英文程序的我是崩溃的,可以说是完全看不懂, ...

  2. 随便写写2014创业记(二)

    这篇文章既然已经开始写了,那就坚持写完吧.可能文章中有很多不符合各位胃口的,请暂且不要去理会其是不是做错了还是做对了,经过这么长的时间我明白一个很简单的道理,只要你做事情就肯定会有错的地方或者不如意的 ...

  3. 我就随便写写,你也随便看看。

    我就随便写写 在这个百无聊赖的下午随便写写 来北京2个多月了,上班也有1个半月了 工作没有事可做,没人教,也不想学,越来越懒,还是一直都很懒. 我没玩微博,可是却把我的新浪微博首页设置在我的收藏夹里. ...

  4. 【给自己看的笔记,随便写写】如何去调整游戏数值(新手为例)

    [随便写写]最近几天事情比较多,也没有多少闲工夫来试玩其他游戏写评测之类的.本篇仅仅因为忽然想到这个随便写写,大家如果有缘点开就随便看看就好了,当然有更好的思路可以指点一二. [前因]为了简化新手期知 ...

  5. 【程序人生】不想学习,随便写写

    这篇博客,随便写写,也懒得整理格式,看到的人随便看看~ 一个月没写博客了,不是因为没有东西可以写,而是大四了,随之而来的是扑面而来的焦虑感. 大一大二幻想着出国,一开始家里也说不上同意说不上反对,后来 ...

  6. go (golang) DNS域名解析实现

    之前使用过GO语言写了一个实时图片下载程序,主要考虑到GO语言的DNS解析对协程支持友好, 即 DNS解析时不会阻塞执行线程,只会阻塞当前协程,顺便研究了一下GO的net.LookupHost/Res ...

  7. 随便写写,都是我从网上收集的东西!

    linux系统分区方案: 根分区40-50g /opt 大于60g /home 大于20g /var 大于20g /media  /run   /tmp   挂在tmpfs /************ ...

  8. [随便写写]Android基础教程

    想来想去的,不知道写什么好.最近没怎么做过Demo.所以写写最最基本的.不错,就是环境搭建.其实我觉得搭建环境这种你必须亲手完成.不要叫人帮你弄甚至从头到尾帮你弄.这种事其实很不好的.对吧.废话完毕, ...

  9. 毕设过程中的学习 随便写写~

    1.sql语句的执行(并非简单的sql语句就可以,见注释) SqlConnection Conn=new SqlConnection(data.strconn); Conn.Open(); strin ...

最新文章

  1. mysql alert on delete cascade_如何在mysql中删除级联使用?(How do I use on delete cascade in mysql?)...
  2. [JavaWeb-MySQL]多表查询(内连接,外连接,子查询)
  3. 在Jersey测试中模拟SecurityContext
  4. mysql在可视化软件navicat中如何解决中文乱码问题
  5. django 允许跨域请求
  6. 两个not exists_分享两个冷门但又超实用的 Vim 使用技巧!
  7. 【2015.9.1】微信开放平台
  8. 利用WinForm 更好的实现Web安装程序的更多功能
  9. python获取灰度图边界
  10. NetBeans在Apache基金会取得的进展
  11. 面象对象与面象过程内存分区
  12. 感受MapXTreme2004
  13. (8)seetaface6 JNI之人脸相似度1:1(包含戴口罩人脸相似度)计算
  14. Orcad CIS本地库添加器件
  15. 用JAVA写一个小游戏程序难不难?具体步骤怎么操作?
  16. 初入steam避坑请进
  17. 读后感之悟道-一位20年IT高管的职场心得
  18. Python数值运算操作符
  19. 三步骤快速开发 iOS资讯类App
  20. 为什么很多人不喜欢做程序员?甚至讨厌程序员?

热门文章

  1. RobotFramework学习笔记二:遇到Frame框架
  2. java ppt控件_Java版PPT操作控件Spire.Presentation v2.12.2新版来袭!支持获取具有超链接的目标幻灯片...
  3. NDIS和Rndis区别
  4. 往事的回忆:木星如何抓获小彗星
  5. win10系统如何添加和切换多个桌面?
  6. 基金A类和C类的科普贴
  7. java作业分工_团队作业(三):确定分工
  8. 《操作系统》学习笔记|6.6外存空间管理
  9. 平方度用计算机打出来,角度计算器-角度计算器
  10. python练习题——文件的打开、读取、复写