Docker
डॉकर के साथ Iptables
खोज…
परिचय
यह विषय iptables का उपयोग करके बाहरी दुनिया से अपने डॉक कंटेनर तक पहुंच को सीमित करने के बारे में है।
अधीर लोगों के लिए, आप उदाहरण देख सकते हैं। दूसरों के लिए, कृपया नए नियम बनाने के तरीके को समझने के लिए टिप्पणी अनुभाग पढ़ें।
वाक्य - विन्यास
- iptables -I DOCKER [RULE ...] [ACCEPT | DROP] // एक नियम जोड़ने के लिए DOCKER तालिका के शीर्ष पर
- iptables -D DOCKER [RULE ...] [ACCEPT | DROP] // DOCKER तालिका से एक नियम हटाने के लिए
- ipset रिस्टोर </etc/ipfriends.conf // अपने ipset ipfriends को फिर से कॉन्फ़िगर करने के लिए
पैरामीटर
पैरामीटर | विवरण |
---|---|
ext_if | डॉकर होस्ट पर आपका बाहरी इंटरफ़ेस। |
XXX.XXX.XXX.XXX | एक विशेष आईपी जिस पर डॉकर कंटेनर का उपयोग दिया जाना चाहिए। |
YYY.YYY.YYY.YYY | एक और आईपी जिस पर डॉकर कंटेनरों की पहुँच दी जानी चाहिए। |
ipfriends | IPs को परिभाषित करने वाला ipset नाम आपके डॉकर कंटेनर तक पहुंचने की अनुमति देता है। |
टिप्पणियों
समस्या
डॉकटर कंटेनरों के लिए iptables नियमों को कॉन्फ़िगर करना थोड़ा मुश्किल है। सबसे पहले, आपको लगता है कि "क्लासिक" फ़ायरवॉल नियमों को चाल करना चाहिए।
उदाहरण के लिए, मान लेते हैं कि आपने HTTPS के माध्यम से कुछ व्यक्तिगत वेब सेवाओं को उजागर करने के लिए एक nginx-प्रॉक्सी कंटेनर + कई सेवा कंटेनरों को कॉन्फ़िगर किया है। फिर इस तरह का एक नियम केवल आईपी XXX.XXX.XXX.XXX के लिए आपकी वेब सेवाओं तक पहुंच प्रदान करना चाहिए।
$ iptables -A INPUT -i eth0 -p tcp -s XXX.XXX.XXX.XXX -j ACCEPT
$ iptables -P INPUT DROP
यह काम नहीं करेगा, आपके कंटेनर अभी भी सभी के लिए सुलभ हैं।
वास्तव में, डॉकर कंटेनर मेजबान सेवाएं नहीं हैं। वे आपके मेजबान में एक आभासी नेटवर्क पर भरोसा करते हैं, और मेजबान इस नेटवर्क के लिए एक प्रवेश द्वार के रूप में कार्य करता है। और गेटवे के विषय में, रूट किए गए ट्रैफिक को INPUT तालिका द्वारा नियंत्रित नहीं किया जाता है, लेकिन FORWARD तालिका द्वारा, जो नियम को अप्रभावी होने से पहले पोस्ट करता है।
लेकिन यह सब नहीं है। वास्तव में, डॉकटर डेमन बहुत सारे iptables नियम बनाता है जब यह कंटेनर नेटवर्क कनेक्टिविटी से संबंधित अपना जादू करना शुरू करता है। विशेष रूप से, इस नई तालिका में FORWARD तालिका से ट्रैफ़िक अग्रेषित करके कंटेनरों से संबंधित नियमों को संभालने के लिए एक DOCKER तालिका बनाई जाती है।
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:https
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:http
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
समाधान
यदि आप आधिकारिक दस्तावेज ( https://docs.docker.com/v1.5/articles/networking/) की जांच करते हैं, तो एक विशेष आईपी के लिए डॉकर कंटेनर की पहुंच को सीमित करने के लिए पहला समाधान दिया जाता है।
$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
वास्तव में, डॉकर तालिका के शीर्ष पर एक नियम जोड़ना एक अच्छा विचार है। यह डॉकर द्वारा कॉन्फ़िगर किए गए नियमों के साथ हस्तक्षेप नहीं करता है, और यह सरल है। लेकिन दो प्रमुख कमी:
- पहला, क्या होगा यदि आपको एक के बजाय दो आईपी से एक्सेस करने की आवश्यकता है? यहां केवल एक src आईपी को स्वीकार किया जा सकता है, अन्य को रोकने के लिए किसी भी तरीके के बिना गिरा दिया जाएगा।
- दूसरा, क्या होगा यदि आपके डॉकटर को इंटरनेट तक पहुंच की आवश्यकता है? व्यावहारिक रूप से कोई भी अनुरोध सफल नहीं होगा, क्योंकि केवल सर्वर 8.8.8.8 उन्हें जवाब दे सकता है।
- अंत में, क्या होगा यदि आप अन्य लॉजिक्स जोड़ना चाहते हैं? उदाहरण के लिए, HTTP प्रोटोकॉल पर सेवारत अपने वेबसर्वर के लिए किसी भी उपयोगकर्ता को एक्सेस दें, लेकिन बाकी सब को विशेष रूप से आईपी तक सीमित करें।
पहले अवलोकन के लिए, हम ipset का उपयोग कर सकते हैं। उपरोक्त नियम में एक आईपी की अनुमति देने के बजाय, हम पूर्वनिर्धारित ipset से सभी आईपी की अनुमति देते हैं। एक बोनस के रूप में, ipset को iptable नियम को फिर से परिभाषित करने की आवश्यकता के बिना अपडेट किया जा सकता है।
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
दूसरे अवलोकन के लिए, यह फ़ायरवॉल के लिए एक विहित समस्या है: यदि आपको फ़ायरवॉल के माध्यम से सर्वर से संपर्क करने की अनुमति है, तो फ़ायरवॉल को आपके अनुरोध का जवाब देने के लिए सर्वर को अधिकृत करना चाहिए। यह पैकेटों को अधिकृत करके किया जा सकता है जो एक स्थापित कनेक्शन से संबंधित हैं। कर्ता तर्क के लिए, यह देता है:
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
अंतिम अवलोकन एक बिंदु पर केंद्रित है: iptables नियम आवश्यक है। वास्तव में, कुछ कनेक्शनों को स्वीकार करने के लिए अतिरिक्त तर्क (एस्टेब्लिश्ड कनेक्शनों में से एक सहित) को DOCKER तालिका के शीर्ष पर रखा जाना चाहिए, DROP नियम से पहले, जो सभी शेष कनेक्शनों को ipset से मेल नहीं खाने से इनकार करता है।
जैसा कि हम iptable के -I विकल्प का उपयोग करते हैं, जो तालिका के शीर्ष पर नियम सम्मिलित करता है, पिछले iptables नियमों को रिवर्स ऑर्डर से डाला जाना चाहिए:
// Drop rule for non matching IPs
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
// Then Accept rules for established connections
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 3rd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 2nd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 1st custom accept rule
इस सब को ध्यान में रखते हुए, अब आप उन उदाहरणों की जाँच कर सकते हैं जो इस विन्यास को चित्रित करते हैं।
आईपी के एक सेट के लिए डॉक कंटेनर पर पहुंच सीमित करें
सबसे पहले, जरूरत होने पर ipset इंस्टॉल करें। यह कैसे करना है, यह जानने के लिए कृपया अपने वितरण को देखें। एक उदाहरण के रूप में, यहां डेबियन जैसे वितरण के लिए कमान है।
$ apt-get update
$ apt-get install ipset
फिर आईपी युक्त एक ipset को परिभाषित करने के लिए एक कॉन्फ़िगरेशन फ़ाइल बनाएं जिसके लिए आप अपने डॉकर कंटेनर तक पहुंच खोलना चाहते हैं।
$ vi /etc/ipfriends.conf
# Recreate the ipset if needed, and flush all entries
create -exist ipfriends hash:ip family inet hashsize 1024 maxelem 65536
flush
# Give access to specific ips
add ipfriends XXX.XXX.XXX.XXX
add ipfriends YYY.YYY.YYY.YYY
इस ipset को लोड करें।
$ ipset restore < /etc/ipfriends.conf
सुनिश्चित करें कि आपका डॉकर डेमॉन चल रहा है: निम्न कमांड दर्ज करने के बाद कोई त्रुटि नहीं दिखाई जानी चाहिए।
$ docker ps
आप अपने iptables नियमों को सम्मिलित करने के लिए तैयार हैं। आपको आदेश का सम्मान करना चाहिए ।
// All requests of src ips not matching the ones from ipset ipfriends will be dropped.
$ iptables -I DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
// Except for requests coming from a connection already established.
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
यदि आप नए नियम बनाना चाहते हैं, तो आपको नए डालने से पहले आपके द्वारा जोड़े गए सभी कस्टम नियमों को हटाने की आवश्यकता होगी।
$ iptables -D DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
$ iptables -D DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
डोकर डेमॉन शुरू होने पर प्रतिबंध की पहुंच को कॉन्फ़िगर करें
कार्य प्रगति पर है
कुछ कस्टम iptables नियम
कार्य प्रगति पर है