python運維常用模塊(三)——DNS處理模塊dnspython


1.dnspython模塊介紹

dnspython(http://www.dnspython.org/)是Python實現的一個DNS工具包,它支持幾乎所有的記錄類型,可以用於查詢、傳輸並動態更新ZONE信息,同時支持TSIG(事務簽名)驗證消息和EDNS0(擴展DNS)。在系統管理方面,我們可以利用其查詢功能來實現DNS服務監控以及解析結果的校驗,可以代替nslookup及dig等工具,輕松做到與現有平台的整合,下面進行詳細介紹。

2.dnspython模塊安裝

[root@prometheus01 ~]# pip3 install dnspython
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting dnspython
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/9b/ed/28fb14146c7033ba0e89decd92a4fa16b0b69b84471e2deab3cc4337cc35/dnspython-2.2.1-py3-none-any.whl (269 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 269.1/269.1 KB 487.7 kB/s eta 0:00:00
Installing collected packages: dnspython
Successfully installed dnspython-2.2.1
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 22.0.3; however, version 22.0.4 is available.
You should consider upgrading via the '/usr/bin/python3 -m pip install --upgrade pip' command.

3.模塊域名解析方法詳解

dnspython模塊提供了大量的DNS處理方法,最常用的方法是域名查詢。dnspython提供了一個DNS解析器類——resolver,使用它的query方法來實現域名的查詢功能。query方法的定義如下:

query(self, qname, rdtype=1, rdclass=1, tcp=False, source=None, raise_on_no_answer=True, source_port=0)

qname參數為查詢的域名。
rdtype參數用來指定RR資源,常見的有以下幾種:
A記錄,將主機名轉換為IP地址;
MX記錄,郵件交換記錄,定義郵件服務器的域名;
CNAME記錄,指別名記錄,實現域名間的映射;
NS記錄,標記區域的域名服務器及授權子域;
PTR記錄,反向解析,與A記錄相反,將IP轉換為主機名;
SOA記錄,SOA標記,一個起始授權區的定義。

rdclass參數用於指定網絡類型,可選的值有IN、CH與HS,其中IN為默認,使用最廣泛。
tcp參數用於指定查詢是否啟用TCP協議,默認為 False(不啟用)。
source與source_port參數作為指定查詢源地址與端口,默認值為查詢設備IP地址和0。
raise_on_no_answer參數用於指定當 查詢無應答時是否觸發異常,默認為True。

4.常見解析類型示例說明:

常見的DNS解析類型包括A、MX、NS、CNAME等。利用 dnspython的dns.resolver.query方法可以簡單實現這些DNS類型的查詢,為后面要實現的功能提供數據來源,比如對一個使用DNS輪循業務的域名進行可用性監控,需要得到當前的解析結果。下面一一進行介紹。

  • 1.A記錄 實現A記錄查詢方法源碼
#!/usr/bin/python3
#_*_coding:utf-8_*_
import dns.resolver
# 輸入域名地址
domain=input('Please input an domain: ')
#指定查詢類型為A記錄
A=dns.resolver.query(domain,'A')
#通過response.answer方法獲取查詢信息
for i in A.response.answer:
    # 遍歷回應信息
    for j in i.items:
        print(j)

執行結果:

[root@prometheus01 ~]# python3 simple1.py 
Please input an domain: www.baidu.com
www.a.shifen.com.
180.97.34.94
180.97.34.96
  • 2.MX記錄 實現MX記錄查詢方法源碼
#!/usr/bin/python3
#_*_coding:utf-8_*_
import dns.resolver
# 輸入域名地址
domain=input('Please input an domain: ')
#指定查詢類型為MX
MX=dns.resolver.query(domain,'MX')
#遍歷回應結果,輸出MX記錄的preference及exchanger信息
for i in MX:
    print('MX preference=' ,i.preference, 'mail exchange=',i.exchange)

執行結果:

[root@prometheus01 ~]# python3 simple2.py 
Please input an domain: google.com
MX preference= 50 mail exchange= alt4.aspmx.l.google.com.
MX preference= 10 mail exchange= aspmx.l.google.com.
MX preference= 30 mail exchange= alt2.aspmx.l.google.com.
MX preference= 40 mail exchange= alt3.aspmx.l.google.com.
MX preference= 20 mail exchange= alt1.aspmx.l.google.com.
  • 3.NS記錄 實現NS記錄查詢方法源碼
#!/usr/bin/python3
#_*_coding:utf-8_*_
import dns.resolver
# 輸入域名地址
domain=input('Please input an domain: ')
#指定查詢類型為NS記錄
ns=dns.resolver.query(domain,'NS')
#通過response.answer方法獲取查詢信息
for i in ns.response.answer:
    # 遍歷回應信息
    for j in i.items:
        print(j.to_text())

執行結果:

[root@prometheus01 ~]# python3 simple3.py 
Please input an domain: baidu.com
ns4.baidu.com.
ns3.baidu.com.
dns.baidu.com.
ns2.baidu.com.
ns7.baidu.com.
  • 4.CNAME記錄 實現CNAME記錄查詢方法源碼
#!/usr/bin/python3
#_*_coding:utf-8_*_
import dns.resolver
# 輸入域名地址
domain=input('Please input an domain: ')
#指定查詢類型為CNAME記錄
cname=dns.resolver.query(domain,'CNAME')
#結果將回應cname后的目標域名
for i in cname.response.answer:
    # 遍歷回應信息
    for j in i.items:
        print(j.to_text())

執行結果:

[root@prometheus01 ~]# python3 simple4.py 
Please input an domain: www.baidu.com
www.a.shifen.com.
  • 5.實踐:DNS域名輪詢業務監控
    大部分的DNS解析都是一個域名對應一個IP地址,但是通過DNS輪詢技術可以做到一個域名對應多個IP,從而實現最簡單高效的負載均衡,不過此方案最大的弊端是目標主機不可用時無法被自動剔除,因此做好業務主機的服務可用監控至關重要。

步驟:
1.實現域名的解析,獲取域名所有的A記錄解析IP列表
2.對IP列表進行HTTP級別的探測

2.代碼解析
本示例第一步通過dns.resolver.query()方法獲取業務域名A記錄信息,查詢出所有IP地址列表,再使用httplib模塊的request()方法以GET請求監控頁面,監控業務所有服務的IP是否正常。

#!/usr/bin/python3
#_*_coding:utf-8_*_
import dns.resolver
import os
import http.client
# 定義域名ip列表變量
iplist=[]
# 定義業務域名
appdomain="www.baidu.com"
# 域名解析函數,解析成功IP將被追加到iplist
def get_iplist(domain=""):
   try:
      A=dns.resolver.query(domain,'A')
   except Exception as e:
      print("dns resolver error: " +str(e))
      return
   for i in A.response.answer:
      for j in i.items:
         # 追加到iplist列表
         iplist.append(j)
   return True

def checkip(ip):
   checkurl=str(ip)+": 80"
   getcontent=""
   # 定義http連接5秒超時(5)秒
   http.client.socket.setdefaulttimeout(5)
   # 創建http連接對象
   conn=http.client.HTTPConnection(checkurl)
   try:
      # 發起url請求,添加host主機頭
      conn.request("GET","/",headers={"Host":appdomain})
      r=conn.getresponse()
      # 獲取URL頁面前15個字符用來可用性效驗
      getcontent=r.read(15)
   finally:
      # 監控URL頁的內容一般是事先定義好的比如http 200等
      if getcontent=="<!DOCTYPE html>":
         print(str(ip)+"\033[32;1m [ok]\033[0m")
      else:
         print(str(ip)+"\033[31;1m [Error]\033[0m")
      # 獲取response的狀態碼
      print(r.reason)
      # 獲取response的狀態 ok或error
      print(r.status)

if __name__=="__main__":
   # 域名解析正確且至少返回一個IP
   if get_iplist(appdomain) and len(iplist)>0:
      for ip in iplist:
         checkip(ip)
   else:
      print("dns resolver error.")

執行結果:

[root@prometheus01 ~]# python3 simple5.py 
www.a.shifen.com. [Error]
OK
200
180.97.34.94 [Error]
OK
200
180.97.34.96 [Error]
OK
200


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM