DNS-over-HTTPS(DoH)详解与C/C++代码实现

这篇具有很好参考价值的文章主要介绍了DNS-over-HTTPS(DoH)详解与C/C++代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

HTTPS上的DNS(DoH)是一种相对较新的协议,通过超文本传输协议安全加密会话传递DNS查询来加密域名系统流量。DoH试图通过隐藏DNS查询来改善在线隐私。

DoH的工作原理与DNS类似,但HTTPS会话保留请求并最大限度地减少查询期间交换的信息。网络浏览器,如Mozilla的Firefox、微软的Edge和谷歌的Chrome,都具有使用加密DoH的功能,目的是提高用户的数据隐私和安全性。

什么是DNS

域名系统,或称DNS,是一种在互联网上将域名转换为IP地址的协议。当您在浏览器中键入域名时,域名系统(DNS)会将其转换为IP地址。

DNS系统允许您通过记住网站和其他在线服务使用的域名而不是数字互联网协议地址来连接网站和其他联机服务。

HTTPS协议

HTTPS是一种用于保护互联网通信安全的协议。HTTPS由网景公司开发,并于1994年引入,作为对HTTP(超文本传输协议)的增强。

它提供端到端的数据加密,这意味着当你访问网站时,没有人可以看到你的个人信息。加密连接可确保密码和信用卡号等敏感数据的安全。

既然我们都知道HTTPS的作用,让我们更深入地了解一下为什么这是一件如此重要的事情。

如何在浏览器中启用DoH?

大多数流行的浏览器默认情况下都启用了DoH,但您可以按照以下步骤进行检查。

转到“设置”

然后是“隐私与安全”

在“隐私和安全”部分,将有“安全”

向下滚动,您将看到“使用安全DNS”

从那里,选择“使用自定义”而不是“使用您当前的服务提供商”,因为大多数ISP的解析器速度很慢,有时会停机。

选择您选择的DNS解析程序,您可以选择Cloudflare DNS、Google DNS、OpenDNS或CleanBrowsing。
doh协议,C/C++,https,c语言,c++,DNS over HTTPS,dohdoh协议,C/C++,https,c语言,c++,DNS over HTTPS,doh

DoH是如何工作

为了了解DoH是如何工作的,有必要首先了解常规DNS是如何工作。网站托管在网络服务器上,每个网络服务器或服务器上的网站都有一个相关的互联网协议(IP)地址。浏览器要访问网站,必须首先确定网站的IP地址,这就是DNS的重要位置。DNS服务器的工作是转换主机名,例如https://whatis.com,转换为IP地址。

当用户在浏览器中输入主机名时,请求会被发送到递归解析程序,然后递归解析程序会将请求传递到根名称服务器——如果解析程序还不知道如何解析查询的话。根名称服务器处理顶级域,如.com、.org和.edu。然后根服务器将相应的顶级DNS服务器的地址发送回解析程序。例如,如果用户试图访问.com网站,则根DNS将提供与.com顶级域服务器相关联的地址。

此时,解析程序将其请求发送到顶级域服务器,顶级域服务器使用处理请求域的DNS服务器的IP地址进行响应。然后,解析程序将请求发送到此DNS服务器,该服务器返回用户试图访问的网站的IP地址。然后,浏览器能够向该IP地址发出HTTP或HTTPS请求,以访问用户请求的网站。在某些情况下,缓存使这个过程成为快捷方式,但这是正常DNS工作的本质。

DOH的工作方式基本相同,但有两个关键区别。第一个也是最明显的区别是,DNS请求被封装在HTTPS会话中,而不是像过去那样由浏览器发出HTTP请求。与HTTPS网络流量一样,这些请求是通过端口443发送的。值得注意的是,为了让DoH工作,浏览器和DNS服务器都必须支持DoH。

标准DNS和DoH之间的另一个关键区别是,DoH寻求最小化在各种DNS查询期间传输的信息。它只传输完成名称解析过程中当前步骤所需的域名部分,而不是发送用户浏览器试图解析的完整域名。例如,DNS根不需要知道用户的浏览器正在尝试解析 https://whatis.com.它只需要知道浏览器正在尝试解析.com地址。

使用DOH的好处

最主要就是防止“中间人”攻击。

HTTPS上的DNS是一种新的协议,它用加密和验证的版本取代了传统的DNS协议。这一变化的结果是,您的浏览将更加安全和私密。

DoH使用HTTPS,这意味着您的设备和DNS服务器之间的所有通信都是端到端加密的,这意味着您在没有从通信通道两侧检测到的情况下,任何第三方都无法看到您在网上做什么或篡改任何来回发送的数据。

这可以防止“中间人”攻击拦截和更改您与网站之间发送的敏感数据。

增强隐私

默认情况下,当您访问网站时,浏览器会将有关网站的信息发送到DNS服务器。您的ISP使用这些信息来确定将您发送到哪个服务器。

使用HTTPS上的DNS,您的浏览器将直接向DoH服务器发送对网站地址的请求,而不是通过您的ISP。这意味着您的ISP将不会掌握您正在访问的网站的任何信息,也不能将这些数据出售给广告商或其他第三方。

DNS Over TLS(DoT)和DNS Over HTTPS(DoH)之间的区别是什么?

DoT与DoH的相似之处在于,它还使用TLS的安全传输层。这将在您和DNS服务器之间创建加密连接。

然而,DoH对通过端口443(与常规网络流量使用的端口相同)发出的网站请求进行加密。而DoT仅使用端口853。

从隐私角度来看,DoH是更好的选择。由于端口443通常由网络管理员解除阻止。而使用DoT使用非标准端口,这使得它不太可能在公共网络或工作场所访问。

DNS-over-HTTPS(DoH)C/C++代码实现

...
typedef enum {
  DOH_OK,
  DOH_DNS_BAD_LABEL,    /* 1 */
  DOH_DNS_OUT_OF_RANGE, /* 2 */
  DOH_DNS_CNAME_LOOP,   /* 3 */
  DOH_TOO_SMALL_BUFFER, /* 4 */
  DOH_OUT_OF_MEM,       /* 5 */
  DOH_DNS_RDATA_LEN,    /* 6 */
  DOH_DNS_MALFORMAT,    /* 7 - wrong size or bad ID */
  DOH_DNS_BAD_RCODE,    /* 8 - no such name */
  DOH_DNS_UNEXPECTED_TYPE,  /* 9 */
  DOH_DNS_UNEXPECTED_CLASS, /* 10 */
  DOH_NO_CONTENT            /* 11 */
} DOHcode;

struct dnsentry {
  unsigned int ttl;
  int numv4;
  unsigned int v4addr[MAX_ADDR];
  int numv6;
  struct addr6 v6addr[MAX_ADDR];
  int numcname;
  struct cnamestore cname[MAX_ADDR];
  int numtxt;
  struct txtstore txt[MAX_ADDR];
};

static const char *type2name(int dnstype)
{
  switch(dnstype) {
  case DNS_TYPE_A: return "A";
  case DNS_TYPE_NS: return "NS";
  case DNS_TYPE_CNAME: return "CNAME";
  case DNS_TYPE_TXT: return "TXT";
  case DNS_TYPE_AAAA: return "AAAA";
  }
  return "Unknown";
}

...

static size_t doh_encode(const char *host,
                         int dnstype,
                         unsigned char *dnsp, /* buffer */
                         size_t len) /* buffer size */
{
...

  *dnsp++ = 0; /* 16 bit id */
  *dnsp++ = 0;
  *dnsp++ = 0x01; /* |QR|   Opcode  |AA|TC|RD| Set the RD bit */
  *dnsp++ = '\0'; /* |RA|   Z    |   RCODE   |                */
  *dnsp++ = '\0';
  *dnsp++ = 1;    /* QDCOUNT (number of entries in the question section) */
  *dnsp++ = '\0';
  *dnsp++ = '\0'; /* ANCOUNT */
  *dnsp++ = '\0';
  *dnsp++ = '\0'; /* NSCOUNT */
  *dnsp++ = '\0';
  *dnsp++ = '\0'; /* ARCOUNT */

...
  do 
  {
    char *dot = strchr(hostp, '.');
    size_t labellen;
    bool found = false;
    if(dot) 
    {
      found = true;
      labellen = dot - hostp;
    }
    else
      labellen = strlen(hostp);
    if(labellen > 63)
      return DOH_DNS_BAD_LABEL;
      
    *dnsp++ = (unsigned char)labellen;
    memcpy(dnsp, hostp, labellen);
    dnsp += labellen;
    hostp += labellen + 1;
    if(!found) 
    {
      *dnsp++ = 0; 
      break;
    }
  } while(1);

...
  return dnsp - orig;
}

static DOHcode store_cname(unsigned char *doh,
                           size_t dohlen,
                           unsigned int index,
                           struct dnsentry *d)
{
  struct cnamestore *c = &d->cname[d->numcname++];
  unsigned int loop = 128; /* 一个有效的DNS名称永远不会循环这么多 */
  unsigned char length;
  do 
  {
    if(index >= dohlen)
      return DOH_DNS_OUT_OF_RANGE;
    length = doh[index];
    if((length & 0xc0) == 0xc0) 
    {
      unsigned short newpos;
      /* 名称指针,获取新的偏移量(14位) */
      if((index + 1) >= dohlen)
        return DOH_DNS_OUT_OF_RANGE;
      /* 移动到新索引  */
      newpos = (length & 0x3f) << 8 | doh[index+1];
      index = newpos;
      continue;
    }
    else if(length & 0xc0)
      return DOH_DNS_BAD_LABEL; 
    else
      index++;

...

  if(!loop)
    return DOH_DNS_CNAME_LOOP;
  return DOH_OK;
}

static DOHcode rdata(unsigned char *doh,
                     size_t dohlen,
                     unsigned short rdlength,
                     unsigned short type,
                     int index,
                     struct dnsentry *d)
{
  /* RDATA
     - A (TYPE 1):  4 bytes
     - AAAA (TYPE 28): 16 bytes
     - NS (TYPE 2): N bytes */
  DOHcode rc;

  switch(type) 
  {
  case DNS_TYPE_A:
    if(rdlength != 4)
      return DOH_DNS_RDATA_LEN;
    rc = store_a(doh, index, d);
    if(rc)
      return rc;
    break;
  case DNS_TYPE_AAAA:
    if(rdlength != 16)
      return DOH_DNS_RDATA_LEN;
    rc = store_aaaa(doh, index, d);
    if(rc)
      return rc;
    break;
  case DNS_TYPE_CNAME:
    rc = store_cname(doh, dohlen, index, d);
    if(rc)
      return rc;
    break;
  case DNS_TYPE_TXT:
    if(rdlength <= 1)
      return DOH_DNS_RDATA_LEN;
    rc = store_txt(doh, dohlen, rdlength, index, d);
    if(rc)
      return rc;
    break;
  default:
    break;
  }
  return DOH_OK;
}
...

int main(int argc, char **argv)
{
...

  if(argc < 1)
    help("no lookup name specified");
  argc--; host = *argv++;
  while(argc > 0) 
  {
    if(n_urls == MAX_URLS)
      help("too many URLs");
    argc--; urls[n_urls++] = *argv++;
  }
  if(n_urls == 0)
    urls[n_urls++] = default_url;
  if(n_urls > 1 && !test_mode)
    help("multiple URLS only permitted in test mode");

  curl_global_init(CURL_GLOBAL_ALL);

  /* 使用旧的内容类型 */
  headers = curl_slist_append(headers,
                              "Content-Type: application/dns-message");
  headers = curl_slist_append(headers,
                              "Accept: application/dns-message");

  /* 初始化多堆栈 */
  multi = curl_multi_init();

  doh_init(&d);

  for(i = 0; i < n_urls; i++) 
  {
    if(query_type == 0 || query_type == DNS_TYPE_A) 
    {
      rc = initprobe(DNS_TYPE_A, host, urls[i], multi,
                     trace_enabled, headers, insecure_mode,
                     transport, resolve, &config);
      if(rc != 0) 
      {
        fprintf(stderr, "initprobe() failed (DNS_TYPE_A)\n");
        exit(1);
      }
    }
    if(query_type == 0 || query_type == DNS_TYPE_AAAA) 
    {
      rc = initprobe(DNS_TYPE_AAAA, host, urls[i], multi,
                     trace_enabled, headers, insecure_mode,
                     transport, resolve, &config);
      if(rc != 0) 
      {
        fprintf(stderr, "initprobe() failed (DNS_TYPE_AAAA)\n");
        exit(1);
      }
    }
    if(query_type == DNS_TYPE_TXT) 
    {
      rc = initprobe(DNS_TYPE_TXT, host, urls[i], multi,
                     trace_enabled, headers, insecure_mode,
                     transport, resolve, &config);
      if(rc != 0) 
      {
        fprintf(stderr, "initprobe() failed (DNS_TYPE_TXT)\n");
        exit(1);
      }
    }
    if(query_type == DNS_TYPE_CNAME) 
    {
      rc = initprobe(DNS_TYPE_CNAME, host, urls[i], multi,
                     trace_enabled, headers, insecure_mode,
                     transport, resolve, &config);
      if(rc != 0) {
        fprintf(stderr, "initprobe() failed (DNS_TYPE_CNAME)\n");
        exit(1);
      }
    }
  }

...

    /* “numfds”为零意味着超时或没有文件描述符等待第一次出现时尝试超时,然后假设没有文件
描述符和无文件描述符等待意味着等待100
毫秒。 */

    if(!numfds) {
      repeats++; /* 计数重复为零的次数 */
      if(repeats > 1) {
        WAITMS(10); /* 睡眠10毫秒 */
      }
    }
    else
      repeats = 0;

    curl_multi_perform(multi, &still_running);
...

  if(successful && !test_mode) 
  {
    int i;
    printf("[%s]\n", host);
    printf("TTL: %u seconds\n", d.ttl);
    if(query_type == 0 || query_type == DNS_TYPE_A) 
    {
      for(i=0; i < d.numv4; i++) 
      {
        printf("A: %d.%d.%d.%d\n",
               d.v4addr[i]>>24,
               (d.v4addr[i]>>16) & 0xff,
               (d.v4addr[i]>>8) & 0xff,
               d.v4addr[i] & 0xff);
      }
    }
    if(query_type == 0 || query_type == DNS_TYPE_AAAA) 
    {
      for(i=0; i < d.numv6; i++) 
      {
        int j;
        printf("AAAA: ");
        for(j=0; j<16; j+=2) 
        {
          printf("%s%02x%02x", j ? ":" : "", d.v6addr[i].byte[j],
                 d.v6addr[i].byte[j+1]);
        }
        printf("\n");
      }
    }
    if(query_type == 0 || query_type == DNS_TYPE_CNAME) 
    {
      for(i=0; i < d.numcname; i++)
        printf("CNAME: %s\n", d.cname[i].alloc);
    }
    if(query_type == 0 || query_type == DNS_TYPE_TXT) 
    {
      for(i=0; i < d.numtxt; i++)
        printf("TXT: %s\n", d.txt[i].txt);
    }
  }

...
  return exit_status;
}

运行结果:
doh协议,C/C++,https,c语言,c++,DNS over HTTPS,doh

doh协议,C/C++,https,c语言,c++,DNS over HTTPS,doh
If you need the complete source code, please add the WeChat number (c17865354792)

总结

HTTPS上的DNS是传统DNS协议的加密、身份验证版本。这意味着您和DNS服务器之间传递的所有数据都是端到端完全加密的;您与网站的连接将是安全的,不易受到中间人攻击或其他类型的窃听。

Welcome to follow WeChat official account【程序猿编码文章来源地址https://www.toymoban.com/news/detail-736330.html

到了这里,关于DNS-over-HTTPS(DoH)详解与C/C++代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何在 Opera 中启用DNS over HTTPS

    DNS over HTTPS(基于HTTPS的DNS)是一种更安全的浏览方式,但大多数 Web 浏览器默认情况下不启用它。了解如何在 Opera 浏览器中启用该功能。   您可能不知道这一点,但您的网络浏览器并不像您希望的那样私密或安全。您会看到,大多数Web浏览器默认为标准DNS,该服务将用户访

    2024年02月11日
    浏览(32)
  • 解决Mixed Content: The page at https://xxx was loaded over HTTPS

    背景 :现有一个项目,网站访问地址示例为 https://www.testcase.com,其中某个功能需要用到外部的服务(例如http:42.192.36.246/api/api.js),并且这个服务是http的并且不能修改。当我们访问https://www.testcase.com的页面时候调用这个http的服务就出现了以下错误。 Mixed Content: The page at \\\'https

    2023年04月08日
    浏览(48)
  • was loaded over HTTPS, but requested an insecure错误解决

    1、问题:今天客服老师在群里反馈一个加密上传图片的组件上传图片失败,问我是不是对图片格式进行了限制。我在控制台打开一下,爆出了这样的一个错误 The page at \\\' https://oms.luojilab.com/oms-host#/ledgers/user \\\' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint \\\' http://ddima

    2024年02月12日
    浏览(48)
  • 解决 Https 站点请求 Http 接口服务后报 the content must be served over HTTPS 错误的问题

    之前将自己所有的 Http 站点全部更新为 Https 站点,但是在请求后台接口服务的时候还是 Http 请求,导致部署之后,直接在控制台报 This request has been blocked; the content must be served over HTTPS; 的错误 因为我不想耗费精力,将所有的后台接口服务也更新为支持 Https 请求,所以访问了

    2024年02月16日
    浏览(51)
  • 错误:Mixed Content: The page at ‘https://XXX’ was loaded over HTTPS, but requested an insecure.

    这种错误的出现是由于网页上同时加载了安全的HTTPS内容和非安全的HTTP内容,这会导致浏览器阻止加载混合内容,以保护用户数据安全和隐私。 出现Mixed Content错误的原因可能是以下几种: 外部脚本或样式表:如果网页中引用的外部脚本或样式表使用了HTTP而不是HTTPS,浏览器

    2024年02月08日
    浏览(45)
  • 解决Mixed Content: The page at https://* was loaded over HTTPS, but requested an insecure XMLHttpReque

    目录 项目场景 问题描述 原因分析 解决方案 一些问题 https协议的网站下请求http的资源 https协议的网站请求http协议的资源被浏览器任务不安全,请求被拦截并且报了以下错误: 原文:  Mixed Content: The page at https://* was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint http:

    2024年02月02日
    浏览(54)
  • 解决Mixed Content:the page at‘https://‘ was loaded over HTTPS,but requested an insecure resource ‘http

    解决Mixed Content:the page at‘https://’ was loaded over HTTPS,but requested an insecure resource ‘http://’ 问题:在Vue项目中使用axios访问了一个http协议的接口,报错如下 查资料后发现原因是在https中请求http接口或引入http资源都会被直接blocked(阻止),浏览器默认此行为不安全,会拦截。

    2024年02月17日
    浏览(57)
  • http请求https报错:Mixed Content: The page at ‘xxx‘ was loaded over HTTPS, but requested an insecure...

    报错的提示: 翻译成中文的话,意思大概就是,混用了 http 和 https 导致不安全,导致请求被阻止了...........。 报错的原因: 由于项目中后端提供的数据接口的地址是采用的 http 协议的,但是他们将项目部署到线上的时候,是放在 php服务器里面的,开启了 https 访问协议。在

    2024年02月11日
    浏览(56)
  • 【WEB前端】【报错解决】This request has been blocked; the content must be served over HTTPS....

    部署WEB项目后,开启了强制HTTPS,产生如下错误: 报错的原因就是当前页面是https协议加载的,但是这个页面发起了一个http的ajax请求,这种做法是非法的。HTTPS页面里动态的引入HTTP资源,比如引入一个js文件,会被直接block掉的.在HTTPS页面里通过AJAX的方式请求HTTP资源,也会被

    2024年02月13日
    浏览(43)
  • Mixed Content: The page at ‘xxx‘ was loaded over HTTPS, but requested an insecure XMLHttpRequest end

    由于项目中后端提供的数据接口的地址是采用的 http 协议的,但是他们将项目部署到线上的时候,是放在 php服务器里面的,开启了 https 访问协议。在https中请求http接口或引入http资源都会被直接blocked(阻止),浏览器默认此行为不安全,会拦截。 https地址中,如果加载了ht

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包