iOS DNS劫持

一、DNS

  DNSDomain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
  简单说就是网络地址IP由数字组成的,例如百度的服务器地址是115.239.210.27,浏览器可以通过这个地址访问百度,但是这个数字记忆起来比较麻烦,于是就有了www.baidu.com这个更直观的表示方法,DNS就是连接这两者的服务。

二、DNS解析

  域名到IP地址的映射,DNS解析请求采用UDP数据报且明文的。
  现在假如我们访问一个网站www.baidu.com从按下回车到百度页面显示到我们的电脑上会经历如下几个步骤:

  • 1:计算机会向我们的运营商(移动、电信、联通等)发出打开www.baidu.com的请求。
  • 2:运营商收到请求后会到自己的DNS服务器中找www.baidu.com这个域名所对应的服务器的IP地址(也就是百度的服务器的IP地址),这里比如是115.239.210.27
  • 3:运营商用第二步得到的IP地址去找到百度的服务器请求得到数据后返回给我们。

  其中第二步就是我们所说的DNS解析过程,域名和IP地址的关系其实就是我们的身份证号和姓名的关系,都是来标记一个人或者是一个网站的,只是IP地址/身份证号只是一串没有意义的数字,辨识度低,又不好记,所以就会在IP上加上一个域名以便区分,或是做的更加个性化,但是如果真的要来准确的区分还是要靠身份证号码或者是IP的,所以DNS解析就应运而生了。

DNS解析

二、DNS劫持

  DNS劫持,由于域名->IP这个过程中,其解析是基于UDP 协议实现,所以报文是明文状态,可能会在请求过程中被监测,然后攻击者做一些自己的处理,比如返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。根本原因就是以下两点:

  • 1:恶意攻击,拦截运营商的解析过程,把自己的非法东西嵌入其中。
  • 2:运营商为了利益或者一些其他的因素,允许一些第三方在自己的链接里打打广告之类的。
DNS劫持

四、防止DNS劫持

  了解了DNS劫持的相关资料后我们就知道了,防止DNS劫持就要从第二步入手,因为DNS解析过程是运营商来操作的,我们不能去干涉他们,不然我们也就成了劫持者了,所以我们要做的就是在我们请求之前对我们的请求链接做一些修改,将我们原本的请求链接www.baidu.com修改为115.239.210.27,然后请求出去,这样的话就运营商在拿到我们的请求后发现我们直接用的就是IP地址就会直接给我们放行,而不会去走他自己DNS解析了,也就是说我们把运营商要做的事情自己先做好了。不走他的DNS解析也就不会存在DNS被劫持的问题,从根本是解决了。

  我们知道要要把项目中请求的接口替换成IP其实很简单,URL是字符串,域名替换IP,无非就是一个字符串替换而已,的确这块其实没有什么技术含量。

  这里要说一下IP地址的来源,如何拿到一个域名所对应的IP呢?这里就是需要用到另一个服务——HTTPDNS

1. HTTPDNS

  HTTPDNS是客户端基于http协议向服务器A发送域名B解析请求(例如:www.baidu.com),服务器A直接返回域名B对应的ip地址(例如:115.239.210.27),客户端获取到的IP后就向直接往此IP发送业务协议请求。
这种方式替代了基于DNS协议向运营商LocalDNS发起解析请求,可以从根本上避免LocalDNS造成的域名劫持问题。
常规的DNS解析是通过UDP方式。

  国内提供域名解析 API 接口的,有 DNSPod,现在国内有很多厂商为 DNSPod 开发了 SDK,比如 阿里、七牛(开源)等。不想自己写的,不妨使用这些 SDK。

2. 内置IP列表
  可以在启动等阶段由服务端下发域名和 IP 的对应列表,客户端来进行缓存,发起网络请求的时候直接根据缓存 IP 来进行业务访问。

  实现 HTTP 协议下 IP 连接其实是很简单的,我们只需要通过 NSURLProtocol 来拦截网络请求,然后将符号条件的网络请求 URL 中的域名修改为 IP 就可以啦,也就是本地域名解析LocalDNS。

#include <netdb.h>
#include <arpa/inet.h>

/**
 * 通过hostname获取ip列表 DNS解析地址
 */
- (NSArray *)getDNSsWithDormain:(NSString *)hostName{
    NSMutableArray *result = [[NSMutableArray alloc] init];
    NSArray *IPV4DNSs = [self getIPV4DNSWithHostName:hostName];
    if (IPV4DNSs && IPV4DNSs.count > 0) {
        [result addObjectsFromArray:IPV4DNSs];
    }
    
    //由于在IPV6环境下不能用IPV4的地址进行连接监测
    //所以只返回IPV6的服务器DNS地址
    NSArray *IPV6DNSs = [self getIPV6DNSWithHostName:hostName];
    if (IPV6DNSs && IPV6DNSs.count > 0) {
        [result removeAllObjects];
        [result addObjectsFromArray:IPV6DNSs];
    }
    
    return [NSArray arrayWithArray:result];
}
//ipv4
- (NSArray *)getIPV4DNSWithHostName:(NSString *)hostName
{
    const char *hostN = [hostName UTF8String];
    struct hostent *phost;
    
    @try {
        phost = gethostbyname(hostN);
    } @catch (NSException *exception) {
        return nil;
    }
    
    NSMutableArray *result = [[NSMutableArray alloc] init];
    int j = 0;
    while (phost && phost->h_addr_list && phost->h_addr_list[j]) {
        struct in_addr ip_addr;
        memcpy(&ip_addr, phost->h_addr_list[j], 4);
        char ip[20] = {0};
        inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip));
        
        NSString *strIPAddress = [NSString stringWithUTF8String:ip];
        [result addObject:strIPAddress];
        j++;
    }
    
    return [NSArray arrayWithArray:result];
}

//ipv6
- (NSArray *)getIPV6DNSWithHostName:(NSString *)hostName
{
    const char *hostN = [hostName UTF8String];
    struct hostent *phost;
    
    @try {
        /**
         * 只有在IPV6的网络下才会有返回值
         */
        phost = gethostbyname2(hostN, AF_INET6);
    } @catch (NSException *exception) {
        return nil;
    }
    
    NSMutableArray *result = [[NSMutableArray alloc] init];
    int j = 0;
    while (phost && phost->h_addr_list && phost->h_addr_list[j]) {
        struct in6_addr ip6_addr;
        memcpy(&ip6_addr, phost->h_addr_list[j], sizeof(struct in6_addr));
        NSString *strIPAddress = [self formatIPV6Address: ip6_addr];
        [result addObject:strIPAddress];
        j++;
    }
    
    return [NSArray arrayWithArray:result];
}

- (NSString *)formatIPV6Address:(struct in6_addr)ipv6Addr{
    NSString *address = nil;
    
    char dstStr[INET6_ADDRSTRLEN];
    char srcStr[INET6_ADDRSTRLEN];
    memcpy(srcStr, &ipv6Addr, sizeof(struct in6_addr));
    if(inet_ntop(AF_INET6, srcStr, dstStr, INET6_ADDRSTRLEN) != NULL){
        address = [NSString stringWithUTF8String:dstStr];
    }
    
    return address;
}

所以调用直接使用

[self getDNSsWithDormain:@"www.baidu.com"];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 一、基础背景 1. DNS解析 现在假如我们访问一个网站www.baidu.com从按下回车到百度页面显示到我们的...
    doudo阅读 11,216评论 4 30
  • 背景 前段时间在处理iOS端的HTTPDNS相关SDK,在接入和测试环节发现大家对HTTP的整体请求流程包括HTT...
    茉莉儿阅读 3,097评论 5 16
  • 摘要 对于互联网,域名是访问的第一跳,而这一跳很多时候会“失足”,导致访问错误内容,失败连接等,让我们在互联网上畅...
    贰爷阅读 1,026评论 0 1
  • 谈办公室恋爱的好处就是,你们可以朝夕相处,你也可以将做不来的企划案丢给他来处理,甚至,你们连情侣衣都可以省了,每套...
    逐梦菇凉阅读 595评论 2 2
  • 前些天我有两篇文章发在了公众号上,因为蹭阅读量,我踌躇再三,还是将文章发到了同学群里。 现在的几个同学群早已没了当...
    冬月之恋阅读 795评论 16 19