DNS
域名系統(Domain Name System,DNS)的主要任務是主機名到IP地址的轉換的目錄服務,DNS是:
- 一個由分層DNS服務器實作的分布式資料庫;
- 一個使得主機能夠查詢分布式資料庫的應用層協議;
DNS服務器是運行BIND(Berkeley Internet Name Domain)軟體的UNIX機器,運行在UDP之上,使用53號埠,
DNS被其他應用層協議所使用,舉例某用戶主機請求某URL:
- 該主機上運行著DNS應用的客戶端;
- 瀏覽器從URL中抽取主機名,并將主機名傳給DNS客戶端;
- DNS客戶端向DNS服務器發送包含主機名的請求;
- DNS服務器回傳主機名對應的IP,主機瀏覽器得到IP后,向其80埠的HTTP服務器行程發起TCP連接;
除提供IP轉換以外,DNS還具有以下服務:
- 主機別名(host aliasing):有著復雜主機名的主機能擁有一個或多個別名,舉例:relay1.west-coast.enterprise.com主機的別名可能是enterprise.com和www.enterprise.com,此時,relay1.west-coast.enterprise.com稱為規范主機名(canonical hostname),主機別名更加容易記憶,
- 郵件服務器別名(mail server aliasing):類似主機別名,一般規范主機名比較復雜,別名容易記憶,呼叫DNS可以得到主機名的規范主機名和IP地址;
- 負載分配(load distribution):繁忙的站點被冗余分布在多臺服務器上,每臺有不同的IP,所以一個IP地址集合與同一個規范主機名對應,用戶請求時,DNS用整個IP地址集合回應,但每個回答中回圈使用這些IP地址,在服務器間回圈分配了負載;
DNS作業機理綜述:
分布式、層次資料庫

DNS使用了大量的DNS服務器,以層次方式組織,大致說來有3類DNS服務器:根DNS服務器、頂級域(Top-Level Domain)DNS服務器和權威DNS服務器,假設一個DNS客戶要決定www.amazon.com的IP地址,首先與根服務器之一聯系,得到頂級域名com的TLD服務器IP,再與這些TLD服務器之一聯系,將為amazon.com回傳權威DNS服務器IP,最后,客戶與amazon.com權威服務器之一聯系,回傳www.amazon.com的IP地址,
- 根DNS服務器:有400多個根DNS服務器遍布,由13個不同的組織管理,根DNS服務器提供TLD服務器的IP地址;
- 頂級域(TLD)DNS服務器:每個頂級域(com、org、net、edu和gov)以及國家的頂級域(uk、fr、ca和jp),都有TLD服務器,TLD服務器提供權威DNS服務器的IP地址;
- 權威DNS服務器:每個在 Internet 上擁有可公開訪問的主機(例如 Web 服務器和郵件服務器)的組織都必須提供可公開訪問的 DNS 記錄,將這些主機的名稱映射到 IP 地址, 組織的權威 DNS 服務器包含這些 DNS 記錄, 組織可以選擇實施自己的權威 DNS 服務器來保存這些記錄;或者,組織可以付費將這些記錄存盤在某些服務提供商的權威 DNS 服務器中, 大多數大學和大公司都實施和維護自己的一級和二級(備份)權威 DNS 服務器,
根、TLD和權威DNS服務器都處在該DNS服務器的層次結構中,
還有另一類重要的DNS服務器,稱為本地DNS服務器(local DNS server),嚴格說來,一個本地DNS服務器并不屬于該服務器的層次結構,但它對DNS層次結構是至關重要的,
每個ISP(如一個居民區的1SP或一個機構的ISP)都有一臺本地DNS服務器(也叫默認名字服務器),當主機與某個ISP連接時,該ISP提供一臺主機的IP地址,該主機具有一臺或多臺其本地DNS服務器的IP地址(通常通過DHCP),通過訪問Windows或UNIX的網路狀態視窗,用戶能夠容易地確定他的本地DNS服務器的IP地址, 主機的本地DNS服務器通常“鄰近”本主機,對某機構ISP而言,本地DNS服務器可能就與主機在同一個局域網中;對于某居民區ISP來說,本地DNS服務器通常與主機相隔不超過幾臺路由器,當主機發岀DNS請求時,該請求被發往本地DNS服務器,它起著代理的作用,并將該請求轉發到DNS服務器層次結構中,
舉例:
假設主機cse.nyu.edu想知道主機gaia.cs.umass.edu的IP地址,同時假設(NYU)的cse.nyu.edu主機的本地DNS服務器為dns.nyu.edu,并且gaia.cs.umass.edu的權威DNS服務器為dns.umass.edu,
如圖所示:

- 主機cse.nyu.edu首先向它的本地DNS服務器dns.nyu.edu發送一個DNS查詢報文,該查詢報文含有被轉換的主機名gaia.cs.umass.edu;
- 本地DNS服務器將該報文轉發到根DNS服務器;
- 該根DNS服務器注意到其edu前綴并向本地DNS服務器回傳負責edu的TLD服務器的IP地址串列;
- 該本地DNS服務器則再次向這些TLD服務器之一發送查詢報文;
- 該TLD服務器注意到umass.edu前綴,并用權威DNS服務器的IP地址進行回應,該權威DNS服務器是負責umass的dns.umass.edu;
- 最后,本地DNS服務器直接向dns.umass.edu重發查詢報文;
- dns.umass.edu用gaia.cs.umass.edu的IP地址進行回應;
注意到在本例中,為了獲得一臺主機名的映射,共發送了8份DNS報文:4份查詢報文和4份回答報文!利用DNS快取能減少這種査詢流量
圖中所示的例子利用了遞回查詢(recursive query)和迭代查詢(iterative query),
- 從cse.nyu.edu到dns.nyu.edu發出的查詢是遞回查詢,因為該查詢以自己的名義請求dns.nyu.edu來獲得該映射,
- 而后繼的3個查詢是迭代查詢,因為所有的回答都是直接回傳給dns.nyu.edu,
從理論上講,任何DNS查詢既可以是迭代的也能是遞回的,
DNS快取:
DNS快取(DNS caching),實際上,為了改善時延性能并減少在因特網上到處傳輸的DNS報文數量,DNS廣泛使用了快取技術,
DNS快取的原理非常簡單,在一個請求鏈中,當某DNS服務器接收一個DNS回答(例如,包含某主機名到IP地址的映射)時,它能將映射快取在本地存盤器中,
例如,在上圖中,每當本地DNS服務器dns.nyu.edu從某個DNS服務器接收到一個回答,它能夠快取包含在該回答中的任何資訊,如果在DNS服務器中快取了一臺主機名/IP地址對,另一個對相同主機名的查詢到達該DNS服務器時,該DNS服務器就能夠提供所要求的IP地址,即使它不是該主機名的權威服務器,DNS服務器在一段時間后(通常設定為兩天)將丟棄快取的資訊,
DNS記錄和報文:
共同實作DNS分布式資料庫的所有DNS服務器存盤了資源記錄(Resource Record, RR), RR提供了主機名到IP地址的映射,每個DNS回答報文包含了一潭訓多條資源記錄,
資源記錄是一個包含了下列欄位的4元組:
(Name, Valuer,Type, TTL)
TTL是該記錄的生存時間,它決定了資源記錄應當從快取中洗掉的時間,在下面給岀的記錄例子中,我們忽略掉TTL欄位,Name和Value的值取決于Type:
- 如果Type = A,則Name是主機名,Value是該主機名對應的IP地址,因此,一條型別為A的資源記錄提供了標準的主機名到IP地址的映射,例如(relay1.bar.foo.com, 145.37.93.126, A)就是一條型別A記錄,
- 如果Type = NS,則Name是個域(如foo.com),而Value是個知道如何獲得該域中主機IP地址的權威DNS服務器的主機名,這個記錄用于沿著查詢鏈來路由DNS查詢,例如(foo.com, dns.foo.com, NS)就是一條型別為NS的記錄,
- 如果Type = CNAME,則Value是別名為Name的主機對應的規范主機名,該記錄能夠向査詢的主機提供一個主機名對應的規范主機名,例如(foo.com, relay1.bar.foo.com, CNAME)就是一條CNAME型別的記錄,
- 如果Type = MX,則Value是個別名為Name的郵件服務器的規范主機名,舉例來說,(foo.com, mail.bar.foo.com, MX)就是一條MX記錄,MX記錄允許郵件服務器主機名具有簡單的別名,值得注意的是,通過使用MX記錄,一個公司的郵件服務器和其他服務器(如它的Web服務器)可以使用相同的別名,為了獲得郵件服務器的規范主機名,DNS客戶應當請求一條MX記錄;而為了獲得其他服務器的規范主機名,DNS客戶應當請求CNAME記錄,
DNS報文:
DNS只有查詢和回答報文,且有著相同的格式:

- 前12個位元組是首部區域,其中有幾個欄位,第一個欄位(識別符號)是一個16位元的數,用于標識該查詢,這個識別符號會被復制到對查詢的回答報文中,以便讓客戶用它來匹配發送的請求和接收到的回答, 標志欄位中含有若干標志,1位元的“查詢/回答”標志位指出報文是查詢報文(0)還是回答報文(1),當某DNS服務器是所請求名字的權威DNS服務器時,1位元的“權威的”標志位被置在回答報文中,如果客戶(主機或者DNS服務器)在該DNS服務器沒有某記錄時希望它執行遞回查詢,將設定1位元的“希望遞回”標志位,如果該DNS服務器支持遞回查詢,在它的回答報文中會對1位元的“遞回可用”標志位置位,在該首部中,還有4個有關數量的欄位,這些欄位指出了在首部后的4類資料區域出現的數量,
- 問題區域包含著正在進行的查詢資訊,該區域包括:①名字欄位,包含正在被查詢的主機名字;②型別欄位,指出有關該名字的正被詢問的問題型別,例如主機地址是與一個名字相關聯(型別A)還是與某個名字的郵件服務器相關聯(型別MX),
- 在來自DNS服務器的回答中,回答區域包含了對最初請求的名字的資源記錄,前面講過每個資源記錄中有Type(如A、NS、CNAME和MX)欄位、Value欄位和TTL欄位,在回答報文的回答區域中可以包含多條RR,因此一個主機名能夠有多個IP地址(例如,就像本節前面討論的冗余Web服務器),
- 權威區域包含了其他權威服務器的記錄,
- 附加區域包含了其他有幫助的記錄,例如,對于一個MX請求的回答報文的回答區域包含了一條資源記錄,該記錄提供了郵件服務器的規范主機名,該附加區域包含一個型別A記錄,該記錄提供了用于該郵件服務器的規范主機名的IP地址,
DNS資料庫中插入記錄:
假定你剛剛創建一個稱為網路烏托邦(Network Utopia)的新創業公司,你必定要做的第一件事是在注冊登記機構注冊域名networkutopia.com,注冊登記機構(registrar)是一個商業物體,它驗證該域名的唯一性,將該域名輸入DNS資料庫,
當你向某些注冊登記機構注冊域名networkutopia.com時,需要向該機構提供你的基本和輔助權威DNS服務器的名字和IP地址,假定該名字和IP地址是dnsl.networkutopia.com和dns2.networkutopia.com及212.212.212.1和212.212.212.2,
對這兩個權威DNS服務器的每一個,該注冊登記機構確保將一個型別NS和一個型別A的記錄輸入TLD com服務器,特別是對于用于networkutopia.com的基本權威服務器,該注冊登記機構將下列兩條資源記錄插入該DNS系統中:
(networkutopia.com, dns1.networkutopia.com, NS)
(dns1.networkutopia.com, 212.212.212.1, A)
你還必須確保用于Web服務器www.networkutopia.com的型別A資源記錄和用于郵件服務器的mail.networkutopia.com的型別MX資源記錄被輸入你的權威DNS服務器中,
P2P檔案分發
在P2P檔案分發中,每個對等方能夠向任何其他對等方重新分發它已經收到的該檔案的任何部分,從而在分發程序中協助該服務器,到2016年止,最為流行的P2P檔案分發協議是BitTorrent,
P2P體系結構到的擴展性:


BitTorrent:
BitTorrent是一種用于檔案分發的流行P2P協議,參與一個特定檔案分發的所有對等方的集合被稱為一個洪流(torrent),在一個洪流中的對等方彼此下載等長度的檔案塊(chunk),典型的塊長度為256KB,當一個對等方首次加入一個洪流時,它沒有塊,隨著時間的流逝,它累積了越來越多的塊,當它下載塊時,也為其他對等方上載了多個塊,一旦某對等方獲得了整個檔案,它也許(自私地)離開洪流,或(大公無私地)留在該洪流中并繼續向其他對等方上載塊,同時,任何對等方可能在任何時候僅具有塊的子集就離開該洪流,并在以后重新加入該洪流中,
每個洪流具有一個基礎設施節點,稱為追蹤器(tracker),當一個對等方加入某洪流時,它向追蹤器注冊自己,并周期性地通知追蹤器它仍在該洪流中,以這種方式,追蹤器跟蹤參與在洪流中的對等方,一個給定的洪流可能在任何時刻具有數以百計或數以千計的對等方,
- 如何決定請求哪個塊?最稀缺優先(rarest first)的技術,這種技術的思路是,針對一個客戶沒有的塊在她的鄰居中決定最稀缺的塊(最稀缺的塊就是那些在她的鄰居中副本數量最少的塊),并首先請求那些最稀缺的塊,這樣,最稀缺塊得到更為迅速的重新分發,其目標是(大致地)均衡每個塊在洪流中的副本數量,
- 為了決定回應哪個請求,BitTorrent使用了一種機靈的對換演算法,其基本想法是:
- 用戶A根據當前能夠以最高速率向她提供資料的鄰居,給出其優先權,
- 特別是,A對于她的每個鄰居都持續地測量接收到位元的速率,并確定以最高速率流入的4個鄰居,
- 每過10秒,她重新計算該速率并可能修改這4個對等方的集合,
- 用BitTorrent術語來說,這4個對等方被稱為疏通(unchoked),
- 重要的是,每過30秒,她也要隨機地選擇另外一個鄰居并向其發送塊,我們將這個被隨機選擇的對等方稱為B,
- 因為A正在向B發送資料,她可能成為B前4位上載者之一,這樣的話B將開始向A發送資料,
- 如果B向A發送資料的速率足夠高,B接下來也能成為A的前4位上載者,
- 換言之,每過30秒A將隨機地選擇一名新的對換伴侶并開始與那位伴侶進行對換,如果這兩名對等方都滿足此對換,它們將對方放入其前4位串列中并繼續與對方進行對換,直到該對等方之一發現了一個更好的伴侶為止,這種效果是對等方能夠以趨向于找到彼此的協調的速率上載,隨機選擇鄰居也允許新的對等方得到塊,因此它們能夠具有對換的東西,除了這5個對等方(“前”4個對等方和一個試探的對等方)的所有其他相鄰對等方均被“阻塞”,即它們不能從A接收到任何塊,BitTorrent有一些有趣的機制沒有在這里討論,包括片(小塊)、流水線、隨機優先選擇、殘局模型和反怠慢,
套接字編程:
- 客戶從其鍵盤讀取一行字符(資料)并將該資料向服務器發送;
- 服務器接收該資料并將這些字符轉換為大寫;
- 服務器將修改的資料發送給客戶;
- 客戶接收修改的資料并在其監視器上將該行顯示出來;
簡單的UDP套接字編程

UDPClient.py
from socket import * server_name = "localhost" server_port = 12000 client_socket = socket(AF_INET, SOCK_DGRAM) while True: message = input("input lowercase: ") if message == "quit": break client_socket.sendto(message.encode(), (server_name, server_port)) modified_message, server_address = client_socket.recvfrom(2048) print(modified_message.decode()) client_socket.close()
UDPServer.py
from socket import * server_port = 12000 server_socket = socket(AF_INET, SOCK_DGRAM) server_socket.bind(("", server_port)) print("server is ready to receive") while True: message, client_address = server_socket.recvfrom(2048) print(f"receive {message}") modified_message = message.decode().upper() server_socket.sendto(modified_message.encode(), client_address)
簡單的TCP套接字編程
與UDP不同,TCP是一個面向連接的協議,這意味著在客戶和服務器能夠開始互相發送資料之前,它們先要握手和創建一個TCP連接,TCP連接的一端與客戶套接字相聯系,另一端與服務器套接字相聯系,當創建該TCP連接時,我們將其與客戶套接字地址(IP地址和埠號)和服務器套接字地址(IP地址和埠號)關聯起來,使用創建的TCP連接,當一側要向另一側發送資料時,它只需經過其套接字將資料丟進TCP連接,這與UDP不同,UDP服務器在將分組丟進套接字之前必須為其附上一個目的地地址,
服務器程式必須具有一扇特殊的門,更精確地說是一個特殊的套接字,該門歡迎來自運行在任意主機上的客戶行程的某種初始接觸,使用房子與門來比喻行程與套接字,有時我們將客戶的初始接觸稱為“敲歡迎之門” ,
隨著服務器行程的運行,客戶行程能夠向服務器發起一個TCP連接,這是由客戶程式通過創建一個TCP套接字完成的,當該客戶生成其TCP套接字時,它指定了服務器中的歡迎套接字的地址,即服務器主機的IP地址及其套接字的埠號,生成其套接字后,該客
戶發起了一個三次握手并創建與服務器的一個TCP連接,發生在運輸層的三次握手,對于客戶和服務器程式是完全透明的,
在三次握手期間,客戶行程敲服務器行程的歡迎之門,當該服務器“聽”到敲門聲時,它將生成一扇新門(更精確地講是一個新套接字),它專門用于特定的客戶,


TCPClient.py
from socket import * server_name = "localhost" server_port = 12000 client_socket = socket(AF_INET, SOCK_STREAM) client_socket.connect((server_name, server_port)) while True: message = input("input lowercase: ") if message == "quit": break client_socket.send(message.encode()) modified_message = client_socket.recv(1024) print(f"modified: {modified_message.decode()}") client_socket.close()
TCPServer.py
from socket import * server_port = 12000 server_socket = socket(AF_INET, SOCK_STREAM) server_socket.bind(("", server_port)) server_socket.listen(2) print("server is ready receive") while True: connect_socket, client_address = server_socket.accept() message = connect_socket.recv(1024).decode() print(f"receive {message}") modified_message = message.upper() connect_socket.send(modified_message.encode()) connect_socket.close()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/530550.html
標籤:其他
上一篇:域前置技術和C2隱藏
下一篇:DHCP 的相關概念
