python-域名系统
域名系统
域名系统(DNS)是一个分布式的数据库,主要用来不主机名转换成IP地址。DNS以及相关系统存在的原因主要有两个:
- 可以使人们比较容易的记住名字。
- 允许服务器改变IP地址,但是还是用原来的名字。
进行DNS查询
首先程序会和操作系统配置文件指定的本地名称服务器通信。这个服务器是一个递归的名称服务器,它收到请求然后询问.com域,其中有个内置的顶级域名列表,这些服务器可以分发世界上顶级域名的信息,递归的询问另外一个名称服务器直到找到需要的名称信息。
操作系统提供执行基本DNS查找服务。python在socket模块中,提供了访问这些基本操作系统服务的接口。
使用操作系统查询服务
操作系统自带有一些用于DNS查找的功能,这些功能可以满足大部分应用程序的需求。
执行基本查询
最基本的查询是正向查询,根据一个主机名来查找IP地址。首先要找到IP地址,正向查询会完成这个任务把一个名字翻译成IP地址。
python中是这么定义的:
getaddrinfo(host,port[,family[,socktypr[,proto[,flags]]]])
host就是需要寻找的域名,其他参数只有想把结果直接传递给socket.socket()或socket.connect()时才用到。返回值是一列tuple,每个是下面的样子:
(family,socktype ,proto,canonname ,sockaddr )
sockaddr 实际上就是远程机器的地址,是执行查找的时候要找的数据。
执行反向查询
有些时候想知道IP地址需要确定相应的主机名。多数情况下,发生在服务器想知道哪个客户端正连接着。
反向查找基础
对于一个IP地址,完全有可能不存在反向的映射。所以需要确保为每一个反向查找的行为捕获和处理socket.herror()。下面是一个反向查找的例子,把命令行中给出的IP地址作为参数,并返回相应的域名,代码如下:
#!/usr/bin/env python
#Basic gethostbyadddr example
import sys,socket
try:
result = socket.gethostbyaddr(sys.argv[1])
print "Primary hostname:"
print " " + result[0]
print "\nAddresses:"
for item in result[2]:
print " " + item
except socket.herror,e:
print "Couldn't look up name:",e
有时候会发现攻击者会在反向查找记录中插入伪造的数据,DNS结构中没法阻止这种欺骗,但是可以在程序中加入一些限制。首先正常的反向查询得到一个域名,然后根据这个域名进行一个正向查询。如果正常则IP地址应该在正向查询得到的列表上,否则就是有人提供伪造的反向信息。
获得环境信息
获得运行程序的机器的信息,需要使用两个新函数一个是socket.gethostname(),不带任何参数,返回一个字符串,是本地机器的主机名,通常是不完整的。第二个是socket.getfqdn(),有一个参数是主机名,会获得完整的主机名。
总结
DNS用于在域名和IP地址之间的转换。python通过socket模块提供了一个访问操作系统本身DNS功能的接口,为了更加灵活也可以使用第三方扩展DNS包,例如PyDNS。
正向查询把域名翻译成IP地址,是连接远程服务的一个基本部分。反向查询把IP地址翻译成主机名,不过需要在反向查询中确保没有使用无效的数据。