जब आप अपने एप्लिकेशन को EC2 पर डेप्लॉय करते हैं, तो ऑटोस्केलिंग ग्रुप का उपयोग करना एक अच्छा विचार है। ऑटोस्केलिंग ग्रुप आपके एप्लिकेशन को मांग को पूरा करने के लिए स्केल अप और डाउन करने की अनुमति देते हैं, या विफल इंस्टेंस से रिकवर करने के लिए, सभी बिना किसी मैन्युअल हस्तक्षेप के। उन्हें काम करने के लिए, हालांकि, सुनिश्चित करें कि हर इंस्टेंस बूट होने के बाद लाइव ट्रैफिक को सर्विस करने के लिए पूरी तरह से तैयार है। यदि आप एक नए सर्वर पर कुछ बदलाव करने या कैपिस्ट्रानो के माध्यम से प्रारंभिक डिप्लॉयमेंट करने के आदी हैं, तो इसमें थोड़ा अधिक प्रयास की आवश्यकता होती है।
उदाहरण के लिए, हमारे पास Rails का उपयोग करके बनाया गया एक उपयोगकर्ता-सामना करने वाला वेब एप्लिकेशन है। जब यह बूट हो जाता है, तो प्रत्येक इंस्टेंस को उस Rails ऐप की आवश्यकता होती है जो लोड बैलेंसर द्वारा अग्रेषित अनुरोधों का जवाब देने के लिए तैयार और प्रतीक्षा कर रहा हो। ऐसा करने के लिए, मैंने पहले Ansible के माध्यम से प्रोविजन किए गए एक इंस्टेंस का स्नैपशॉट लेकर एक कस्टम AMI बनाया जिसमें ऐप, nginx, आदि शामिल थे। फिर मैंने ऑटोस्केलिंग ग्रुप को यूजरडेटा के साथ कॉन्फिगर किया जो एक स्क्रिप्ट को इनवोक करता है जो कैपिस्ट्रानो एक डिप्लॉयमेंट के लिए क्या करता है - यह गिट से नवीनतम कोड खींचता है, बंडलर चलाता है, और इसी तरह। तो ऐप और इसके सभी निर्भरताएं जगह में होने के साथ, क्या बचा है?
एप्लिकेशन सीक्रेट्स: डिप्लॉयर का अभिशाप
एप्लिकेशन सीक्रेट्स एक चुनौती पेश करते हैं: आप उन्हें वहां स्टोर होने से रोकना चाहते हैं जहां वे उजागर हो सकते हैं (जैसे, आपके गिट रिपो में), लेकिन आपको उन्हें अपने ऐप के लिए उपलब्ध होने की आवश्यकता है जब यह चल रहा हो। और ऑटोस्केलिंग के कारण, आप अपने ऐप को जब उनकी आवश्यकता हो तो उन्हें रखने के लिए किसी इंसान पर भरोसा नहीं कर सकते।
इस समस्या का एक उत्तर Hashicorp द्वारा Vault है। यह विशेष रूप से इस समस्या को हल करने के लिए लिखा गया एक शानदार सॉफ्टवेयर है जो आपके सीक्रेट्स को तब तक गुप्त रखता है जब तक आपके ऐप को उनकी आवश्यकता न हो। हालांकि, नकारात्मक पक्ष यह है कि आपको Vault को प्रोविजन और मैनेज करना होगा - यह एक और सेवा है जिसे आपको चालू रखने की आवश्यकता है।
एक अन्य विकल्प सीक्रेट्स को शेयर्ड स्टोरेज (S3, स्वाभाविक रूप से) में सहेजना है, और यह सुनिश्चित करना है कि केवल आपके इंस्टेंस की उस बकेट और/या कुंजी तक पहुंच हो। यह IAM रोल्स का उपयोग करके किया जा सकता है, जिनमें नीतियों को जोड़ा जा सकता है जो प्रतिबंधित S3 संसाधनों तक पहुंच प्रदान करते हैं। फिर भी, यदि आप उन सभी सीक्रेट्स को S3 पर प्लेनटेक्स्ट में स्टोर करते हैं, तो आप अवांछित जोखिम के लिए खुले रहते हैं। उस डेटा को उस बकेट तक पहुंच वाले अन्य लोगों या यहां तक कि पूरी दुनिया के लिए गलती से उपलब्ध कराना संभव है।
क्या यह अच्छा नहीं होगा यदि आप S3 पर सहेजने से पहले अपने सीक्रेट्स को एन्क्रिप्ट कर सकें, और फिर जब आपको उनकी आवश्यकता हो तो ऐप में उन्हें लोड और डिक्रिप्ट कर सकें?
गुप्त घटक: Amazon की Key Management Service
Amazon की Key Management Service (KMS) एन्क्रिप्शन कुंजियों के साथ इंटरैक्ट करने के लिए एक API प्रदान करती है। जब IAM रोल्स और Aws::S3::Encryption मॉड्यूल के साथ संयुक्त, तो यह आपके सीक्रेट्स को S3 पर एन्क्रिप्टेड रखते हुए आपके एप्लिकेशन में लोड करने के लिए केवल कुछ लाइन कोड लेता है।
इससे पहले कि मैं खुदाई करूं, मुझे Don Mills को धन्यवाद देना होगा, जिन्होंने KMS प्लस S3 का उपयोग करके सीक्रेट्स स्टोर करने पर एक शानदार पोस्ट लिखा। मैंने IAM रोल्स पर निर्भर करके और KMS कुंजी आईडी को अलग से ट्रैक करके उनके दृष्टिकोण को थोड़ा बदल दिया, बजाय इसके कि कुंजी जानकारी को S3 पर सीक्रेट्स के साथ स्टोर किया जाए।
KMS एक मास्टर एन्क्रिप्शन कुंजी उत्पन्न करता है और उस तक पहुंच प्रदान करता है जिसका उपयोग आप डेटा को एन्क्रिप्ट और डिक्रिप्ट करने के लिए कर सकते हैं। जब आप इसे कुछ एन्क्रिप्ट करने के लिए कहते हैं, तो KMS आपको मास्टर कुंजी के आधार पर एक अस्थायी कुंजी देता है, और उस अस्थायी कुंजी का उपयोग एन्क्रिप्शन या डिक्रिप्शन के लिए किया जा सकता है।
एक कुंजी उत्पन्न करने के लिए, आप IAM कंसोल पर जाते हैं और Encryption Keys लिंक चुनते हैं। जब आप एक कुंजी बनाते हैं, तो आपसे उन IAM उपयोगकर्ताओं या रोल्स को निर्दिष्ट करने के लिए कहा जाएगा जिनके पास इस कुंजी का उपयोग करने की क्षमता होगी। उस रोल को चुनें जिसे ऑटोस्केलिंग ग्रुप का हिस्सा बनने वाले EC2 इंस्टेंस को असाइन किया जाएगा। कुंजी का ARN नोट करें - आप बाद में इसका उपयोग करेंगे।
रूक्स बनाना: बराबर भाग KMS और IAM
एक बार जब आप कुंजी बना लेते हैं, तो IAM कंसोल का उपयोग करके उस IAM रोल को एडिट करें जिसे आपने चुना था। उस बकेट तक पहुंच प्रदान करें जहां सीक्रेट स्टोर किया जाएगा, इस तरह की नीति संलग्न करके:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1476277816000", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:PutObjectAcl", "s3:HeadObject" ], "Resource": [ "arn:aws:s3:::yourbucket/secrets.yml" ] } ] }
कुंजी कॉन्फिगर होने और रोल से जुड़ी नीति के साथ, अब आप Aws::S3::Encryption::Client इंस्टेंस के माध्यम से KMS और S3 के साथ इंटरैक्ट कर सकते हैं। यहां कुछ नमूना कोड है जो सीक्रेट्स फ़ाइल को पुनर्प्राप्त करता है और इसकी सामग्री को एनवायरनमेंट वेरिएबल्स में लोड करता है:
begin
es3 = Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID'])
YAML.load(es3.get_object(bucket: "yourbucket", key: "secrets.yml").body.read).each do |k, v|
ENV[k] ||= v # स्थानीय ENV सेटिंग्स को ओवरराइड न करें
end
rescue ArgumentError
# जब ENV में कोई KMS_KEY_ID नहीं मिला, तो करने के लिए कुछ नहीं
rescue Aws::S3::Errors::NoSuchKey
# कोई सीक्रेट्स फ़ाइल नहीं मिली, तो करने के लिए कुछ नहीं
end
सबसे पहले हम KMS कुंजी की आईडी के साथ एक नया ऑब्जेक्ट इंस्टेंटिएट करते हैं। कुंजी के लिए ARN (जब आपने कुंजी बनाई तो IAM कंसोल में प्रदर्शित) KMS_KEY_ID एनवायरनमेंट वेरिएबल में स्टोर किया जाता है। जब आप यहां कंस्ट्रक्टर में कुंजी आईडी पास करते हैं, तो यह आपके लिए अस्थायी डिक्रिप्शन कुंजियों को लाने को संभालेगा। यदि आप S3 से बात करने के लिए KMS की तुलना में क्रेडेंशियल्स का एक अलग सेट उपयोग करना चाहते हैं तो आप यहां एक विकल्प के रूप में Aws::S3::Client इंस्टेंस निर्दिष्ट कर सकते हैं। यदि आपने पहले की तरह IAM रोल सेट किया है, तो आपको इसकी आवश्यकता नहीं है, क्योंकि Aws::S3::Encryption::Client IAM रोल द्वारा प्रदान किए गए क्रेडेंशियल्स के साथ आपके लिए एक नया Aws::S3::Client इंस्टेंस बनाएगा।
एन्क्रिप्टेड S3 क्लाइंट तैयार होने के साथ, KMS द्वारा प्रदान की गई कुंजी का उपयोग करके S3 से डेटा लाने और डिक्रिप्ट करने के लिए #get_object का उपयोग करें। एक बार जब आपके पास डेटा हो, तो आप इसके साथ जो चाहें कर सकते हैं। हमारा डेटा YAML है, इसलिए हम इसे लोड करते हैं और ऐप कोड के उपयोग के लिए कुंजी/मान जोड़ियों को ENV में भर देते हैं।
इस कोड को अपने Rails एप्लिकेशन में एक इनिशियलाइज़र फ़ाइल में डालें, और आप जाने के लिए तैयार हैं। खैर, एक बार जब आपके सीक्रेट्स S3 पर स्टोर हो जाएं, तो। :) यह मानते हुए कि आपके पास सही IAM रोल के साथ चल रहे इंस्टेंस पर एक IRB कंसोल है, आप अपने सीक्रेट्स को स्टोर करने के लिए ऐसा कुछ कर सकते हैं:
# /path/to/secrets.yml से डेटा एन्क्रिप्ट करें और इसे S3 पर स्टोर करें
Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID']).put_object(bucket: "yourbucket", key: "secrets.yml", body: File.read("/path/to/secrets.yml"))
तुरंत सर्व करें
अब आपके सीक्रेट्स आपके ऑटोस्केलिंग ग्रुप में जोड़े गए किसी भी नए इंस्टेंस के लिए हमेशा उपलब्ध हैं जबकि सीक्रेट्स एन्क्रिप्टेड रखे गए हैं। हर कोई जीतता है! :)