广告
返回顶部
首页 > 资讯 > 服务器 >使用golang怎么实现一个DNS服务器
  • 399
分享到

使用golang怎么实现一个DNS服务器

2023-06-14 22:06:33 399人浏览 薄情痞子
摘要

使用golang怎么实现一个DNS服务器?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Golang适合做什么golang可以做服务器端开发,但golang很适合做日志处理、

使用golang怎么实现一个DNS服务器?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Golang适合做什么

golang可以做服务器开发,但golang很适合做日志处理、数据打包、虚拟机处理、数据库代理等工作。在网络编程方面,它还广泛应用于WEB应用、api应用等领域。

简单的DNS服务器

提供一个简单的可以查询域名和反向查询的DNS服务器。

dig命令主要用来从 DNS 域名服务器查询主机地址信息。

查找www.baidu.com的ip (A记录):

命令:dig @127.0.0.1 www.baidu.com

使用golang怎么实现一个DNS服务器

根据ip查找对应域名 (PTR记录):

命令:dig @127.0.0.1 -x 220.181.38.150

使用golang怎么实现一个DNS服务器

源码

package mainimport ("fmt""net""golang.org/x/net/dns/dnsmessage")func main() {conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: 53})if err != nil {panic(err)}defer conn.Close()fmt.Println("Listing ...")for {buf := make([]byte, 512)_, addr, _ := conn.ReadFromUDP(buf)var msg dnsmessage.Messageif err := msg.Unpack(buf); err != nil {fmt.Println(err)continue}go ServerDNS(addr, conn, msg)}}// address booksvar (addressBookOfA = map[string][4]byte{"www.baidu.com.": [4]byte{220, 181, 38, 150},}addressBookOfPTR = map[string]string{"150.38.181.220.in-addr.arpa.": "www.baidu.com.",})// ServerDNS servefunc ServerDNS(addr *net.UDPAddr, conn *net.UDPConn, msg dnsmessage.Message) {// query infoif len(msg.Questions) < 1 {return}question := msg.Questions[0]var (queryTypeStr = question.Type.String()queryNameStr = question.Name.String()queryType    = question.TypequeryName, _ = dnsmessage.NewName(queryNameStr))fmt.Printf("[%s] queryName: [%s]\n", queryTypeStr, queryNameStr)// find recordvar resource dnsmessage.Resourceswitch queryType {case dnsmessage.TypeA:if rst, ok := addressBookOfA[queryNameStr]; ok {resource = NewAResource(queryName, rst)} else {fmt.Printf("not fount A record queryName: [%s] \n", queryNameStr)Response(addr, conn, msg)return}case dnsmessage.TypePTR:if rst, ok := addressBookOfPTR[queryName.String()]; ok {resource = NewPTRResource(queryName, rst)} else {fmt.Printf("not fount PTR record queryName: [%s] \n", queryNameStr)Response(addr, conn, msg)return}default:fmt.Printf("not support dns queryType: [%s] \n", queryTypeStr)return}// send responsemsg.Response = truemsg.Answers = append(msg.Answers, resource)Response(addr, conn, msg)}// Response returnfunc Response(addr *net.UDPAddr, conn *net.UDPConn, msg dnsmessage.Message) {packed, err := msg.Pack()if err != nil {fmt.Println(err)return}if _, err := conn.WriteToUDP(packed, addr); err != nil {fmt.Println(err)}}// NewAResource A recordfunc NewAResource(query dnsmessage.Name, a [4]byte) dnsmessage.Resource {return dnsmessage.Resource{Header: dnsmessage.ResourceHeader{Name:  query,Class: dnsmessage.ClassINET,TTL:   600,},Body: &dnsmessage.AResource{A: a,},}}// NewPTRResource PTR recordfunc NewPTRResource(query dnsmessage.Name, ptr string) dnsmessage.Resource {name, _ := dnsmessage.NewName(ptr)return dnsmessage.Resource{Header: dnsmessage.ResourceHeader{Name:  query,Class: dnsmessage.ClassINET,},Body: &dnsmessage.PTRResource{PTR: name,},}}

补充:Golang自定义DNS Nameserver

某些情况下我们希望程序通过自定义Nameserver去查询域名,而不希望通过操作系统给定的Nameserver,本文介绍如何在Golang中实现自定义Nameserver。

DNS解析过程

Golang中一般通过net.Resolver的LookupHost(ctx context.Context, host string) (addrs []string, err error)去实现域名解析,

解析过程如下:

检查本地hosts文件是否存在解析记录,存在即返回解析地址

不存在即根据resolv.conf中读取的nameserver发起递归查询

nameserver不断的向上级nameserver发起迭代查询

nameserver最终返回查询结果给请求者

用户可以通过修改/etc/resolv.conf来添加特定的nameserver,但某些场景下我们不希望更改系统配置。比如在kubernetes中,作为sidecar服务需要通过service去访问其他集群内服务,必须更改dnsPolicy为ClusterFirst,但这可能会影响其他容器的DNS查询效率。

自定义Nameserver

在Golang中自定义Nameserver,需要我们自己实现一个Resolver,如果是HttpClient需要自定义DialContext()

Resolver实现如下:

// 默认dialerdialer := &net.Dialer{  Timeout: 1 * time.Second,}// 定义resolverresolver := &net.Resolver{ Dial: func(ctx context.Context, network, address string) (net.Conn, error) {  return dialer.DialContext(ctx, "tcp", nameserver) // 通过tcp请求nameserver解析域名 },}

自定义Dialer如下:

type Dialer struct { dialer     *net.Dialer resolver   *net.Resolver nameserver string}// NewDialer create a Dialer with user's nameserver.func NewDialer(dialer *net.Dialer, nameserver string) (*Dialer, error) { conn, err := dialer.Dial("tcp", nameserver) if err != nil {  return nil, err } defer conn.Close() return &Dialer{  dialer: dialer,  resolver: &net.Resolver{   Dial: func(ctx context.Context, network, address string) (net.Conn, error) {    return dialer.DialContext(ctx, "tcp", nameserver)   },  },  nameserver: nameserver, // 用户设置的nameserver }, nil}// DialContext connects to the address on the named network using// the provided context.func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { host, port, err := net.SplitHostPort(address) if err != nil {  return nil, err } ips, err := d.resolver.LookupHost(ctx, host) // 通过自定义nameserver查询域名 for _, ip := range ips {    // 创建链接  conn, err := d.dialer.DialContext(ctx, network, ip+":"+port)  if err == nil {   return conn, nil  } } return d.dialer.DialContext(ctx, network, address)}

httpClient中自定义DialContext()如下:

ndialer, _ := NewDialer(dialer, nameserver)client := &http.Client{  Transport: &http.Transport{    DialContext:         ndialer.DialContext,    TLSHandshakeTimeout: 10 * time.Second,  },  Timeout: timeout,}

关于使用golang怎么实现一个DNS服务器问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网服务器频道了解更多相关知识。

--结束END--

本文标题: 使用golang怎么实现一个DNS服务器

本文链接: https://www.lsjlt.com/news/275647.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用golang怎么实现一个DNS服务器
    使用golang怎么实现一个DNS服务器?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。golang适合做什么golang可以做服务器端开发,但golang很适合做日志处理、...
    99+
    2023-06-14
  • Golang中怎么实现一个HTTP代理服务器
    本篇文章给大家分享的是有关Golang中怎么实现一个HTTP代理服务器,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。定义请求对象,接收客户端请求处理请求,把处理结果返回给客户端...
    99+
    2023-06-03
  • 使用golang怎么实现一个布谷鸟过滤器
    本文章向大家介绍使用golang怎么实现一个布谷鸟过滤器的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。golang适合做什么golang可以做服务器端开发,但golang很适合做日志处理、数据打包、虚拟机处理、...
    99+
    2023-06-06
  • golang DNS服务器的简单实现操作
    简单的DNS服务器 提供一个简单的可以查询域名和反向查询的DNS服务器。 dig命令主要用来从 DNS 域名服务器查询主机地址信息。 查找www.baidu.com的ip (A记录)...
    99+
    2022-11-12
  • Linux怎么搭建一个golang服务器
    这篇文章主要介绍了Linux怎么搭建一个golang服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Linux怎么搭建一个golang服务器文章都会有所收获,下面我们一起来看看吧。一、预备知识在开始之前,你...
    99+
    2023-07-05
  • 怎么使用dns服务器实现负载均衡
    要使用DNS服务器实现负载均衡,可以按照以下步骤操作:1. 购买或设置多个服务器:首先需要购买或设置多台服务器,并利用负载均衡软件或...
    99+
    2023-09-07
    负载均衡 dns服务器 服务器
  • 怎么实现一个Http服务器
    这期内容当中小编将会给大家带来有关怎么实现一个Http服务器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。说到http协议和http请求,很多人都知道,但是他们真的“知道”吗我面试过很多求职者,一说到ht...
    99+
    2023-06-04
  • 使用node-images怎么实现一个图片服务器
    这篇文章给大家介绍使用node-images怎么实现一个图片服务器,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Edit:2016-5-11 修正了代码里面一些明显的错误,并发布在 a...
    99+
    2022-10-19
  • 使用golang怎么实现一个京东支付功能
    这篇文章主要介绍了使用golang怎么实现一个京东支付功能,此处通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考价值,需要的朋友可以参考下:什么是golanggolang 是Google开发的一种静态强类型、编译型、并发型...
    99+
    2023-06-06
  • golang 实现一个restful微服务的操作
    如何用net/http构建一个简单的web服务 Golang提供了简洁的方法来构建web服务 package main import ( "net/http" ) ...
    99+
    2022-11-12
  • Golang中怎么实现一个工作池
    本篇文章为大家展示了Golang中怎么实现一个工作池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。worker pool简介worker pool其实就是线程池th...
    99+
    2022-10-18
  • 使用golang怎么实现一个比特币交易功能
    使用golang怎么实现一个比特币交易功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。比特币交易交易(transaction)是比特币的核心所在,而区块链唯一的目的,也正...
    99+
    2023-06-15
  • Golang怎么使用channel实现一个优雅退出功能
    这篇文章主要介绍了Golang怎么使用channel实现一个优雅退出功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang怎么使用channel实现一个优雅退出功能文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-05
  • 使用golang怎么实现一个登录验证码功能
    这篇文章将为大家详细讲解有关使用golang怎么实现一个登录验证码功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。golang适合做什么golang可以做服务器端开发,但golang很适合...
    99+
    2023-06-06
  • ASP.NETCore中怎么实现一个Kestrel服务器
    这篇文章给大家介绍ASP.NETCore中怎么实现一个Kestrel服务器,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Kestrel Web服务器的概述Kestrel被认为是较新的ASP.NET应用程序的首选Web服...
    99+
    2023-06-19
  • Node.js中怎么使用原生API实现一个Web服务器
    这期内容当中小编将会给大家带来有关Node.js中怎么使用原生API实现一个Web服务器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Hello World要搭建一个简单...
    99+
    2022-10-19
  • Golang怎么优雅的终止一个服务
    今天小编给大家分享一下Golang怎么优雅的终止一个服务的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言采用常规方式启动一...
    99+
    2023-06-29
  • 怎么使用Dnsmasq搭建DNS服务器
    这篇文章主要介绍“怎么使用Dnsmasq搭建DNS服务器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Dnsmasq搭建DNS服务器”文章能帮助大家解决问题。一、Dnsmasq安装安装并启动...
    99+
    2023-06-28
  • ASP.NET中怎么实现一个服务器控件
    ASP.NET中怎么实现一个服务器控件,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。ASP.NET组件设计之ASP.NET服务器控件1、用户控件类似page,基本上不需要编程,...
    99+
    2023-06-18
  • Linux中怎么实现一个代理服务器
    本篇文章为大家展示了Linux中怎么实现一个代理服务器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。  1.安装Linux,不管是在图形,还是文体下都可以,选择最小安装,在安装的时候可以先配置一下外...
    99+
    2023-06-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作