लिनक्स पर QoS: ट्रैफ़िक का मज़ाक उड़ाना

पिछले लेख में, मैंने U32 फ़िल्टर के बारे में बात की थी। इस लेख में, हम तथाकथित टीसी क्रियाओं के बारे में बात करेंगे - जो ट्रैफ़िक पर किए जा सकते हैं। उदाहरण के लिए, आप iptables / netfilter का उपयोग किए बिना एक फ़ायरवॉल का निर्माण कर सकते हैं, या पैकेट में अलग-अलग बाइट्स बदल सकते हैं, अन्य इंटरफेस में रीडायरेक्ट / मिरर ट्रैफ़िक कर सकते हैं। हम उदाहरणों के साथ इसमें महारत हासिल करेंगे। कट के नीचे जारी है।


ये किस प्रकार की tc क्रियाएं हैं?

ट्रैफिक कंट्रोल एक्शन (बाद में बस "एक्शन" के रूप में जाना जाता है) ट्रैफिक कंट्रोल सबसिस्टम में फिल्टर का विस्तार है। इन एक्सटेंशनों की आवश्यकता विभिन्न प्रकार की जरूरतों के लिए होती है - सबसे सरल ड्रॉपिंग पैकेट से लेकर ट्रैफ़िक को बदलने तक। कार्रवाई एक अलग फिल्टर से जुड़ी हुई है, और इस प्रकार जोड़तोड़ केवल चयनित ट्रैफ़िक पर किए जाते हैं, जो लचीलापन जोड़ता है। इसके अलावा, आप पाइपों (जैसे कंसोल में पाइपलाइनिंग डेटा) के माध्यम से क्रियाओं की पूरी श्रृंखला बना सकते हैं। आने वाले ट्रैफ़िक और आउटगोइंग ट्रैफ़िक दोनों पर जोड़तोड़ किया जा सकता है।

सबसे पहले, हमें इंटरफ़ेस में एक वर्ग या वर्गहीन अनुशासन जोड़ने की आवश्यकता है, और कार्यों के साथ फ़िल्टर पहले से ही इसमें जोड़े जाएंगे। अगर हम इनबाउंड ट्रैफ़िक का मज़ाक उड़ाना चाहते हैं, तो हमें अनुशासन को जोड़ना होगा। इसकी विशिष्ट विशेषता यह है कि इसका हैंडल हमेशा "ffff:" होता है और यह हमेशा क्लासलेस होता है।

स्वाभाविक रूप से, उपयुक्त मॉड्यूल को कर्नेल में शामिल किया जाना चाहिए। वे नेटवर्किंग समर्थन - नेटवर्किंग विकल्प - क्यूओएस और / या उचित कतार शाखा में स्थित हैं। आपके द्वारा उपयोग किए जाने वाले कार्यों के साथ आपको शामिल किए गए क्रियाएँ विकल्प और मॉड्यूल की आवश्यकता है। वितरण कर्नेल में, आमतौर पर सब कुछ पहले से ही शामिल है।

कार्यों का उपयोग करने का सबसे सरल उदाहरण


फ़िल्टर के निर्माण को सरल बनाने के लिए, हम लेबल का उपयोग करके जोड़तोड़ के लिए ट्रैफ़िक का चयन करेंगे। यह विधि केवल आउटगोइंग ट्रैफ़िक के लिए उपयुक्त है। ऐसा क्यों? आइए इस चित्र को देखें , जो लिनक्स नेटवर्क स्टैक पर पैकेज पथ दिखाता है। जैसा कि आप देख सकते हैं, आने वाले पैकेजों का अनुशासन और वर्गीकरण किसी भी नेटफिटर हुक की तुलना में बहुत पहले किया गया है, और इसलिए हमारे पास पहले पैकेज को चिह्नित करने के लिए कहीं नहीं है। इस मामले में, वर्गीकरण के लिए, यह अन्य मानदंडों के अनुसार फिल्टर बनाने के लिए समझ में आता है, उदाहरण के लिए, यू 32 का उपयोग करके। इस समस्या का दूसरा तरीका ट्रैफ़िक को किसी अन्य इंटरफ़ेस पर पुनर्निर्देशित करना है।

आइए कार्यों को लागू करने का सबसे सरल उदाहरण देखें। निश्चित रूप से, कई लोग उसका सामना कर चुके हैं। हम तथाकथित पॉलीसर का उपयोग करके कुछ प्रकार के ट्रैफ़िक के लिए बैंडविड्थ प्रतिबंधों के बारे में बात करेंगे। पॉलीसर वर्तमान बाल्टी के एल्गोरिदम के अनुसार काम करता है (आप विकिपीडिया पर या तन्नेबौम पर इस एल्गोरिथ्म के बारे में पढ़ सकते हैं)।

मान लीजिए कि हम tcp प्रोटोकॉल के आने वाले ट्रैफिक की गति को आईपी एड्रेस 192.168.10.3 से एड्रेस 192.168.10.5 तक सीमित करना चाहते हैं। आप इस प्रकार कर सकते हैं:
#   #  tc qdisc add \ dev eth0 \ ingress #    # tcp #  192.168.10.3/32 #  192.168.10.5/32 tc filter add \ dev eth0 \ parent ffff: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip protocol 6 0xff \ match ip src 192.168.10.3/32 \ match ip dst 192.168.10.5/32 \ action police \ rate 2Mbit burst 200K exceed-conform drop 


अंतिम दो लाइनें हमारे लिए सबसे बड़ी रुचि हैं (यदि अन्य लाइनें आपके लिए स्पष्ट नहीं हैं, तो U32 फ़िल्टर के बारे में LARTC पढ़ें)।


उदाहरण के लिए दोनों मशीनों पर iperf चलाएं और गति को मापें। यदि सब कुछ सही ढंग से किया जाता है, तो 192.168.10.3 से 192.168.10.5 तक की गति दो मेगाबिट्स के क्षेत्र में होनी चाहिए (यह मामला है यदि परीक्षण डेटा को छोड़कर नोड्स के बीच कुछ भी प्रेषित नहीं किया गया है)। आंकड़ों में, आप देख सकते हैं कि कितना डेटा फ़िल्टर से गुजरा, कितनी बार काम किया, कितने पैकेट छोड़ दिए गए और गिरा दिए गए, आदि।

 ~$ iperf -s -p 10500 ------------------------------------------------------------ Server listening on TCP port 10500 TCP window size: 85.3 KByte (default) ------------------------------------------------------------ [ 4] local 192.168.10.5 port 10500 connected \ with 192.168.10.3 port 59154 [ ID] Interval Transfer Bandwidth [ 4] 0.0-11.2 sec 2.73 MBytes 2.04 Mbits/sec ~$ tc -s -pf ls dev eth0 parent ffff: filter protocol ip pref 10 u32 filter protocol ip pref 10 u32 fh 800: ht divisor 1 filter protocol ip pref 10 u32 fh 800::1 \ order 1 key ht 800 bkt 0 terminal flowid ??? \ (rule hit 2251145 success 4589) match IP src 91.193.236.62/32 (success 5843 ) match IP dst 91.193.236.44/32 (success 4608 ) match IP protocol 6 (success 4589 ) action order 1: police 0x1e rate 2000Kbit burst 200Kb mtu 2Kb \ action drop overhead 0b ref 1 bind 1 Action statistics: Sent 6870220 bytes 4589 pkt (dropped 761, overlimits 761 requeues 0) backlog 0b 0p requeues 0 


अन्य कार्यों का इसी तरह उपयोग किया जाता है। प्रत्येक क्रिया के लिए, आप मापदंडों पर थोड़ी मदद कर सकते हैं। उदाहरण के लिए, एक ही पॉलीसर के लिए, यह कमांड के साथ किया जा सकता है:

 tc filter add \ dev eth0 \ parent ffff: \ u32 \ match u32 0 0 \ action police \ help Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ] [ peakrate BPS ] [ avrate BPS ] [ overhead BYTES ] [ linklayer TYPE ] [ ACTIONTERM ] Old Syntax ACTIONTERM := action <EXCEEDACT>[/NOTEXCEEDACT] New Syntax ACTIONTERM := conform-exceed <EXCEEDACT>[/NOTEXCEEDACT] Where: *EXCEEDACT := pipe | ok | reclassify | drop | continue Where: pipe is only valid for new syntax 


अन्य कार्यों के लिए एक संकेत प्राप्त करने के लिए, बस "पुलिस" के बजाय उनके नाम का संकेत दें।

क्रियाओं की छोटी सूची


वर्तमान में, निम्न क्रियाएं कर्नेल में शामिल हैं:


जंजीरों की क्रिया


क्रियाओं को व्यक्तिगत और एक साथ, चेन बनाने पर लागू किया जा सकता है। यह सब कंसोल में डेटा को पाइपलाइन करने के समान है, जब एक प्रोग्राम का आउटपुट दूसरे के इनपुट को खिलाया जाता है। ठीक उसी तरह से क्रियाओं के साथ। उदाहरण के लिए, पैकेज हेडर में कुछ फ़ील्ड को बदलने का प्रयास करें। उसके बाद, हमें चेकसम को फिर से लिखना और अपडेट करना होगा। इसके लिए, pedit और csum को एक साथ जंजीर बनाया जाएगा। स्पष्टता के लिए, हम ifb0 इंटरफ़ेस पर परिणामी पैकेट को मिरर करते हैं और उन्हें tcpdump के साथ देखते हैं।

 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip protocol 6 0xff \ match ip src 10.10.20.119/32 \ match ip dst 10.10.20.254/32 \ match u16 10500 0xffff at 22 \ action pedit \ munge offset 22 u16 set 11500 \ pipe \ action csum \ tcp \ pipe \ action mirred \ egress mirror dev ifb0 


टीम काफी भयभीत दिख रही है। हम शुरुआत से परिचित हैं - हम स्रोत और गंतव्य पते, प्रोटोकॉल और पोर्ट नंबर (प्रोटोकॉल tcp, आईपी src 10.10.20.119, ip dst 10.10.20.254, tcp aport 10500) द्वारा आवश्यक पैकेजों का चयन करने के लिए एक फिल्टर जोड़ते हैं। लेकिन वर्गीकृत करने के बजाय, हम पैकेट की सामग्री ("एक्शन पेडिट" पैरामीटर) को बदलते हैं - आईपी पैकेट की शुरुआत से 22 बाइट्स के ऑफसेट पर एक शब्द। यदि आप हेडर के प्रारूप को देखते हैं, तो यह फ़ील्ड tcp में रिसीवर पोर्ट नंबर से मेल खाती है। हम इसे अधिलेखित कर देते हैं, इसे 11500 पर सेट करते हैं ("22 से 1616 सेट 1616" मोड़)। लेकिन हमने फ़ील्ड बदलने के बाद, हेडर चेकसम बदल जाएगा। इसे पुनर्गणना करने के लिए, पैकेट को "पाइप" पैरामीटर का उपयोग करके सीमम क्रिया पर पुनर्निर्देशित किया जाता है। Csum tcp हैडर के चेकसम की गणना करता है और पैकेट को पैरामीटर के साथ-साथ पाइप पैरामीटर का उपयोग करते हुए पैकेट को रूट करता है। "Mirred" कार्रवाई के परिणामस्वरूप, भेजे गए पैकेट की प्रतियां ifb0 इंटरफ़ेस पर आती हैं।

आइए देखें कि आँकड़ों का विश्लेषण करके सब कुछ कैसे काम करता है, साथ ही साथ ifb0 इंटरफ़ेस पर tcpdump चलाकर:

 #      ~$ tc -s -pf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 terminal flowid ??? (rule hit 102554 success 0) match IP protocol 6 (success 102517 ) match IP src 10.10.20.119/32 (success 0 ) match IP dst 10.10.20.254/32 (success 0 ) match dport 10500 (success 0 ) action order 1: pedit action pipe keys 1 index 66 ref 1 bind 1 installed 132 sec used 132 sec key #0 at 20: val 00002cec mask ffff0000 Action statistics: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 action order 2: csum (tp) action pipe index 29 ref 1 bind 1 installed 132 sec used 132 sec Action statistics: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 action order 3: mirred (Egress Mirror to device ifb0) pipe index 79 ref 1 bind 1 installed 132 sec used 132 sec Action statistics: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 #  tcp  10.10.20.254:10500 ~$ telnet 10.10.20.254 10500 #    ,    #   ifb0 ~$ tcpdump -nvvi ifb0 tcpdump: WARNING: ifb0: no IPv4 address assigned tcpdump: listening on ifb0, link-type EN10MB (Ethernet), capture size 65535 bytes ... 00:46:11.080234 IP (tos 0x10, ttl 64, id 46378, offset 0, flags [DF], proto TCP (6), length 60) 10.10.20.119.36342 > 10.10.20.254.11500: Flags [S], cksum 0x2001 (correct), seq 1542179969, win 14600, options [mss 1460,sackOK,TS val 1417050539 ecr 0,nop,wscale 4], length 0 ... #    ~$ tc -s -pf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 terminal flowid ??? (rule hit 580151 success 12) match IP protocol 6 (success 579716 ) match IP src 10.10.20.119/32 (success 12 ) match IP dst 10.10.20.254/32 (success 12 ) match dport 10500 (success 12 ) action order 1: pedit action pipe keys 1 index 66 ref 1 bind 1 installed 747 sec used 454 sec key #0 at 20: val 00002cec mask ffff0000 Action statistics: Sent 888 bytes 12 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 action order 2: csum (tdp) action pipe index 29 ref 1 bind 1 installed 747 sec used 454 sec Action statistics: Sent 888 bytes 12 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 action order 3: mirred (Egress Mirror to device ifb0) pipe index 79 ref 1 bind 1 installed 747 sec used 454 sec Action statistics: Sent 888 bytes 12 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 


यह मूल रूप से वह सब है जो मैं कार्यों के आवेदन के बारे में बताना चाहता था।

उपयोगी लिंक

LARTC - लिनक्स उन्नत रूटिंग और ट्रैफ़िक नियंत्रण।
Ifb और mirred कार्रवाई का उपयोग करने का एक उदाहरण

Source: https://habr.com/ru/post/In138562/


All Articles