Iptables के साथ डॉकटर कंटेनर के बाहर के कनेक्शन को सीमित करने के लिए कदम?


20

मेरा लक्ष्य सिर्फ कुछ सार्वजनिक आईपी पतों के लिए डॉकटर कंटेनरों तक पहुंच को सीमित करना है। क्या मेरे लक्ष्य को पूरा करने के लिए एक सरल, दोहराने योग्य प्रक्रिया है? डॉकर के डिफ़ॉल्ट विकल्पों का उपयोग करते समय केवल iptables की मूल बातें समझना, मुझे बहुत मुश्किल लग रहा है।

मैं एक कंटेनर चलाना चाहता हूं, इसे सार्वजनिक इंटरनेट पर दृश्यमान बना सकता हूं, लेकिन केवल चयनित होस्ट से कनेक्शन की अनुमति देता हूं। मैं REJECT की डिफ़ॉल्ट INPUT नीति सेट करने की अपेक्षा करूंगा और उसके बाद ही अपने मेजबानों से कनेक्शन की अनुमति दूंगा। लेकिन डॉकर के NAT नियम और श्रृंखलाएं रास्ते में आती हैं और मेरे INPUT नियमों की अनदेखी की जाती है।

क्या कोई व्यक्ति इस बात का उदाहरण दे सकता है कि निम्नलिखित मान्यताओं को देखते हुए मेरे लक्ष्य को कैसे पूरा किया जाए?

  • Eth0 पर सार्वजनिक आईपी 80.80.80.80 होस्ट करें
  • Eth1 पर निजी IP 192.168.1.10 होस्ट करें
  • docker run -d -p 3306:3306 mysql
  • मेजबान 4.4.4.4 और 8.8.8.8 को छोड़कर होस्ट / कंटेनर 3306 के सभी कनेक्शन को अवरुद्ध करें

मुझे कंटेनर को केवल स्थानीय आईपी पते से बांधने में खुशी हो रही है, लेकिन यह सुनिश्चित करने के लिए निर्देशों की आवश्यकता होगी कि कैसे iptables को नियमों को ठीक से स्थापित करने के लिए जो डॉक प्रक्रिया और होस्ट पुनरारंभ हो।

धन्यवाद!

जवाबों:


15

गोदी के फ़ायरवॉल नियमों के साथ काम करते समय दो बातों को ध्यान में रखें:

  1. डॉकटर द्वारा आपके नियमों की अनदेखी से बचने के लिए, DOCKER-USERश्रृंखला का उपयोग करें
  2. डॉकर तालिका की PREROUTINGश्रृंखला में पोर्ट-मैपिंग करता है nat। इस से पहले होता है filterनियम है, तो --destऔर --dportआंतरिक IP और कंटेनर के बंदरगाह देखेंगे। मूल गंतव्य तक पहुंचने के लिए, आप उपयोग कर सकते हैं -m conntrack --ctorigdstport

उदाहरण के लिए:

iptables -A DOCKER-USER -i eth0 -s 8.8.8.8 -p tcp -m conntrack --ctorigdstport 3306 --ctdir ORIGINAL -j ACCEPT
iptables -A DOCKER-USER -i eth0 -s 4.4.4.4 -p tcp -m conntrack --ctorigdstport 3306 --ctdir ORIGINAL -j ACCEPT
iptables -A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 3306 --ctdir ORIGINAL -j DROP

नोट: इसके बिना --ctdir ORIGINAL, यह किसी अन्य सर्वर पर कंटेनर से 3306 पोर्ट के लिए कनेक्शन के लिए वापस आने वाले उत्तर पैकेट से भी मेल खाएगा, जो कि निश्चित रूप से आप क्या चाहते हैं! आपको इसकी कड़ाई से ज़रूरत नहीं है अगर मेरी तरह आपका पहला नियम है -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT, जैसा कि सभी उत्तर पैकेटों के साथ होगा, लेकिन यह अभी --ctdir ORIGINALभी वैसे भी उपयोग करने के लिए सुरक्षित होगा ।


यह शामिल करने के लिए संपादित किया जाना चाहिए --ctdir? मैं उपयोग करता हूं-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
lonix

@Ionix, हाँ, यह होना चाहिए, हालाँकि मैंने अभी-अभी काम किया है क्यों यह मुझे भ्रमित कर रहा है। मैंने थोड़ा स्पष्टीकरण जोड़ा है।
सिस्टमपारॉक्स

1
ध्यान दें कि डिफ़ॉल्ट DOCKER-USERतालिका में प्रविष्टि है: -A DOCKER-USER -j RETURNयदि आप उपयोग करते हैं तो ऊपर से पहले चलेंगे -A। एक समाधान यह है कि सिर को उल्टे क्रम में नियम से डालें -I
BMitch

@BMitch या इससे भी बेहतर अभी तक , सभी नियमों को एक नई FILTERSश्रृंखला में जोड़ें , और -Iनए नियमों को सम्मिलित करें (जैसे आपने कहा था), इसे कूदने के लिए:-I INPUT -j FILTERS-I DOCKER-USER -i eth0 -j FILTERS
lonix

@BMitch हालाँकि, मैंने अभी-अभी अपने सर्वर की जाँच की है, और वापसी नियम नहीं है, हो सकता है कि नवीनतम docker संस्करण अब इसमें सम्मिलित न हो? अच्छा विचार -Iहालांकि उपयोग करने के लिए , बस सुरक्षित होने के लिए।
लोनिक्स

8

Docker v.17.06 के साथ एक नई iptables श्रृंखला है जिसे DOCKER-USER कहा जाता है। यह एक आपके कस्टम नियमों के लिए है: https://docs.docker.com/network/iptables/

श्रृंखला DOCKER के विपरीत यह कंटेनरों के निर्माण / शुरू करने पर रीसेट नहीं होता है। इसलिए आप डॉकटर को स्थापित करने और कंटेनरों को शुरू करने से पहले सर्वर को प्रोविजन करने के लिए अपने iptables config / script में इन पंक्तियों को जोड़ सकते हैं:

-N DOCKER
-N DOCKER-ISOLATION
-N DOCKER-USER
-A DOCKER-ISOLATION -j RETURN
-A DOCKER-USER -i eth0 -p tcp -m tcp --dport 3306 -j DROP
-A DOCKER-USER -j RETURN

अब MySQL के लिए पोर्ट बाहरी एक्सेस (eth0) से अवरुद्ध है, यहां तक ​​कि विचारक भी दुनिया के लिए पोर्ट खोलता है। (ये नियम मानते हैं, आपका बाहरी इंटरफ़ेस eth0 है)

आखिरकार, आपको iptables को फिर से साफ करना होगा, पहले docker सेवा को फिर से शुरू करें, अगर आपने इसे बहुत ज्यादा गड़बड़ कर दिया है जैसा कि मैंने पोर्ट को लॉक करने की कोशिश की है।


मुझे याद है कि क्यों यह डॉकर-USER तालिका किसी भी अन्य उपयोगकर्ता-गयी तालिका से भिन्न है .. इसमें कोई पूर्व फ़िल्टर लागू नहीं है, इसलिए आपको अभी भी इंटरफ़ेस नामों को स्वयं निर्दिष्ट करना होगा। यदि आप "MY-CHAIN" बनाते हैं और इसे FORWARD श्रृंखला में सम्मिलित करते हैं, तो इसका परिणाम वही होगा, नहीं?
कॉलिनम

हां, इससे फर्क पड़ता है, क्योंकि डॉकर ने DOCKER-USER चेन को FORWARD चेन -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION में डाला है : इसीलिए, DOCKER चेन से पहले कस्टम निर्देशों को निष्पादित किया जाता है।
18:

ध्यान दें कि यदि आप --dportDOCKER-USER के अंदर उपयोग करते हैं तो इसे कंटेनर सेवा के आंतरिक आईपी ​​से मेल खाना चाहिए , कि उजागर पोर्ट से। ये अक्सर मेल खाते हैं लेकिन हमेशा नहीं और यह आसानी से अन्य सेवाओं के साथ संघर्ष कर सकता है इसलिए मैं अभी भी यह तर्क देता हूं कि यह डॉकर-यूएसईआर समाधान आधा बेक्ड है।
कॉलिनएम

4

अद्यतन : 2015 में मान्य होने पर, यह समाधान अब इसे करने का सही तरीका नहीं है।

इस सवाल का जवाब डॉकर के डॉक्यूमेंटेशन https://docs.docker.com/articles/networking/#the-world पर लगता है

डॉकर के आगे के नियम डिफ़ॉल्ट रूप से सभी बाहरी स्रोत आईपी को अनुमति देते हैं। कंटेनरों तक पहुँचने के लिए केवल एक विशिष्ट आईपी या नेटवर्क की अनुमति देने के लिए, डॉकर फ़िल्टर श्रृंखला के शीर्ष पर एक नकारात्मक नियम डालें। उदाहरण के लिए, बाहरी उपयोग को प्रतिबंधित करने के लिए जैसे कि केवल स्रोत आईपी 8.8.8.8 कंटेनर तक पहुंच सकते हैं, निम्नलिखित नियम जोड़ा जा सकता है:iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

मैंने जो किया वह पूरा किया:

iptables -I DOCKER -i eth0 -s 8.8.8.8 -p tcp --dport 3306 -j ACCEPT
iptables -I DOCKER -i eth0 -s 4.4.4.4 -p tcp --dport 3306 -j ACCEPT
iptables -I DOCKER 3 -i eth0 -p tcp --dport 3306 -j DROP

मैंने --iptablesया --iccविकल्पों को नहीं छुआ ।


1
यदि आप करते हैं iptables -vnL DOCKER, तो गंतव्य पोर्ट कंटेनर के भीतर सभी पोर्ट हैं। अगर मुझे वह अधिकार मिलता है, तो इसका मतलब है कि ऊपर दिए गए नियम केवल 3306कंटेनर के भीतर पोर्ट को प्रभावित करेंगे - यानी, यदि आप -p 12345:3306अपने कंटेनर में थे, तो आपका नियम अभी भी एक्सेस लॉक करने के लिए आवश्यक --dport 12345होगा (यानी काम नहीं करेगा) , क्योंकि DOCKER श्रृंखला के ACCEPT नियम NAT हैं।
सूर्यास्त

यह सही है, नियमों को कंटेनरों के भीतर बंदरगाहों से संबंधित होना चाहिए।
GGGforce

1
हुम, यह बदसूरत की तरह है यदि आप कई कंटेनर चलाते हैं, जो कहते हैं, रिवर्स प्रॉक्सिंग करने के लिए एक आंतरिक NGINX (जैसे Zabbix, एक कस्टम लोड बैलेंसर, आदि) करते हैं क्योंकि यह आपको कंटेनर के आईपी को पहले से जानना होगा। मैं अभी भी उस समस्या के समाधान की तलाश कर रहा हूं, जिसकी आवश्यकता नहीं है --iptables=false, क्योंकि यह उन सभी का सबसे बुरा विकल्प है।
sunside

धन्यवाद! आपने कई घंटों की खोज के बाद मेरा मुद्दा हल किया है। अब मैं अंततः MySQL को पूरी दुनिया के लिए नरम अंडरबेली को उजागर किए बिना अपने घर के आईपी पते पर जेल करने में सक्षम हूं।
मैट कैवानघ

1
DOCKER श्रृंखला को उपयोगकर्ता द्वारा सीधे हेरफेर नहीं किया जाना चाहिए! उसके लिए DOCKER-USER श्रृंखला का उपयोग करें। स्वीकृत उत्तर की जांच करें।
पॉल-सेबेस्टियन मैनोल

3

अद्यतन: जबकि यह उत्तर अभी भी @SystemParadox द्वारा उत्तर के साथ मान्य है, DOCKER-USERसंयोजन --ctorigdstportबेहतर है।

यहां एक समाधान है जो पुनरारंभ के बीच अच्छी तरह से बना रहता है और आपको आंतरिक बंदरगाह के बजाय उजागर बंदरगाह को प्रभावित करने की अनुमति देता है ।

iptables -t mangle -N DOCKER-mysql iptables -t mangle -A DOCKER-mysql -s 22.33.44.144/32 -j RETURN iptables -t mangle -A DOCKER-mysql -s 22.33.44.233/32 -j RETURN iptables -t mangle -A DOCKER-mysql -j DROP iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 3306 -j DOCKER-mysql

मैंने एक डॉकर छवि बनाई है जो इस विधि का उपयोग आपके लिए iptables को स्वचालित रूप से प्रबंधित करने के लिए करती है, पर्यावरण चर या गतिशील रूप से etcd (या दोनों) का उपयोग करके:

https://hub.docker.com/r/colinmollenhour/confd-firewall/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.