डोकर टूट libvirt पुल नेटवर्क

यह मुद्दा मुझे पागल कर रहा है । मैं उबंटू 18.04 की एक नई स्थापना चलाता हूं:

  • फ़ायरवॉल का प्रबंधन करने के लिए यूएफडब्ल्यू
  • एक br0 पुल
  • lxd और libvirt (KVM)

मैंने स्टॉक की कोशिश की docker.io पैकेज और पैकेज डॉकर का अपना डेब रिपॉजिटरी बनाते हैं ।

मैं चाहता हूं कि ओ अपने पोर्ट को बांधने के लिए आईपी चुनने वाले डॉकर कंटेनरों को तैनात करने में सक्षम हो (जैसे। - पी 10.58.26.6:9,800: 9,800) और फिर यूएफडब्ल्यू के साथ पोर्ट खोलें ।

लेकिन डोकर करने के लिए लगता है बनाने के लिए iptables के नियमों है कि pertubates के br0 पुल (उदाहरण के लिए । होस्ट लिबवर्ट मेहमानों को पिंग नहीं कर सकता)

मैंने चारों ओर देखा है और अच्छा, सुरक्षा जागरूक समाधान नहीं पा रहा हूं ।

मैन्युअल रूप से कर रहा है iptables -I FORWARD -i br0 -o br0 -j ACCEPTलगता है सब कुछ काम करता है ।

सेटिंग भी "iptables": false डॉकर डेमॉन के लिए पुल को सामान्य रूप से व्यवहार करने की अनुमति देता है, लेकिन डॉकर के कंटेनरों के निकास नेटवर्क को तोड़ देता है ।

मुझे यह समाधान मिला है जो एक यूएफडब्ल्यू की फ़ाइल को संपादित करके सरल लग रहा था https://stackoverflow.com/a/51741599/1091772, लेकिन यह बिल्कुल काम नहीं करता ।

रिबूट करने के लिए जीवित रहने के लिए इसे स्थायी रूप से हल करने का सबसे अच्छा अभ्यास और सुरक्षित तरीका क्या होगा ?

संपादित करें:मैंने जोड़ना समाप्त कर दिया -A ufw-before-forward -i br0 -o br0 -j ACCEPT के अंत में /etc/ufw/before.rules प्रतिबद्धता से पहले । क्या मैं इसे एक फिक्स के रूप में मान सकता हूं या यह कुछ मुद्दों को नहीं उठाता है ?

समस्या, वास्तव में एक विशेषता: ब्र_नेटफिल्टर

विवरण से, मेरा मानना है कि एकमात्र तार्किक व्याख्या यह है कि ब्रिज नेटफिल्टर कोड सक्षम है: स्टेटफुल ब्रिज फायरवॉल या लीवरेजिंग के लिए अन्य उपयोगों के बीच इरादा है iptables'पुल पथ से मिलान और लक्ष्य उन सभी को डुप्लिकेट किए बिना (या सक्षम होने के लिए) ebtables. नेटवर्क लेयरिंग की अवहेलना करते हुए, ईथरनेट ब्रिज कोड, नेटवर्क लेयर 2 पर, अब अपकॉल करता है iptables आईपी स्तर पर काम करना, यानी नेटवर्क परत 3। इसे केवल विश्व स्तर पर अभी तक सक्षम किया जा सकता है: या तो होस्ट और प्रत्येक कंटेनर के लिए, या किसी के लिए नहीं । एक बार समझ गया कि क्या चल रहा है और यह जानना कि क्या देखना है, अनुकूलित विकल्प बनाए जा सकते हैं ।

नेटफिल्टर परियोजना विभिन्न का वर्णन करती है ebtables/iptables बातचीत कब ब्र_नेटफिल्टर सक्षम है । विशेष रूप से ब्याज की है धारा 7 यह बताते हुए कि पुल पथ से अनपेक्षित प्रभावों से बचने के लिए कभी-कभी स्पष्ट प्रभाव के बिना कुछ नियमों की आवश्यकता क्यों होती है, जैसे उपयोग करना:

iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -d 172.16.1.0/24 -j ACCEPTiptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE

एक ही लैन पर दो प्रणालियों से बचने के लिए । .. पुल (नीचे उदाहरण देखें) ।

आपकी समस्या से बचने के लिए आपके पास कुछ विकल्प हैं, लेकिन आपके द्वारा लिया गया विकल्प शायद सबसे अच्छा है यदि आप सभी विवरण नहीं जानना चाहते हैं और न ही सत्यापित करें कि क्या कुछ आईपीटीबल्स नियम (कभी-कभी अन्य नामस्थानों में छिपे हुए) बाधित होंगे:

  • स्थायी रूप से रोकें ब्र_नेटफिल्टर मॉड्यूल लोड किया जाना है । आमतौर पर blacklist पर्याप्त नहीं है, install इस्तेमाल होना चाहिए । यह एक विकल्प है जिस पर निर्भर अनुप्रयोगों के लिए मुद्दों का खतरा है ब्र_नेटफिल्टर: जाहिर है, डोकर, Kubernetes, ...

    echo install br_netfilter /bin/true > /etc/modprobe.d/disable-br-netfilter.conf
  • मॉड्यूल लोड करें, लेकिन इसके प्रभावों को अक्षम करें । के लिए iptables'प्रभाव है कि:

    sysctl -w net.bridge.bridge-nf-call-iptables=0

    यदि इसे स्टार्टअप पर डालते हैं, तो मॉड्यूल को पहले लोड किया जाना चाहिए या यह टॉगल अभी तक मौजूद नहीं होगा ।

ये दो पिछले विकल्प निश्चित रूप से बाधित होंगे iptables मैच -m physdev: द एक्सटी_फिसदेव मॉड्यूल जब खुद लोड होता है, तो ऑटो-लोड होता है ब्र_नेटफिल्टर मॉड्यूल (यह तब भी होगा जब कंटेनर से जोड़ा गया नियम लोडिंग को ट्रिगर करता है) । अब ब्र_नेटफिल्टर लोड नहीं किया जाएगा, -m physdev शायद कभी मेल नहीं खाएगा।

  • जरूरत पड़ने पर ब्र_नेटफिल्टर के प्रभाव के आसपास काम करें, जैसे ओपी: उन स्पष्ट नो-ऑप नियमों को विभिन्न श्रृंखलाओं में जोड़ें (प्रीरूटिंग, फॉरवर्ड, पोस्टरूटिंग) जैसा कि वर्णित है धारा 7. उदाहरण के लिए:

    iptables -t nat -A POSTROUTING -s 172.18.0.0/16 -d 172.18.0.0/16 -j ACCEPTiptables -A FORWARD -i br0 -o br0 -j ACCEPT

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

  • पुल पर एक आईपी मत डालो: उस आईपी को एक के एक छोर पर रखो veth पुल पर इसके दूसरे छोर के साथ इंटरफ़ेस: यह सुनिश्चित करना चाहिए कि पुल रूटिंग के साथ बातचीत नहीं करेगा, लेकिन ऐसा नहीं है कि अधिकांश कंटेनर/वीएम आम उत्पाद क्या कर रहे हैं ।

  • आप पुल को अपने अलग-थलग नेटवर्क नेमस्पेस में भी छिपा सकते हैं (यह केवल तभी मददगार होगा जब आप दूसरे से अलग होना चाहते हैं ebtables इस बार नियम)।

  • सब कुछ स्विच करें nftables जो बताए गए लक्ष्यों में से इनसे बचेंगे ब्रिज इंटरैक्शन मुद्दे. अभी के लिए ब्रिज फायरवॉल के पास कोई स्टेटफुल सपोर्ट उपलब्ध नहीं है, यह अभी भी है WIP लेकिन उपलब्ध होने पर क्लीनर होने का वादा किया जाता है, क्योंकि कोई "अपकॉल"नहीं होगा ।

आपको यह खोजना चाहिए कि लोडिंग को क्या ट्रिगर करता है ब्र_नेटफिल्टर (जैसे: -m physdev) और देखें कि आप इससे बच सकते हैं या नहीं, यह चुनने के लिए कि कैसे आगे बढ़ना है ।


नेटवर्क नामस्थान के साथ उदाहरण

आइए नेटवर्क नेमस्पेस का उपयोग करके कुछ प्रभावों को पुन: उत्पन्न करें । ध्यान दें कि कहीं भी नहीं ebtables नियम का उपयोग किया जाएगा । यह भी ध्यान दें कि यह उदाहरण सामान्य विरासत पर निर्भर करता है iptables, नहीं iptables पर nftables जैसा कि डेबियन बस्टर पर डिफ़ॉल्ट रूप से सक्षम है ।

आइए कई कंटेनर उपयोगों के समान एक साधारण मामले को पुन: पेश करें: एक राउटर 192.168.0.1/192.0.2.100 दो मेजबानों के साथ एनएटी कर रहा है: 192.168.0.101 और 192.168.0.102, राउटर पर एक पुल के साथ जुड़ा हुआ है । दो मेजबान पुल के माध्यम से सीधे एक ही लैन पर संवाद कर सकते हैं ।

#!/bin/shfor ns in host1 host2 router; do    ip netns del $ns 2>/dev/null || :    ip netns add $ns    ip -n $ns link set lo updoneip netns exec router sysctl -q -w net.ipv4.conf.default.forwarding=1ip -n router link add bridge0 type bridgeip -n router link set bridge0 upip -n router address add 192.168.0.1/24 dev bridge0for i in 1 2; do    ip -n host$i link add eth0 type veth peer netns router port$i    ip -n host$i link set eth0 up    ip -n host$i address add 192.168.0.10$i/24 dev eth0    ip -n host$i route add default via 192.168.0.1    ip -n router link set port$i up master bridge0done#to mimic a standard NAT router, iptables rule voluntarily made as it is to show the last "effect"ip -n router link add name eth0 type dummyip -n router link set eth0 upip -n router address add 192.0.2.100/24 dev eth0ip -n router route add default via 192.0.2.1ip netns exec router iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE

चलो कर्नेल मॉड्यूल लोड करते हैं ब्र_नेटफिल्टर (यह सुनिश्चित करने के लिए कि यह बाद में नहीं होगा) और इसके प्रभावों को (प्रति-नाम स्थान नहीं) टॉगल के साथ अक्षम करें पुल-एनएफ-कॉल-iptables, केवल प्रारंभिक नामस्थान में उपलब्ध है:

modprobe br_netfiltersysctl -w net.bridge.bridge-nf-call-iptables=0

चेतावनी: फिर, यह बाधित कर सकता है iptables जैसे नियम -m physdev मेजबान पर या कंटेनरों में कहीं भी जो भरोसा करते हैं ब्र_नेटफिल्टर लोड और सक्षम।

आइए कुछ आईसीएमपी पिंग ट्रैफिक काउंटर जोड़ें।

ip netns exec router iptables -A FORWARD -p icmp --icmp-type echo-requestip netns exec router iptables -A FORWARD -p icmp --icmp-type echo-reply

चलो पिंग करते हैं:

# ip netns exec host1 ping -n -c2 192.168.0.102PING 192.168.0.102 (192.168.0.102) 56(84) bytes of data.64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.047 ms64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.058 ms--- 192.168.0.102 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1017msrtt min/avg/max/mdev = 0.047/0.052/0.058/0.009 ms

काउंटर मैच नहीं होंगे:

# ip netns exec router iptables -v -S FORWARD-P FORWARD ACCEPT -c 0 0-A FORWARD -p icmp -m icmp --icmp-type 8 -c 0 0-A FORWARD -p icmp -m icmp --icmp-type 0 -c 0 0

आइए सक्षम करें पुल-एनएफ-कॉल-iptables और फिर से पिंग:

# sysctl -w net.bridge.bridge-nf-call-iptables=1net.bridge.bridge-nf-call-iptables = 1# ip netns exec host1 ping -n -c2 192.168.0.102PING 192.168.0.102 (192.168.0.102) 56(84) bytes of data.64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.094 ms64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.163 ms--- 192.168.0.102 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1006msrtt min/avg/max/mdev = 0.094/0.128/0.163/0.036 ms

इस बार स्विच किए गए पैकेट को आईपीटेबल्स के फिल्टर/फॉरवर्ड चेन में एक मैच मिला:

# ip netns exec router iptables -v -S FORWARD-P FORWARD ACCEPT -c 4 336-A FORWARD -p icmp -m icmp --icmp-type 8 -c 2 168-A FORWARD -p icmp -m icmp --icmp-type 0 -c 2 168

आइए एक ड्रॉप पॉलिसी डालें (जो डिफ़ॉल्ट काउंटरों को शून्य करता है) और पुनः प्रयास करें:

# ip netns exec host1 ping -n -c2 192.168.0.102PING 192.168.0.102 (192.168.0.102) 56(84) bytes of data.--- 192.168.0.102 ping statistics ---2 packets transmitted, 0 received, 100% packet loss, time 1008ms# ip netns exec router iptables -v -S FORWARD-P FORWARD DROP -c 2 168-A FORWARD -p icmp -m icmp --icmp-type 8 -c 4 336-A FORWARD -p icmp -m icmp --icmp-type 0 -c 2 168

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

# ip netns exec router iptables -A FORWARD -i bridge0 -o bridge0 -j ACCEPT# ip netns exec host1 ping -n -c2 192.168.0.102PING 192.168.0.102 (192.168.0.102) 56(84) bytes of data.64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.132 ms64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.123 ms--- 192.168.0.102 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1024msrtt min/avg/max/mdev = 0.123/0.127/0.132/0.012 ms# ip netns exec router iptables -v -S FORWARD-P FORWARD DROP -c 0 0-A FORWARD -p icmp -m icmp --icmp-type 8 -c 6 504-A FORWARD -p icmp -m icmp --icmp-type 0 -c 4 336-A FORWARD -i bridge0 -o bridge0 -c 4 336 -j ACCEPT

आइए देखें कि होस्ट 2 से पिंग के दौरान होस्ट 1 पर वास्तव में क्या प्राप्त हुआ है:

# ip netns exec host2 tcpdump -l -n -s0 -i eth0 -p icmptcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes02:16:11.068795 IP 192.168.0.1 > 192.168.0.102: ICMP echo request, id 9496, seq 1, length 6402:16:11.068817 IP 192.168.0.102 > 192.168.0.1: ICMP echo reply, id 9496, seq 1, length 6402:16:12.088002 IP 192.168.0.1 > 192.168.0.102: ICMP echo request, id 9496, seq 2, length 6402:16:12.088063 IP 192.168.0.102 > 192.168.0.1: ICMP echo reply, id 9496, seq 2, length 64

... स्रोत के बजाय 192.168.0.101। मास्करेड नियम को पुल पथ से भी बुलाया गया था । इससे बचने के लिए या तो जोड़ें (जैसा कि समझाया गया है धारा 7उदाहरण) पहले एक अपवाद नियम, या एक गैर-पुल आउटगोइंग इंटरफ़ेस राज्य, यदि संभव हो तो (अब यह उपलब्ध है आप भी उपयोग कर सकते हैं -m physdev अगर यह एक पुल होना है । ..).


बेतरतीब ढंग से संबंधित:

LKML/नेटफिल्टर-देव: ब्र_नेटफिल्टर: गैर-प्रारंभिक नेटएनएस में सक्षम करें: यह विश्व स्तर पर प्रति नाम स्थान पर इस सुविधा को सक्षम करने में मदद करेगा, इस प्रकार मेजबानों और कंटेनरों के बीच बातचीत को सीमित करेगा ।

नेटफिल्टर-देव: नेटफिल्टर: physdev: आराम br_netfilter निर्भरता: केवल एक गैर-मौजूदा को हटाने का प्रयास physdev नियम समस्याएं पैदा कर सकता है ।

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

यदि उपरोक्त खतरे आपकी समस्या को हल नहीं कर रहे हैं, तो यहां बताया गया है कि मैंने अपने डेबियन खिंचाव पर समस्या का समाधान कैसे किया ।

  • 1, अपने वर्तमान आईपीटीबल्स को सहेजें

    iptables-save > your-current-iptables.rules
  • 2, हटाएं सभी डॉकर ने बनाए नियम

    iptables -D <DOCKER-CHAIN-RULES> <target-line-number>
  • 3, इनपुट, फॉरवर्ड और आउटपुट में किसी भी ट्रैफ़िक को स्वीकार करने के लिए आईटीपेबल्स नियम जोड़ें

    iptables -I INPUT -j ACCEPTiptables -I FORWARD -j ACCEPTiptables -I OUTPUT -j ACCEPT
  • 4, अपने डॉकर को पुनरारंभ करें

    service docker restart

एक बार चरण 3 पूरा होने के बाद, आप अपने अवरुद्ध लिबवर्ट केवीएम होस्ट को दूसरे पीसी से पिंग कर सकते हैं, आपको आईसीएमपी प्रतिक्रियाएं दिखाई देंगी ।

डॉकर को पुनरारंभ करने से इसके आवश्यक आईपीटीबल्स नियम भी आपकी मशीन में वापस आ जाएंगे लेकिन यह आपके ब्रिज्ड केवीएम होस्ट को और अधिक अवरुद्ध नहीं करेगा ।

यदि उपरोक्त समाधान आपके लिए काम नहीं कर रहा है, तो आप निम्न कमांड का उपयोग करके आईपीटीबल्स को पुनर्स्थापित कर सकते हैं:

  • बहाल iptables

    iptables-restore < your-current-iptables.rules