An Intelligent DNS Similar to DNSPod
Project description
smartdns
使用场景
smartdns是python3语言编写,smartdns基于小米smartdns二次开发,支持类似Dnspod的D监控功能,能够支持针对不同的dns请求根据配置返回不同的解析结果。smartdns获取dns请求的源IP或者客户端IP(支持edns协议的请求可以获取客户端IP),根据本地的静态IP库获取请求IP的特性,包括所在的国家、省份、城市、ISP等,然后根据我们的调度配置返回解析结果,smartdns的典型使用场景:
- 服务的多机房流量调度,比如电信流量调度到电信机房、联通流量调度到联通机房;
- 用户访问控制,将用户调度到离用户最近或者链路质量最好的节点上。
举个简单的例子,我们的一个站点test.test.com同时部署在电信和联通两个机房,该站点在电信机房的ip为1.1.1.1、在联通机房的ip为2.2.2.2,就可以通过smartdns做到该站点域名解析时判断源IP为电信的IP时返回1.1.1.1、判断源IP为联通的IP时返回2.2.2.2,从而达到不同运营商机房流量调度的目的。
安装方法
- 安装python-devel以及bzip2包,以centos为例:
yum install -y bzip2 python-devel
- 执行
pip install smartdns
脚本即可完成安装
支持的功能
支持A、SOA、NS记录的查询,支持DNS forward功能
性能
在虚拟机2.4G CPU上能够处理1000QPS查询请求,打开debug日志后可以到800QPS。3-5台dns server组成的集群已经能够满足大部分站点的需求。
目前我们正在实现和小流量测试go语言实现的smartdns,能够达到3wQPS以上,后续测试稳定后会开源出来,大家敬请期待:)
原理
smartdns响应dns请求的处理流程如下:
IPPool类的初始化和该类中FindIP方法进行解析处理是smartdns中最关键的两个要素,这两个要素在下面详细介绍。其他的特性比如继承twisted中dns相关类并重写处理dns请求的方法、升级twisted代码支持解析和处理edns请求等大家可以通过代码了解。edns知识可以猛戳这里:DNS support edns-client-subnet
IPPool初始化
ip.csv内容格式如下:
200000001, 200000010,中国,陕西,西安,电信
其中各个字段含义分别为 IP段起始,IP段截止,IP段所属国家,IP段所属省份,IP段所属城市,IP段所属ISP
a.yaml配置文件格式:
test.test.com: ttl: 3600 default: 5.5.5.5 2.2.2.2 中国,广东,,联通: 1.1.1.1 3.3.3.1 中国,广东,,电信: 1.1.1.2 3.3.3.2
配置中地域信息的key包括四个字段,分别带有不同的权重:
- 国家: 8
- 省份: 4
- 城市: 2
- 运营商: 1
初始化阶段,会生成一个名为iphash的dict,具体数据结构如下图:
其中,iphash的key为ip.csv每一条记录的起始IP,value为一个list,list长度为6,list前5个字段分别为以该key为起始IP记录的IP段截止、IP段所属国家、IP段所属省份、IP段所属城市、IP段所属ISP,第六个字段是一个hash,key为a.yaml里面配置的域名,value为长度为2的list,iphash[IP段起始][6][域名1][0]为域名1在该IP段的最优解析,iphash[IP段起始][6][域名1][1]为该最优解析的总权值,该总权值暂时只做参考。
iphash初始化过程中最关键的是iphash[IP段起始][6][域名1]的最优解析的计算,最简单直接的方式是直接遍历域名1的所有调度配置,挑选出满足条件且总权值最高的解析,即为最优解析。这种方式记录整个iphash的时间复杂度为O(xyz),x为ip.csv记录数,y为域名总数量,z为各个域名的调度配置数。为了优化启动速度,优化了寻找最优解析的方法:事先将每个域名调度配置生成一颗树,这棵树是用dict模拟出来的,这样需要最优解的时候就不需要遍历所有调度配置,而是最多检索15次即可找到最优,即时间复杂度为O(15xy),具体实现参考IPPool的LoadRecord和JoinIP两个方法。
有了初始化后的iphash数据结构之后,每次请求处理的时候,只需要定位请求IP处在哪个IP段,找到IP段起始IP,然后从iphash中取出最优解析,取出最优解析的过程是O(1)的。具体流程如下:
监控
监控配置详见配置目录的monitor.yaml,内容如下:
test.test.cn:
interval: 30
frequency: 3
url: https://www.baidu.com
分别代表监控域名、监控周期(秒)、容错次数、监控url,监控失败的次数大于容错次数则停止该条记录的解析。
代码
github: https://github.com/duanhongyi/smartdns
安装
依赖:
gcc bzip2 python3以及相关dev包 Twisted
安装:
git clone smartdns到本地路径,执行python setup.py install
命令安装。
启动:
执行sdns /etc/smartdns即可启动smartdns
测试
本地测试 dig test.test.com @127.0.0.1
或者将搭建的smartdns加到测试域名的ns中进行测试。
支持
mail: duanhongyi@doopai.com
github: duanhongyi
EDNS相关请参考:DNS support edns-client-subnet
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file smartdns-3.6.2-py3-none-any.whl
.
File metadata
- Download URL: smartdns-3.6.2-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.6.3 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e9b6ff6ceeaddf2cecc7f9411aade669b621dca6200c54d7ffd79a4f2f369fdc |
|
MD5 | 53ea331784a31cd96e6785e47f830c26 |
|
BLAKE2b-256 | 18d42be4c225cfa3dfcbf5eda1c808be068762a433e1700692d4182454a01039 |