一、API接口
- 入口:dns.kangdbao.net
- 协议:支持HTTP/HTTPS协议
二、URL形式
三、请求参数说明
参数 |
含义 |
必填 |
---|---|---|
host | 待查询的域名 | Y |
account_id | md5sum格式账户id,如“21de58ae91bf3ab77e32aeb8fae95291” | Y |
t | 鉴权签名失效时间,最大为now()+600,如”1576468800″ | Y |
sign | 鉴权签名,sign = md5sum(“host-secret-t”) | Y |
out | 输出格式,可选json、text,默认为json | N |
ip | 发起edns请求的ip,不填则为客户端真实ip(仅支持IPv4格式) | N |
qtype | 查询记录的类型,可选A、AAAA默认为A | N |
ttl | 输出包含ttl,可选1、0,默认为0不输出ttl | N |
encrypt | 响应包体是否加密,可选1、0,默认为0即不对响应包体加密 | N |
- account_id:系统为用户随机生成的唯一id,为md5sum格式,如”21de58ae91bf3ab77e32aeb8fae95291″
- t:鉴权签名失效时间,为1970年1月1日以来的秒数,最大值为now()+600。如t=1576468800表示签名在2019-12-16 12:00:00过期。
- sign:鉴权签名。sign = md5sum(“host-secret-t”)。对于host=www.yunaq.com,secret=oB1q6EF8rGUpd1qxBtcm,t=1576468800的情况,sign=md5sum(“www.yunaq.com-oB1q6EF8rGUpd1qxBtcm-1576468800″),则sign取值为1f8c93f4853b8a9cc179b54ea7e0e2f6。secret是系统为用户随机生成长度为20的密钥,每个用户最多存在两个密钥。
- encrypt:encrypt为1时,响应包体以 AES-256-ECB方式进行加密,加密密钥与请求的签名密钥相同,签名密钥为20字符,加密时使用pkcs7padding的16字节方式对密钥进行补齐,即加密密钥从20个字符填充到32个字符。
四、响应格式
- json格式
- 查询成功返回格式:{“ipsv6”:[“2408:8741:0:1:0:0:0:27″],”ttl”:144,”host”:”www.yunaq.com“}
- 未查询到结果返回格式:{}
- 请求错误返回格式:{“code”:”SignatureExpired”}
参数
|
含义
|
---|---|
host | 查询的域名 |
ttl | 该域名解析结果的TTL缓存时间 |
ips/ipsv6 | 解析到的A/AAAA记录 |
- text格式
- 查询成功返回格式:183.212.96.233,111.212.98.126;187(多个地址使用”,”分割,ttl使用”;”分割)
- 未查寻到结果返回格式:null
- 请求错误返回格式:{“code”:”SignatureExpired”}
五、状态码
状态码 |
HTTP状态码 |
描述 |
---|---|---|
MissingArgument | 403 | 缺少必要参数 |
InvalidParam | 403 | 参数格式不合法 |
InvalidSignature | 403 | 签名校验错误 |
SignatureExpired | 403 | 签名时间戳过期 |
DnNotInWhitelist | 403 | 域名不在用户白名单内 |
InvalidAccountId | 403 | 账户id不存在 |
InvalidUrlPath | 404 | 请求路径不存在 |
MethodNotAllowed | 405 | 不支持的HTTP方法 |
AccessRestricted | 503 | 请求过于频繁或并发连接数过多被拒绝 |
InternalError | 500 | 服务端内部错误 |
六、使用示例
- 常规使用示例
# -*- coding:utf-8 -*- import requests import time import hashlib ip = "1.2.3.4" host = "www.yunaq.com" secret = "oB1q4EF8rGUpd2qxBtcm" expiration_time = str(int(time.time())+600) account_id = "7cf125ce0190b2fe2bb6bbb6ab386c15" sign_str = host + "-" + secret + "-" + expiration_time sign = hashlib.md5(sign_str.encode(encoding='UTF-8')).hexdigest() url_tmp = "http://dns.kangdbao.net/sign_d?host=%s&account_id=%s&sign=%s&t=%s&ip=%s" uri = url_tmp % (host, account_id, sign, expiration_time, ip) r = requests.get(uri) print(r.text) ------------------------------------------------------------------------------------------------------- output: {"host":"www.yunaq.com","ips":["111.212.98.126","122.218.238.112"]} |
- 响应加密示例
encrypt==1时,响应包体使用AES-256-ECB方式加密,同时包体也使用pkcs7padding的16字节方式对齐。由于加密后的密文不都是可打印的,所以响应包体是由密文转换而来的16进制字符串,转换过程中每个密文字节由两个十六进制字符表示,如密文为"0123456789abcdef"则转换为十六进制字符串后为"30313233343536373839414243444546"。因此解密时需要先将十六进制字符串响应包体转换为原始密文。
# -*- coding:utf-8 -*- import re import requests import time import hashlib from Crypto.Cipher import AES ip = "1.2.3.4" host = "www.yunaq.com" secret = "TQ3hq6bkp5gmbXNJOJ13" expiration_time = str(int(time.time())+600) account_id = "48c1a96381fbcad1e63c435a44d52713" sign_str = host + "-" + secret + "-" + expiration_time sign = hashlib.md5(sign_str.encode(encoding='UTF-8')).hexdigest() url_tmp = "http://dns.kangdbao.net/sign_d?host=%s&account_id=%s&sign=%s&t=%s&ip=%s&encrypt=1" def hex2str(s): hex_list = re.findall(r'.{2}', s) # 按两个字符切分 return ''.join([chr(int(i, 16)) for i in hex_list]) # pkcs7填充,block_size为16 def pkcs7_padding(text): amount_to_pad = 16 - (len(text) % 16) if amount_to_pad == 0: amount_to_pad = 16 pad = chr(amount_to_pad) return text + pad * amount_to_pad uri = url_tmp % (host, account_id, sign, expiration_time, ip) r = requests.get(uri) if r.status_code != 200: print(r.text) exit() # 将密钥填充到32个字符,即使用AES-256 key = pkcs7_padding(secret) aes = AES.new(str.encode(key), AES.MODE_ECB) encrypted_text = hex2str(r.text) decrypted_text = aes.decrypt(encrypted_text) # 去除pkcs7填充的字符 amount_to_pad = ord(decrypted_text[-1]) res = decrypted_text[0:0-amount_to_pad] print(res) -------------------------------------------------------------------------------------------------------、 output: {"host":"www.yunaq.com","ips":["121.212.98.126","122.218.38.112"]} |
七、实例演示
请求:http://dns.kangdbao.net/sign_d?host=www.yunaq.com&account_id=21de58ae91bf3ab77e32aeb8fae95291&t=1576468800&sign=1f8c93f4853b8a9cc179b54ea7e0e2f6&ip=192.168.12.4
响应:{“host”:”www.yunaq.com“,”ips”:[“122.218.238.109″,”183.212.96.249”]}
响应:{“ipsv6”:[“2308:871c:0:1:0:0:0:27″],”ttl”:144,”host”:”www.yunaq.com“}
八、注意事项
- httpdns会缓存查询结果,当用户更新httpdns的相关配置如密钥或根域名时,最长需要等待2分钟才能生效。
- 当前仅支持IPv4客户端接入。