初探gethostbyname、DNS、dig


标题三个名词产生的联系

源于需求: 当域名解析失败或者解析的结果不正常(被劫持)时,需要指定公共DNS重新进行域名解析



  • 应用程序为了获取域名的IP地址时会调用解析器(resolver)的函数(例如 gethostbyname)与域名服务器(Domain Name Server(DNS))进行信息交换,获取服务器的ip地址;
    应用程序、解析器、DNS关系图

  • dig 命令可以用于解析域名获取ip,此外 dig @NameServerIP url (例如 dig @8.8.8.8 www.google.com) 可以指定DNS服务器进行解析域名,拿到的结果可能和默认的 dig www.google.com 不一致,但都是从属于google的服务器ip;
    dig指定DNS服务器与默认区别

引发如下疑问

  • dig 可以加参数指定name server进行域名解析,是否 gethostbyname 也可以通过指定dns来进行解析?
  • gethostbyname失败的原因有哪几种?(待续,下述为目前博主已知场景,如有补充可在评论区新增)
    • 1, 域名输入错误;
    • 2, 本地/etc/hosts文件或者本地网卡属性中的DNS解析服务器设置错误;
    • 3, DNS污染;
    • 4, DNS被劫持;
  • gethostbyname返回的结果如果错误(被劫持)该如何鉴别?
    • 1,根据一个硬编码表查询? 不可取,ip地址变更,硬编码不会变更

延伸

如何设置Windows的DNS解析服务器地址?
  • 手动设置:
    image

  • 使用程序设置(C++, VS2015编译测试, 此段源代码非博主原创,来源见代码末尾):

#include <iostream>
#include <string>
#include <windows.h>
#include <stdlib.h>
#include <list>
#include <io.h>
using namespace std;

class DNS_Hijack {
private:
	list<string> interface_using;                   //获取本地可用网卡
	list<string> last_get_interface_using;
private:
	string str;                             //存储文件读取后的内容
	string DNS;

private:
	void Get_using_interface()
	{
		system("netsh interface show interface > interface_info.txt");

		FILE* fp = fopen("interface_info.txt", "rb");
		const int file_size = filelength(fileno(fp));
		char* buff = (char*)malloc(sizeof(char)*file_size);
		if (fp) {
			fread(buff, 1, file_size, fp);
			str = buff;
			free(buff);
			replaceA_to_B(str, "-------------------------------------------------------------------------\r\n", "");
			Split(str, "\r\n", interface_using);
			Spilt_space(interface_using);
		}
	}

private:
	void Spilt_space(list<string> list_str) {
		for (list<string>::iterator itor = list_str.begin(); itor != list_str.end(); itor++) {
			cout << *itor << endl;
			string::size_type first_variable = (*itor).find("已启用");
			string::size_type second_variable = (*itor).find("已连接");
			string::size_type third_variable = (*itor).find("专用");
			if (first_variable != string::npos && second_variable != string::npos && third_variable != string::npos) {
				string info = *itor;
				last_get_interface_using.push_back(info.substr(55, info.length()));
			}
		}

	}

private:
	void replaceA_to_B(std::string& S, const std::string A, const std::string B) {
		std::size_t found = S.find(A);
		while (std::string::npos != found) {
			S.replace(found, A.length(), B);
			found = S.find(A, found + 1);
		}
	}

private:
	void Split(const string& src, const string& separator, list<string>& dest)
	{
		string str = src;
		string substring;
		string::size_type start = 0, index;
		dest.clear();
		index = str.find_first_of(separator, start);
		do
		{
			if (index != string::npos)
			{
				substring = str.substr(start, index - start);
				dest.push_back(substring);
				start = index + separator.size();
				index = str.find(separator, start);
				if (start == string::npos) break;
			}
		} while (index != string::npos);

		//the last part
		substring = str.substr(start);
		dest.push_back(substring);
	}

public:
	DNS_Hijack(string DNS = "192.168.1.233")
	{
		Get_using_interface();
		for (list<string>::iterator itor = last_get_interface_using.begin(); itor != last_get_interface_using.end(); itor++)
		{
			string str = "netsh interface ip set dns \"" + (*itor) + "\" static " + DNS;
			cout << str << endl;
			system(str.c_str());
		}
	}
};

int main()
{
	DNS_Hijack* one = new DNS_Hijack("233.5.5.5");
	system("pause");
	return 0;
}
/*
源代码来源作者:程序小黑(https://blog.csdn.net/qq_27180763/article/details/82556807)
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值