डॉकटर और सुरक्षित पासवर्ड


162

मैं हाल ही में डॉकटर के साथ कुछ सेवाओं के निर्माण के साथ प्रयोग कर रहा हूं, जिनके साथ खेलने के लिए और एक चीज जो मुझे कचोटती रहती है, वह है कि मैं डॉकरफाइल में पासवर्ड डाल रहा हूं। मैं एक डेवलपर हूं, इसलिए स्रोत में पासवर्ड संग्रहीत करना चेहरे में एक पंच की तरह लगता है। क्या यह भी एक चिंता का विषय होना चाहिए? क्या डॉकरफाइल्स में पासवर्ड को संभालने के लिए कोई अच्छा सम्मेलन है?


7
डॉकटर और रहस्यों के बारे में सर्वोत्तम प्रथाओं के लिए गिथब के अनुरोध पर एक खुला मुद्दा है, मुद्दा यहां है: github.com/docker/docker/issues/13490
लुइस बियानचिन

जवाबों:


92

निश्चित रूप से यह एक चिंता का विषय है। Dockerfiles को सामान्यतः रिपॉजिटरी में चेक किया जाता है और अन्य लोगों के साथ साझा किया जाता है। एक विकल्प है कि किसी भी क्रेडेंशियल (उपयोगकर्ता नाम, पासवर्ड, टोकन, कुछ भी संवेदनशील) को रनवे पर पर्यावरण चर के रूप में प्रदान किया जाए । यह -eतर्क (सीएलआई पर अलग-अलग संस्करणों के लिए) या --env-fileतर्क (एक फ़ाइल में कई चर के लिए ) के माध्यम से संभव है docker run। डॉकटर-कम्पोज़ के साथ पर्यावरण का उपयोग करने के लिए इसे पढ़ें ।

यदि --env-fileनिश्चित रूप से कोई उपयोग करता है psया लॉग में दिखाई दे रहा है, तो इससे बचाव के लिए यह निश्चित रूप से सुरक्षित विकल्प है set -x

हालाँकि, env var विशेष रूप से सुरक्षित नहीं हैं। वे के माध्यम से दिखाई दे रहे हैं docker inspect, और इसलिए वे किसी भी उपयोगकर्ता के लिए उपलब्ध हैं जो dockerकमांड चला सकते हैं । (बेशक, किसी भी उपयोगकर्ता जो dockerहोस्ट पर एक्सेस करता है, वैसे भी रूट होता है।)

मेरा पसंदीदा पैटर्न एक आवरण स्क्रिप्ट का उपयोग करना है ENTRYPOINTया CMD। आवरण स्क्रिप्ट पहले किसी बाहरी स्थान से गुप्त समय में कंटेनर में आयात कर सकती है, फिर आवेदन निष्पादित करती है, रहस्य प्रदान करती है। इसके सटीक मैकेनिक्स आपके रन टाइम वातावरण के आधार पर भिन्न होते हैं। AWS में, आप SAM बाल्टी में एन्क्रिप्ट किए गए रहस्यों को संग्रहीत करने के लिए IAM भूमिकाओं, प्रमुख प्रबंधन सेवा और S3 के संयोजन का उपयोग कर सकते हैं । की तरह कुछ HashiCorp वॉल्ट या credstash एक और विकल्प है।

AFAIK निर्माण प्रक्रिया के हिस्से के रूप में संवेदनशील डेटा का उपयोग करने के लिए कोई इष्टतम पैटर्न नहीं है। वास्तव में, मेरे पास इस विषय पर एक एसओ प्रश्न है । आप एक छवि से परतों को हटाने के लिए डॉकटर-स्क्वैश का उपयोग कर सकते हैं । लेकिन इस उद्देश्य के लिए डॉकर में कोई मूल कार्यक्षमता नहीं है।

आप कंटेनर में विन्यास पर शर्मीली टिप्पणी उपयोगी पा सकते हैं ।


जैसा कि अन्य टिप्पणियों में कहा गया है कि इसमें 2 परतें होंगी (ADD के बाद और पहले RUN के बाद) जिसमें .configफ़ाइल होगी।
पेट्र ग्लैडिख

1
Yer, env variables जाने का सबसे अच्छा तरीका लगता है। मैं इसे TDDing Dockerfile विकास के संदर्भ में देख रहा हूं।
gnoll110

5
मुझे चिंता है कि यदि आपका पासवर्ड एक एनवी वैरिएबल है, तो यह दिखाई देता है docker inspect
स्लिम

Docker की एक डिफ़ॉल्ट स्थापना (linux पर) को चलाने के लिए sudoer विशेषाधिकारों की आवश्यकता होती है docker inspect। यदि हमलावर पहले से ही सूद कर सकता है, तो डॉक इंस्पेक्टर से आपका पासवर्ड छीनना शायद आपकी उन चीजों की सूची पर बहुत कम है जो अब गलत हो सकती हैं। यह विशेष विवरण मुझे स्वीकार्य जोखिम की तरह लगता है।
ग्रैंडऑनर

7
@GrandOpener केवल उस स्थिति पर लागू होता है जहां आपके सिस्टम का उपयोग करने वाला हमलावर है। यदि मैं एक doos छवि को एक रिपॉजिटरी में धकेलता हूं, और इसे किसी और द्वारा खींचा जाता है, तो मुझे परवाह नहीं है यदि उनके पास अपने सिस्टम पर sudo है, लेकिन मुझे निश्चित रूप से परवाह है अगर वे env में रहस्य देखते हैं जो अब होने वाले नहीं हैं।
vee_ess

74

हमारी टीम रिपॉजिटरी में क्रेडेंशियल्स डालने से बचती है, इसका मतलब है कि उन्हें अंदर जाने की अनुमति नहीं है Dockerfile। अनुप्रयोगों के भीतर हमारा सबसे अच्छा अभ्यास पर्यावरण चर से क्रेडिट का उपयोग करना है।

हम इसका उपयोग करने के लिए हल करते हैं docker-compose

भीतर docker-compose.yml, आप एक फ़ाइल निर्दिष्ट कर सकते हैं जिसमें कंटेनर के लिए पर्यावरण चर शामिल हैं:

 env_file:
- .env

यकीन है कि जोड़ने के लिए सुनिश्चित .envकरने के लिए .gitignoreहै, तो भीतर साख सेट .envकी तरह फ़ाइल:

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

स्टोर .envफ़ाइल स्थानीय रूप से या एक सुरक्षित स्थान जहां टीम के बाकी यह हड़पने कर सकते हैं में।

देखें: https://docs.docker.com/compose/environment-variables/#/the-env-file


15
आप चाहें तो .env फ़ाइल के बिना भी ऐसा कर सकते हैं। बस अपने docker-compose.yml फ़ाइल में पर्यावरण संपत्ति का उपयोग करें । "केवल एक कुंजी के साथ पर्यावरण चर को मशीन पर उनके मूल्यों के लिए हल किया जाता है कम्पोज़ चालू है, जो गुप्त या होस्ट-विशिष्ट मानों के लिए सहायक हो सकता है।"
डी। विज़र

1
इस आदमी को एक कुकी दे दो! :) हाँ, यह वास्तव में अच्छा अभ्यास है मैं बस उस डॉक्स को जोड़ना चाहता हूँ ।
बराबर 8

5
पर्यावरण चर का उपयोग करते हुए खुद डॉकर टीम द्वारा हतोत्साहित किया जाता है, क्योंकि env var को / proc / <pid> / environ और docker निरीक्षण के माध्यम से देखा जा सकता है। यह केवल एक हमलावर के लिए क्रेडेंशियल प्राप्त करने के तरीके को बाधित करता है जिसने रूट एक्सेस प्राप्त किया है। बेशक क्रेडेंशियल को सीवीएस द्वारा कभी भी ट्रैक नहीं किया जाना चाहिए। मुझे लगता है कि क्रेडेंशियल को रोकने के लिए रूट-यूज़र को रोकने का एकमात्र तरीका वेब ऐप के भीतर से क्रेडेंशियल्स को पढ़ना है (उम्मीद है कि यह एनक्रिप्ट की गई फ़ाइल से इसकी खरीद को अपडेट नहीं करता है), डिक्रिप्शन प्रक्रिया सुरक्षित रूप से पासवर्ड की मांग करती है। मुझे लगता है कि मैं एक कब्र के साथ कोशिश करने जा रहा हूँ: github.com/dyne/Tomb
pawamoy

.gitignoreताकि .envसंवेदनशील जानकारी वाली फ़ाइल GitHub में चेक-इन नहीं हो। मुझे पूरा यकीन है कि अगर आप इसे जोड़ेंगे तो यह काम नहीं करेगा.dockerignore
TheUtherSide

हाय @theUtherSide, आपके उत्तर के लिए धन्यवाद, मेरे पास एक सवाल था, जब मैं .envफ़ाइल की जांच नहीं करता हूं और मैं एक सर्वर को प्रीमियर पर तैनात करता हूं, तो क्या आप .envमैन्युअल रूप से सर्वर पर फिर से फ़ाइल बनाने का सुझाव देते हैं ?
ओपनसोर्स-डेवलपर

37

डॉकर अब (संस्करण 1.13 या 17.06 और उच्चतर) को गुप्त जानकारी के प्रबंधन के लिए समर्थन है। यहाँ एक सिंहावलोकन और अधिक विस्तृत प्रलेखन है

इसी तरह की सुविधा कुबेरनेट्स और डीसीओएस में मौजूद है


ऊपर दिए गए लिंक से कुछ उपयोगी कमांड: docker secret create: एक गुप्त बनाने docker secret inspectएक रहस्य के बारे में विस्तृत जानकारी प्रदर्शित: docker secret ls: सभी रहस्यों को देखने docker secret rm: एक विशिष्ट गुप्त हटाने --secretके लिए झंडा docker service create: सेवा निर्माण के दौरान एक गुप्त बनाने --secret-addऔर --secret-rmके लिए झंडे docker service updateएक गुप्त का मूल्य अद्यतन या एक गुप्त निकालें: सेवा अद्यतन कार्य के दौरान। डॉकटर रहस्यों को प्रबंधक नोड्स पर आराम से संरक्षित किया जाता है और कंटेनर स्टार्टअप के दौरान कार्यकर्ता नोड्स के लिए प्रावधान किया जाता है।
पीजे

7
हाँ, आपको डॉकर सीक्रेट्स का उपयोग करने के लिए एक झुंड स्थापित करने की आवश्यकता है
हीदर क्यूसी

11
यह एक उत्तर पर एक अच्छी शुरुआत है, लेकिन इससे बहुत अधिक जानकारी की आवश्यकता है, जो उत्तर में ही प्रदर्शित होने के लिए जुड़ी हुई है।
जेफ लैम्बर्ट

7
सुनिश्चित नहीं है कि यह स्वीकृत उत्तर हो सकता है यदि यह केवल स्वार के साथ काम करता है। बहुत से लोग swarms का उपयोग नहीं कर रहे हैं, लेकिन अभी भी रहस्य पारित करने की आवश्यकता है।
जॉन वाई

9

आपको कंटेनर में कभी भी क्रेडेंशियल नहीं जोड़ना चाहिए जब तक कि आप ओके को क्रेडेंकड नहीं कर रहे हों जिस पर छवि डाउनलोड कर सकते हैं। विशेष रूप से, करना और ADD credsबाद RUN rm credsमें सुरक्षित नहीं है क्योंकि क्रेडेंशियल फ़ाइल एक मध्यवर्ती फाइल सिस्टम परत में अंतिम छवि में बनी हुई है। इसे निकालने के लिए छवि तक पहुंच वाले किसी के लिए भी यह आसान है।

जब आपको चेकआउट निर्भरता के लिए क्रेडेंशियल की आवश्यकता होती है, तो विशिष्ट समाधान मैंने देखा है और इस तरह एक कंटेनर का उपयोग दूसरे को बनाने के लिए किया जाता है। यानी, आम तौर पर आपके बेस कंटेनर में कुछ बिल्ड वातावरण होता है और आपको अपने ऐप कंटेनर को बनाने के लिए इनवाइट करना होगा। तो इसका सरल उपाय यह है कि आप अपने ऐप स्रोत और फिर RUNबिल्ड कमांड को जोड़ें । यह असुरक्षित है यदि आपको इसमें क्रेडिट की आवश्यकता है RUN। इसके बजाय आप जो करते हैं, वह आपके स्रोत को एक स्थानीय निर्देशिका में डाल देता है, docker runकंटेनर को वॉल्यूम के रूप में माउंट किए गए स्थानीय स्रोत निर्देशिका के साथ बिल्ड स्टेप को पूरा करने के लिए चलाएं ( या तो इंजेक्ट किया जाता है या किसी अन्य वॉल्यूम के रूप में क्रेडिट किया जाता है)। एक बार बिल्ड स्टेप पूरा हो जाने के बाद आप अपने अंतिम कंटेनर का निर्माण ADDस्थानीय स्रोत निर्देशिका से करते हैं जिसमें अब निर्मित कलाकृतियाँ होती हैं।

मैं उम्मीद कर रहा हूँ कि डॉकर इस सब को आसान बनाने के लिए कुछ सुविधाएँ जोड़ता है!

अद्यतन: ऐसा लगता है कि आगे जाने की विधि नेस्टेड बिल्ड होगी। संक्षेप में, डॉकफाइल एक पहले कंटेनर का वर्णन करेगा जो रन-टाइम वातावरण बनाने के लिए उपयोग किया जाता है और फिर एक दूसरा नेस्टेड कंटेनर निर्माण होता है जो सभी टुकड़ों को अंतिम कंटेनर में इकट्ठा कर सकता है। इस तरह बिल्ड-टाइम सामान दूसरे कंटेनर में नहीं है। यह एक जावा ऐप है जहाँ आपको ऐप के निर्माण के लिए JDK की आवश्यकता है लेकिन इसे चलाने के लिए केवल JRE की आवश्यकता है। कई प्रस्तावों पर चर्चा की जा रही है, https://github.com/docker/docker/issues/7115 से शुरू करने के लिए और वैकल्पिक प्रस्तावों के लिए कुछ लिंक का पालन करें।


7

पर्यावरण चर का उपयोग करने का एक विकल्प, जो गड़बड़ हो सकता है यदि आपके पास उनमें से बहुत कुछ है, तो कंटेनर में होस्ट सुलभ पर एक निर्देशिका बनाने के लिए संस्करणों का उपयोग करना है।

यदि आप अपने सभी क्रेडेंशियल्स को उस फ़ोल्डर में फ़ाइलों के रूप में रखते हैं, तो कंटेनर फाइलों को पढ़ सकता है और उनका उपयोग कर सकता है जैसा कि वह प्रसन्न करता है।

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

$ echo "secret" > /root/configs/password.txt
$ docker run -v /root/configs:/cfg ...

In the Docker container:

# echo Password is `cat /cfg/password.txt`
Password is secret

कई प्रोग्राम एक अलग फ़ाइल से उनके क्रेडेंशियल्स पढ़ सकते हैं, इसलिए इस तरह से आप प्रोग्राम को फाइलों में से एक को इंगित कर सकते हैं।


5

रन-टाइम केवल समाधान

docker- रचना भी एक गैर-झुंड मोड समाधान प्रदान करता है (v1.11 के बाद से: बाइंड माउंट का उपयोग करके रहस्य )।

रहस्यों को /run/secrets/डॉकटर-कम्पोज़ द्वारा नीचे दी गई फ़ाइलों के रूप में रखा गया है । यह रन-टाइम (कंटेनर चलाने) में समस्या को हल करता है, लेकिन बिल्ड-टाइम (छवि निर्माण) /run/secrets/में नहीं , क्योंकि बिल्ड-टाइम पर माउंट नहीं किया गया है। इसके अलावा यह व्यवहार डॉकटर-कंपोज के साथ कंटेनर को चलाने पर निर्भर करता है।


उदाहरण:

Dockerfile

FROM alpine
RUN cat /run/secrets/password
CMD sleep inifinity

डोकर-compose.yml

version: '3.1'
services:
  app:
    build: .
    secrets:
      - password

secrets:
  password:
    file: password.txt

बनाने के लिए, निष्पादित करें:

docker-compose up -d

आगे की पढाई:


2

Docker v1.9 के साथ आप ARG इंस्ट्रक्शन को बिल्ड एक्शन पर कमांड लाइन द्वारा दिए गए तर्कों को इमेज में लाने के लिए उपयोग कर सकते हैं । बस - thebuild-arg ध्वज का उपयोग करें । तो आप डॉकरफ़ाइल पर स्पष्ट पासवर्ड (या अन्य समझदार जानकारी) रखने से बच सकते हैं और उन्हें फ्लाई पर पास कर सकते हैं।

स्रोत: https://docs.docker.com/engine/reference/commandline/build/ http://docs.docker.com/engine/reference/builder/#arg

उदाहरण:

Dockerfile

FROM busybox
ARG user
RUN echo "user is $user"

छवि कमांड बनाएँ

docker build --build-arg user=capuccino -t test_arguments -f path/to/dockerfile .

निर्माण के दौरान यह प्रिंट

$ docker build --build-arg user=capuccino -t test_arguments -f ./test_args.Dockerfile .

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM busybox
 ---> c51f86c28340
Step 2 : ARG user
 ---> Running in 43a4aa0e421d
 ---> f0359070fc8f
Removing intermediate container 43a4aa0e421d
Step 3 : RUN echo "user is $user"
 ---> Running in 4360fb10d46a
**user is capuccino**
 ---> 1408147c1cb9
Removing intermediate container 4360fb10d46a
Successfully built 1408147c1cb9

आशा करता हूँ की ये काम करेगा! अलविदा।


26
डॉकर के एआरजी डॉक्स के अनुसार : "जीथब चाबियों, उपयोगकर्ता क्रेडेंशियल्स आदि जैसे गुप्त रहस्यों के लिए बिल्ड-टाइम चर का उपयोग करने की अनुशंसा नहीं की जाती है"
रेयान

3
बस यह सोचकर कि डॉकटर --build-arg var=secretएक SSH निजी कुंजी को एक छवि में पारित करने के लिए उपयोग करने के लिए क्यों रोकते हैं , कोई औचित्य दस्तावेज नहीं है। क्या कोई इसे समझा सकता है?
हेन्क वेसेरेमा

2
@HenkWiersema प्रक्रिया की जानकारी, लॉग और कमांड इतिहास असुरक्षित हैं। प्रक्रिया की जानकारी सार्वजनिक रूप से उपलब्ध है और इसमें सभी कमांड लाइन पैरामीटर शामिल हैं। अक्सर ये कॉल लॉग्स में समाप्त हो जाते हैं जो सार्वजनिक भी हो सकते हैं। यह किसी हमलावर के लिए चल रही प्रक्रियाओं और रहस्यों के लिए सार्वजनिक लॉगफ़ाइल्स की जानकारी का निरीक्षण करने के लिए असामान्य नहीं है। यहां तक ​​कि जब यह सार्वजनिक नहीं है, तो इसे आपके कमांड इतिहास में संग्रहीत किया जा सकता है, जो किसी के लिए गैर-प्रशासनिक खाते के माध्यम से रहस्य प्राप्त करना आसान बना देगा।
tu-Reinstate Monica-dor duh

2
बिल्ड समय में आवश्यक क्रेडेंशियल्स की आपूर्ति करने के लिए अनुशंसित तरीका क्या है? उदाहरण के लिए, एक छवि जिसे aws s3 एक्सेस की आवश्यकता है, एक बड़ा डेटा सेट प्राप्त करने के लिए जो छवि के अंदर रहता है?
Ely

3
मैं कल्पना करता हूं कि इसकी अनुशंसा नहीं की गई है क्योंकि docker historyएक्सपोज़ build-arg/ ARGवैरिएबल है। कोई भी चित्र खींच सकता है, उसका निरीक्षण कर सकता है और निर्माण के दौरान पारित किए गए किसी भी रहस्य को build-arg/ ARGपैरामीटर के रूप में देख सकता है ।
vee_ess

2

मेरा दृष्टिकोण काम करने लगता है, लेकिन शायद भोला है। मुझे बताओ कि यह गलत क्यों है।

डॉक बिल्ड के दौरान सेट किए गए ARG को इतिहास सबकोमांड द्वारा उजागर किया जाता है, इसलिए वहां नहीं जाना चाहिए। हालांकि, कंटेनर चलाते समय, रन कमांड में दिए गए पर्यावरण चर कंटेनर में उपलब्ध होते हैं, लेकिन छवि का हिस्सा नहीं होते हैं।

इसलिए, डॉकरफाइल में, सेटअप करें जिसमें गुप्त डेटा शामिल नहीं है। जैसे कुछ का CMD सेट करें /root/finish.sh। रन कमांड में, कंटेनर में गुप्त डेटा भेजने के लिए पर्यावरण चर का उपयोग करें। finish.shबिल्ड कार्यों को पूरा करने के लिए चर का अनिवार्य रूप से उपयोग करता है।

गुप्त डेटा को प्रबंधित करना आसान बनाने के लिए, इसे एक ऐसी फ़ाइल में डालें, जिसे --env-fileस्विच के साथ docker द्वारा चलाया गया हो । बेशक, फ़ाइल को गुप्त रखें। .gitignoreऔर ऐसा।

मेरे लिए, finish.shएक पायथन प्रोग्राम चलाता है। यह सुनिश्चित करने के लिए जाँच करता है कि यह पहले नहीं चला है, फिर सेटअप पूरा करता है (जैसे, डेटाबेस का नाम Django में कॉपी करता है settings.py)।


2

"रहस्य" प्रबंधन के लिए एक नया डॉकटर कमांड है । लेकिन यह केवल झुंड समूहों के लिए काम करता है।

docker service create
--name my-iis
--publish target=8000,port=8000
--secret src=homepage,target="\inetpub\wwwroot\index.html"
microsoft/iis:nanoserver 

1

12-फैक्टर एप्लिकेशन कार्यप्रणाली बताता है, कि किसी भी विन्यास वातावरण चर में संग्रहित किया जाना चाहिए।

डॉकर कंपोज़ कॉन्फ़िगरेशन में परिवर्तनीय प्रतिस्थापन कर सकता है , ताकि होस्ट से डॉकटर तक पासवर्ड पास करने के लिए उपयोग किया जा सके।


मैं बाइबिल के संदर्भ की सराहना करता हूं।
जेककॉटन

-2

जबकि मैं पूरी तरह सहमत हूं कि कोई सरल उपाय नहीं है। असफलता का एक ही बिंदु है। या तो dockerfile, वगैरह, वगैरह। Apcera की एक योजना है जो साइडकिक - दोहरी प्रमाणीकरण जैसी दिखती है। दूसरे शब्दों में दो कंटेनर तब तक बात नहीं कर सकते जब तक कि अपेक कॉन्फ़िगरेशन नियम नहीं है। उनके डेमो में uid / pwd स्पष्ट था और तब तक पुन: उपयोग नहीं किया जा सकता था जब तक कि व्यवस्थापक लिंकेज को कॉन्फ़िगर न कर दे। हालांकि, काम करने के लिए, इसका मतलब शायद डॉकिंग पैचिंग या कम से कम नेटवर्क प्लगइन है (यदि ऐसी कोई बात है)।


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