एक ही होस्ट पर दो वर्चुअल मशीनें किसी ब्रिज से होकर LAN तक पहुँचती हैं, और ip forward चेन में रखा गया नियम ऐसा काउंटर दिखाता है जो कभी नहीं हिलता। फ़्रेम असली हैं, ट्रैफ़िक गुज़र रहा है, और नियम बस उसके रास्ते पर नहीं है। Linux ब्रिज ट्रैफ़िक को जिन दो तरीक़ों से बाहर लाता है, उनकी तुलना इस ख़ामोशी को समझाती है, और यह भी समझाती है कि एक पुराना मॉड्यूल लोड करना जितना आसान लगता है उससे बुरा जवाब क्यों है।

एक होस्ट से होकर दो रास्ते

एक पैकेट इस होस्ट को दो बहुत अलग तरीक़ों से छोड़ सकता है, और यही अंतर तय करता है कि कौन-से हुक उसे देखेंगे। अगर गंतव्य किसी भौतिक पोर्ट के पार है और फ़्रेम ब्रिज के दो पोर्टों के बीच स्विच होता है, तो होस्ट एक Ethernet फ़्रेम आगे भेजता है; रूटिंग कोड से नहीं पूछा जाता, और कोई रूटेड हॉप नहीं होता। अगर गंतव्य होस्ट स्वयं है, या टनल इंटरफ़ेस से पहुँचा जाने वाला नेटवर्क है, तो पैकेट रूट होता है और IP परत के हुक वास्तव में लागू होते हैं। इस काँटे को याद रखें, क्योंकि चेन और परिवारों के बारे में हर बाद का सवाल इसी से निकलता है कि फ़्रेम दो रास्तों में से कौन-सा लेता है।

यही भेद उस नियम के पीछे की पूरी कहानी है जो कुछ भी नहीं गिनता। veth9a1 से enp3s0 तक ब्रिज किया गया फ़्रेम IP स्टैक को नहीं, ब्रिज को पार करता है, इसलिए ip forward चेन को मिलाने के लिए कुछ नहीं दिखता। किसी पुराने उदाहरण में इंटरफ़ेस के नाम यह तय नहीं करते कि आपके पास कौन-सा रास्ता है, और इसीलिए पहला क़दम नियम-समुच्चय की जगह टोपोलॉजी देखना है।

टनल एक तीसरा मामला जोड़ती है जो नाम देने योग्य है। TUN डिवाइस होस्ट को IP पैकेट सौंपता है, इसलिए वे रूट होते हैं और वाक़ई IP चेन से गुज़रते हैं, जबकि ब्रिज से जुड़ा TAP डिवाइस फ़्रेम सौंपता है और ब्रिज वाले मामले की तरह व्यवहार करता है। डिवाइस का प्रकार, उत्पाद का नाम नहीं, यह तय करता है।

उन दो परिवारों की तुलना करें जो ब्रिज किया गया फ़्रेम देख सकते हैं

Linux nftables के bridge परिवार के ज़रिए मूल ब्रिज फ़िल्टरिंग का समर्थन करता है, और उड़ान में फ़्रेम जाँचने और गिराने के लिए उसे किसी पुराने मॉड्यूल की ज़रूरत नहीं है। कर्नेल का अपना ब्रिज दस्तावेज़ीकरण सीधे यही सिफ़ारिश करता है, जिसे किसी खोज परिणाम के आपको मॉड्यूल लोड करने के लिए कहने से पहले जानना फ़ायदेमंद है।

Observation pointWhat it seesWhat it costs
nftables bridge family chainsEthernet frames forwarded between bridge ports, in both directionsRules must be written in bridge syntax with link-layer matches
Legacy br_netfilter plus an ip chainBridged IPv4 and IPv6 packets, re-exposed through IP-layer hooksExisting host rules may begin matching traffic they never saw before
inet chain for routed trafficPackets the host routes, including traffic arriving from a TUN deviceNo visibility into purely switched frames

iptables के बजाय nft कमांड इस्तेमाल करना अपने आप में नियम को सही परिवार में नहीं रखता। bridge परिवार में घोषित चेन फ़्रेम देखती है; ip, ip6 या inet में घोषित चेन उन्हें नहीं देखती, चाहे उसे किसी भी बाइनरी ने बनाया हो। परिवार चेन का गुण है, उसे टाइप करने वाले टूल का नहीं।

पुराना रास्ता अलग तरह से काम करता है, और इसीलिए आदत से पक्ष चुनने के बजाय तुलना करनी चाहिए। br_netfilter लोड करने और bridge-nf-call सेटिंग्स सक्षम करने से ब्रिज किया गया IPv4 और IPv6 ट्रैफ़िक फिर से IP परत के हुकों के ज़रिए बाहर आता है, ताकि एक साधारण iptables नियम आख़िरकार उससे मिल सके। फ़्रेम नहीं बदलते; जिन हुकों से वे गुज़रते हैं वह समुच्चय बदलता है, जिसका मतलब है कि हर मौजूदा होस्ट नियम के पास अब नया दर्शक-वर्ग है।

नियम जोड़ने से पहले प्रभावी रास्ता पढ़ें

तीन कमांड तय करते हैं कि आप कहाँ हैं: ब्रिज किससे जुड़ा है, पुराना मॉड्यूल सक्रिय है या नहीं, और bridge परिवार में कौन-सी चेन पहले से हैं। कुछ भी लिखने से पहले उन्हें चलाएँ, क्योंकि जवाब ही तय करता है कि आप दो डिज़ाइनों में से किसे बढ़ा रहे हैं। यह क़दम छोड़ना ही वह तरीक़ा है जिससे सही नियम ऐसी चेन में पहुँच जाता है जिससे कुछ भी नहीं गुज़रता।

bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"

आउटपुट मामलों को साफ़-साफ़ अलग करता है। ब्रिज के नीचे सूचीबद्ध पोर्ट बताते हैं कि कौन-से इंटरफ़ेस स्विच हो रहे हैं; ख़ाली lsmod परिणाम का मतलब है ब्रिज किए गए फ़्रेमों की IP परत पर कोई दृश्यता नहीं; मौजूदा bridge परिवार की forward चेन का मतलब है कि नीति का स्वामी पहले से है और आपका नियम अपनी नई चेन में नहीं, वहीं जाता है।

फिर एक ऐसा नियम जोड़ें जिसे वापस पढ़ना आसान हो, काउंटर के साथ और फ़ैसला बदले बिना, और एक प्रतिनिधि प्रवाह ब्रिज से गुज़ारें। हिलता हुआ काउंटर साबित करता है कि फ़्रेम नियम तक पहुँचा। बस इतना ही वह साबित करता है, इसलिए अस्वीकृत रास्ते के साथ भी आगे बढ़ें, क्योंकि सब कुछ स्वीकार करने वाली नीति भी हिलता हुआ काउंटर पैदा करती है।

nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter accept

पुराना मॉड्यूल व्यवहार कहाँ बदलता है

चालू ब्रिज पर पुराना रास्ता सक्षम करना दृश्यता जोड़ने की तटस्थ क्रिया नहीं है। जो नियम पहले ब्रिज ट्रैफ़िक के लिए अगम्य थे वे गम्य हो जाते हैं, जिनमें दूसरे इंटरफ़ेस के लिए लिखे गए होस्ट नियम भी शामिल हैं, और ip forward चेन की डिफ़ॉल्ट drop नीति अचानक उन फ़्रेमों पर लागू हो सकती है जो पहले बिना छुए गुज़रते थे। जिस होस्ट का प्रबंधन उसी ब्रिज से होता है, वहाँ नतीजा कंसोल के बिना लॉकआउट है। यह कोई काल्पनिक विफलता-विधा नहीं है; यह उस मशीन पर हुकों का समुच्चय बढ़ाने का सामान्य परिणाम है जहाँ आप उसी रास्ते से पहुँचते हैं जिसे आपने अभी-अभी बढ़ाया है।

अधिक सुरक्षित क्रम यह है कि तय करें कि नीति किस परिवार की है, नियम वहीं लिखें, और कोई भी sysctl बदलने से पहले एक स्वतंत्र पुनर्प्राप्ति रास्ता रखें। अगर दो परिवार नियम रखते हैं, तो दस्तावेज़ित करें कि कौन आधिकारिक है; दो अतिव्यापी नीतियाँ ही वह तरीक़ा हैं जिससे पैकेट एक जगह स्वीकार और दूसरी जगह अस्वीकार होता है, बिना पढ़ने के लिए एक भी फ़ाइल के।

अलगाव को अपने आप में अभी भी पूरा डिज़ाइन चाहिए। एक स्रोत को एक गंतव्य तक अनुमति देना सिर्फ़ यह साबित करता है कि एक प्रवाह काम करता है, जबकि अपेक्षा आमतौर पर यह होती है कि कोई VM अपने पड़ोसियों या होस्ट तक न पहुँच सके। अस्वीकृति नियमों के काउंटर स्वीकृति नियम के काउंटर से ज़्यादा मायने रखते हैं, क्योंकि स्वीकृति काउंटर वही है जिसके हिलने की आपको पहले से उम्मीद थी।

अंत में, होस्ट-इनपुट मामले को अलग रखें। ब्रिज के अपने IP पर पता किया गया ट्रैफ़िक input पर आता है, forward पर नहीं, और forward का नियम उसे कभी नहीं देखेगा, चाहे आप कोई भी परिवार चुनें। तीन मामले, दो परिवार, एक सबक़: रास्ता हुक तय करता है, और हुक तय करता है कि आपका नियम है भी या नहीं।

संबंधित लेख