标题三个名词产生的联系
源于需求: 当域名解析失败或者解析的结果不正常(被劫持)时,需要指定公共DNS重新进行域名解析
- gethostbyname用于获取一个域名(例如 www.google.com)或者主机名的ip地址,在Linux和Windows上均有对应的系统级函数,用法可以参考如下链接,关于用法很多博文已经阐述,此处不再赘述;
- 应用程序为了获取域名的IP地址时会调用解析器(resolver)的函数(例如 gethostbyname)与域名服务器(Domain Name Server(DNS))进行信息交换,获取服务器的ip地址;
- dig 命令可以用于解析域名获取ip,此外 dig @NameServerIP url (例如 dig @8.8.8.8 www.google.com) 可以指定DNS服务器进行解析域名,拿到的结果可能和默认的 dig www.google.com 不一致,但都是从属于google的服务器ip;
引发如下疑问
- dig 可以加参数指定name server进行域名解析,是否 gethostbyname 也可以通过指定dns来进行解析?
- gethostbyname失败的原因有哪几种?(待续,下述为目前博主已知场景,如有补充可在评论区新增)
- 1, 域名输入错误;
- 2, 本地/etc/hosts文件或者本地网卡属性中的DNS解析服务器设置错误;
- 3, DNS污染;
- 4, DNS被劫持;
- gethostbyname返回的结果如果错误(被劫持)该如何鉴别?
- 1,根据一个硬编码表查询? 不可取,ip地址变更,硬编码不会变更
延伸
如何设置Windows的DNS解析服务器地址?
-
手动设置:
-
使用程序设置(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)
*/