关注小编微信公众号公众号【前端基础教程从0开始】回复“1”,拉你进程序员技术讨论群,群内有大神,可以免费提供问题解答。公众号回复“小程序”,领取300个优秀的小程序开源代码+一套入门教程。公众号回复“领取资源”,领取300G前端,Java,产品经理,微信小程序,Python等资源合集大放送,让我们一起学前端。
https可以防止http劫持,但是无法防止dns劫持,因为dns劫持发生在你和web 服务器建立连接之前。
打个比方,你要#去超市买东西,dns是出租车,把你送到超市门口(web服务器),https能防止超市给你的商品里加了假货,但是你一开始就上了黑车(dns劫持)!后面的就不可能会发生了!
防止dns劫持,很难,尤其对于小运营商的用户,被劫持的概率非常大。如果你认为用户只要使用8.8.8.8或者119.29.29.29等公共dns就可以避免劫持,那说明你还没发现运营商有多险恶,他们甚至在网关处伪造dns应答,抢答了目标递归dns给你的应答。看你的提问,是站在网站服务提供者的角度来问的,那就更难了,还是上面那个例子,你作为一个超市,想要防止客人被黑车拐跑,你觉得可能吗?我提供三种思路:
第一个(我没试过),发现网站在某些地区运营商被劫持了,投诉工信部,让他们放开劫持。
第二个,选用cdn服务。大部分小运营商dns劫持,是由于你的网站流量大,而源站又在网外,他们为了避免产生高额的网间结算费用,将被网内的dns请求劫持到网内他们自己的缓存服务器集群里。如果你用了cdn,被劫持的概率会略有下降,因为cdn厂商大多节点很多,以我司为例,国内几乎无孔不入,既然都在网内,他们就不会盯上你。即使被劫持,cdn厂商凭借和小运营商良好的沟通渠道(至少我司是这样,经常一个电话或者社交软件上和对方负责人说一句就会放开了),也很容易放开劫持。
第三个,选用httpdns,利用腾讯httpDns应对dns劫持来举例:
主要有三个步骤
1、自制DNS服务器,监听127.0.0.1:53
2、修改网络连接里面的首选DNS服务器为:127.0.0.1
3、服务器收到DNS请求后,从腾讯的httpDns接口查询,再返回给请求端,接口:http://119.29.29.29/d?dn=域名
防劫持源码地址:
/fz6/mobile_h5_antihijacking
代码:
import hpsocket;import hpsocket.udpServer;import wsock;namespace hpsocketclass dnsServer{ctor(initFile, dnsApp ){this = ..hpsocket.udpServer()if(!this){return null; }this.threadGlobal = {_dnsApp = dnsApp;_initFile = initFile;response = {};request = {};}this.onThreadCreated = function(){import web.json;import hpsocket.dnsServer;import console;log=function(...){console.dump(...)}if(_initFile){loadcodex(_initFile)}response.close = function(){if(owner.resultStr and #owner.resultStr){hpUdpServerEx.send(connId,owner.resultStr,#owner.resultStr)}owner.resultStr = "";}response.write = function(s,...){if( s === null ) return;var ts = type(s);if( ts == 'table' ){if(s[["_struct"]]) {if( s@[["_tostring"]] ) s = tostring(s); }else s = web.json.stringify(s,owner.jsonPrettyPrint);}elseif( (ts != 'string') && (ts != 'buffer') ){s = tostring(s);};owner.resultStr ++= s;s = null;ts=nullif(...===null) return;return owner.write(...);}response.loadcode = function(path){loadcodex( path );}global.print = function(...){response.write(...);};}this.onReceive = function(hpUdpServerEx,connId,pData,length){global.hpUdpServerEx = hpUdpServerEx;global.connId = connIdif(_dnsApp){request.body = ..raw.tostring(pData,1,length)request.domains = hpsocket.dnsServer.dealDNSbyte(request.body);response.resultStr = "";_dnsApp(request,response);response.close();}}};}namespace dnsServer{class TDNSBitCode{Word QR=0; //Query/Response FlagWord OpCode=0; //Word AA=0; //Authoritative Answer FlagWord TC=0; //Truncation FlagWord RD=0; //Recursion DesiredWord RA=0; //Recursion Available:Word Z=0; //ZeroWord RCode=0; //Response Code}class TDNSHeader{Word ID=0; //Identifier:Word BitCode=0; //从中分析出TDNSBitCodeWord QDCount=0;Word ANCount=0;Word NSCount=0;Word ARCount=0;}class dns_packet{WORD Id=0;WORD Flags=0;WORD Questions=0;WORD Answers=0;WORD Authoritys=0;WORD Additionals=0;} class DnsQuery{Word TheType=0; //记录类型 A NS CNAMEWord TheClasses=0;}class DnsResponse{Word TheName=0;Word TheType=0;Word TheClasses=0;INT ttl=0;Word length=0;INT addr=0;}GetDNSBitCode = function( BitCode){var result = TDNSBitCode();result.QR = BitCode >> 15;result.OpCode = ((BitCode & 0x7800) >> 11) & 0x000F;result.AA = (BitCode & 0x0700) >> 10;result.TC = (BitCode & 0x0200) >> 9;result.RD = (BitCode & 0x0100) >> 8;result.RA = (BitCode & 0x0800) >> 7;result.Z = 0;result.RCode = BitCode & 0x000F;return result; }DNSStrToDomain = function(SrcStr, Idx){var Result = '' ;var fRPackSize = #SrcStr;var SavedIdx = 0;do{var Len = SrcStr[Idx];while( (Len & 0xC0)==0xC0 ){if (SavedIdx == 0){SavedIdx = Succ(Idx)}var aChar = Len & 0x3F;Idx = twoCharToWord(aChar, SrcStr[Idx + 1]) + 1;Len := SrcStr[Idx]; }if (Idx >= fRPackSize){return ; }var LabelStr='';if (Len > 0){LabelStr = ..string.sub(SrcStr,Idx+1,Idx+Len);Idx += Len+1;}if (Idx+1 > fRPackSize){return ; }Result ++= LabelStr ++ '.';}while(!(SrcStr[Idx] == 0 or Idx > #SrcStr))if (Result[#Result] == '.'#){Result = ..string.left(Result,#Result-1)}if (SavedIdx > 0){Idx = SavedIdx}Idx++;return Result, Idx; }long2str=function(src,len=2){if(type(src)==type.number){var bytesif(len==2){bytes = ..raw.convert({WORD n=src},{BYTE s[2]={}});}elseif(len==4) {bytes = ..raw.convert({INT n=src},{BYTE s[4]={}});}elseif(len==8) {bytes = ..raw.convert({LONG n=src},{BYTE s[8]={}});}return ..string.pack(bytes.s)//..raw.malloc(#bytes.s,bytes); }}BuilderDNSResponse = function(pDnsQuery, nQueryLen, SnoopIP){if(pDnsQuery){var dnsr = dns_packet();var dnslen = ..raw.sizeof(dnsr);var dnss = dns_packet();var queryr = DnsQuery();var str = ..string.left(pDnsQuery,dnslen);..raw.convert(str,dnsr);//标识字段dnss.Id := dnsr.Id;//标志字段,其中设置了QR = 1,RD = 1,RA = 1dnss.Flags := ..wsock.htons(0x8180);//问题数量dnss.Questions := ..wsock.htons(1);if(type(SnoopIP)==type.table){//回答数量dnss.Answers := ..wsock.htons(#SnoopIP);}else {//回答数量dnss.Answers := ..wsock.htons(1);}dnss.Authoritys := 0;dnss.Additionals := 0;var querylen = ..raw.sizeof(queryr);var ulen = nQueryLen - dnslen - querylen;var start = dnslen+ ulenstart += 1;var dname = ..string.sub(pDnsQuery, dnslen+1, dnslen+ulen)str = ..string.sub(pDnsQuery, start, start+3)..raw.convert(str,queryr);start += 4;var responses = DnsResponse();var responselen = ..raw.sizeof(responses)var usBufferLenif(type(SnoopIP)==type.table){usBufferLen = start + responselen*#SnoopIP;}else {usBufferLen = start + responselen;}var result = ..raw.malloc(usBufferLen,dnss);var len = dnslen;len = ..raw.concat(result,dname,len,#dname);var queryr1 = ..raw.malloc(queryr);len = ..raw.concat(result,queryr1,len,#queryr1);if(type(SnoopIP)==type.table){for(i=1;#SnoopIP;1){//域名指针str = long2str(..wsock.htons(0xC00C));len =..raw.concat(result,str,len,#str);//0005 CNAME str = long2str(queryr.TheType);len =..raw.concat(result,str,len,#str);//0001 类,表示为Internet数据str = long2str(queryr.TheClasses);len =..raw.concat(result,str,len,#str);//TTL 生存时间str = long2str(0x0000000A,4);len =..raw.concat(result,str,len,#str);//数据长度 127 0 0 1str = long2str(..wsock.htons(4));len =..raw.concat(result,str,len,#str);//内容 127 0 0 1str = long2str(..wsock.inet_addr(SnoopIP[ i ]),4);len =..raw.concat(result,str,len,#str);}}else {//域名指针str = long2str(..wsock.htons(0xC00C));len = ..raw.concat(result,str,len,#str);//0005 CNAME str = long2str(queryr.TheType);len = ..raw.concat(result,str,len,#str);//0001 类,表示为Internet数据str = long2str(queryr.TheClasses);len = ..raw.concat(result,str,len,#str);//TTL 生存时间str = long2str(0xFFFFFFFF,4);len = ..raw.concat(result,str,len,#str);//数据长度 127 0 0 1str = long2str(..wsock.htons(4));len = ..raw.concat(result,str,len,#str);//内容 127 0 0 1str = long2str(..wsock.inet_addr(SnoopIP),4);len = ..raw.concat(result,str,len,#str);}return ..raw.tostring(result,0,len); }}twoCharToWord = function(b1,b2){return ((b1 << 8) & 0xFF00) | (b2 & 0x00FF)}dealDNSbyte = function(strRecvData){var id = twoCharToWord(strRecvData[1], strRecvData[2]);var Code = twoCharToWord(strRecvData[3], strRecvData[4]);var BitCode = GetDNSBitCode(Code);if( BitCode.QR != 0){return}; //0表示查询,1表示反馈var QDCount = twoCharToWord(strRecvData[5], strRecvData[6]);if (QDCount <= 0) {return } var APos = 13; // DNS头恒为12字节var DomainNamevar domains = {}for(i=1;QDCount;1){DomainName,APos = DNSStrToDomain(strRecvData, APos);if (!DomainName){return };var QueryType = twoCharToWord(strRecvData[APos], strRecvData[APos + 1]);APos += 2;var QueryClass = twoCharToWord(strRecvData[APos], strRecvData[APos + 1]);APos += 2;..table.push(domains,DomainName);}return domains; }}
如果觉得《移动端h5页面会被植入广告问题解决》对你有帮助,请点赞、收藏,并留下你的观点哦!