गिट रिपॉजिटरी में पासवर्ड से निपटने के लिए सबसे अच्छा अभ्यास क्या है?


225

मुझे थोड़ी सी बैश स्क्रिप्ट मिली है जिसका उपयोग मैं ट्विटर तक पहुँचने के लिए करता हूँ और कुछ स्थितियों में ग्रोथ नोटिफिकेशन को पॉप अप करता हूँ। स्क्रिप्ट के साथ अपना पासवर्ड संग्रहीत करने का सबसे अच्छा तरीका क्या है?

मैं इस स्क्रिप्ट को गिट रेपो के लिए प्रतिबद्ध करना चाहता हूं और इसे GitHub पर उपलब्ध कराना चाहता हूं, लेकिन मैं सोच रहा हूं कि ऐसा करते समय मेरे लॉगिन / पासवर्ड को निजी रखने का सबसे अच्छा तरीका क्या है। वर्तमान में, पासवर्ड स्क्रिप्ट में ही संग्रहीत है। मैं इसे धक्का नहीं दे सकता इससे पहले कि मैं धक्का दे दूं क्योंकि सभी पुराने कमिट में पासवर्ड होगा। पासवर्ड के बिना विकास एक विकल्प नहीं है। मुझे लगता है कि मुझे बाहरी कॉन्फ़िगरेशन फ़ाइल में पासवर्ड संग्रहीत करना चाहिए, लेकिन मैंने सोचा कि मैं यह देखने के लिए जांच करूंगा कि क्या इससे पहले कि मैं कोशिश करूं और कुछ एक साथ रखूं, इसे संभालने का एक स्थापित तरीका था।

जवाबों:


256

ऐसा करने का विशिष्ट तरीका कॉन्फ़िगरेशन फ़ाइल से पासवर्ड जानकारी पढ़ना है। यदि आपकी कॉन्फ़िगरेशन फ़ाइल को कॉल किया जाता है foobar.config, तो आप एक फ़ाइल foobar.config.exampleको रिपॉजिटरी को कहते हैं , जिसमें नमूना डेटा होगा। अपना प्रोग्राम चलाने के लिए, आप foobar.configअपने वास्तविक पासवर्ड डेटा के साथ एक स्थानीय (ट्रैक नहीं की गई) फ़ाइल बनाएँगे ।

पिछले कमिट से अपने मौजूदा पासवर्ड को फ़िल्टर करने के लिए, संवेदनशील डेटा को हटाने पर GitHub सहायता पृष्ठ देखें ।


4
Btw, आप रेपो में एक उदाहरण foobar.config जोड़ सकते हैं और फिर .ignore फ़ाइल में foobar.conig जोड़ सकते हैं। इस तरह से phobar.config का उदाहरण दिया जाएगा जब क्लोन किया जाएगा और आपके वास्तविक पासवर्ड रेपो में नहीं जुड़ेंगे।
Mr_Chimp

16
@Mr_Chimp: .gitignoreफ़ाइल पहले से रिपॉजिटरी में ट्रैक की गई फ़ाइलों पर लागू नहीं होती है। उदाहरण के लिए, git add -uएक परिवर्तित फ़ाइल जोड़ देगा भले ही वह पहले से ही हो .gitignore
ग्रेग हेवगिल

1
एक पूरक के रूप में, यहां एक दिलचस्प कड़ी है यदि आपने दुर्घटना की फाइल को दुर्घटना से जोड़ दिया है और आप इसे गिट इतिहास से हटाना चाहते हैं: help.github.com/articles/remove-sensitive-data
Loïc Lopes

16
आप अपनी टीम के साथ उन पासवर्डों को साझा करने के बारे में कैसे जायेंगे? एक चीज़ की एक स्थानीय प्रतिलिपि (रेपो के लिए प्रतिबद्ध नहीं) है, दूसरा इसे स्वचालित टूल (तैनाती के लिए) के साथ भी बड़ी टीम के साथ साझा करना है
ब्लूफ़ास्ट

2
मेरे पास @dangonfast जैसा ही प्रश्न है। यह एक बड़ी टीम के लिए व्यावहारिक नहीं लगता है।
जैकब स्टैम जूल

25

एक पर्यावरण चर का उपयोग करके पासवर्ड (या एपीआई कुंजी) सेट करने के लिए एक दृष्टिकोण हो सकता है। तो यह पासवर्ड संशोधन नियंत्रण से बाहर है।

बैश के साथ, आप पर्यावरण चर का उपयोग करके सेट कर सकते हैं

export your_env_variable='your_password'

यह दृष्टिकोण ट्रैविस जैसी निरंतर एकीकरण सेवाओं के साथ उपयोग किया जा सकता है , आपका कोड (पासवर्ड के बिना) एक GitHub में संग्रहीत किया जा रहा है रिपॉजिटरी है जिसे ट्रैविस (आपके पासवर्ड को पर्यावरण चर का उपयोग करके सेट किया जा रहा है) द्वारा निष्पादित किया जा सकता है।

बैश के साथ, आप एक पर्यावरण चर का उपयोग करके मूल्य प्राप्त कर सकते हैं:

echo "$your_env_variable"

पायथन के साथ, आप एक पर्यावरण चर का उपयोग करके मूल्य प्राप्त कर सकते हैं:

import os
print(os.environ['your_env_variable'])

पुनश्च: ध्यान रखें कि यह शायद थोड़ा जोखिम भरा है (लेकिन यह काफी सामान्य अभ्यास है) https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment-variables/

PS2: "कैसे सुरक्षित रूप से स्टोर करने के लिए एपीआई कुंजी"dev.to शीर्षक वाला यह लेख पढ़ने में दिलचस्प हो सकता है।


1
अपने पर्यावरण चर की सामग्री को पढ़ने से संभावित "असुरक्षित" कोड मधुमक्खी निर्माण को कैसे रोका जाए?
गोरूटडे


16

ग्रेग ने क्या कहा, लेकिन मैं यह जोड़ना चाहूंगा कि किसी फाइल में जांच करना अच्छा है foobar.config-TEMPLATE

इसमें उदाहरण के नाम, पासवर्ड या अन्य कॉन्फ़िगरेशन जानकारी होनी चाहिए। फिर यह बहुत स्पष्ट है कि वास्तविक फोब्बर.कॉन्फिग में क्या होना चाहिए, बिना सभी कोड में देखने के लिए कि किन मूल्यों में मौजूद होना चाहिएfoobar.config और उनके पास क्या प्रारूप होना चाहिए।

अक्सर कॉन्फ़िगरेशन मान गैर-स्पष्ट हो सकते हैं, जैसे डेटाबेस कनेक्शन स्ट्रिंग्स और इसी तरह की चीजें।


7

रिपॉजिटरी में पासवर्ड के साथ व्यवहार करना आपके सटीक समस्या के आधार पर विभिन्न तरीकों को संभाला जाएगा।

1. यह मत करो।

और करने से बचने के तरीके कुछ उत्तरों में शामिल हैं - .ignignore, config.example, आदि

  • .itignore: सर्वर आदि पर स्टोर करें लेकिन Git (कमजोर समाधान) नहीं
  • पर्यावरण चर: https://stackoverflow.com/a/30664318/3070485
  • Config.example: https://stackoverflow.com/a/2397905/3070485
  • कमांड लाइन पैरामीटर: प्रोग्राम स्टार्टअप पर मैन्युअल रूप से पासवर्ड दर्ज करें

या 2. केवल अधिकृत लोगों को ही रिपॉजिटरी सुलभ बनाएं

यानी वे लोग जिन्हें पासवर्ड जानने की अनुमति है। chmodऔर उपयोगकर्ता समूहों के दिमाग में आता है; यदि आप अपने रिपॉजिटरी या सर्वर को बाहरी रूप से होस्ट करते हैं, तो भी गिथब या एडब्ल्यूएस कर्मचारियों को चीजों को देखने की अनुमति दी जानी चाहिए?

या 3. संवेदनशील डेटा एन्क्रिप्ट करें (इस उत्तर का उद्देश्य)

यदि आप किसी सार्वजनिक स्थान पर संवेदनशील जानकारी (जैसे पासवर्ड) वाली अपनी कॉन्फ़िगर फ़ाइलों को संग्रहीत करना चाहते हैं तो उसे एन्क्रिप्ट करने की आवश्यकता है। रिपॉजिटरी से बरामद होने पर फाइलों को डिक्रिप्ट किया जा सकता है, या सीधे उनके एन्क्रिप्टेड फॉर्म से भी इस्तेमाल किया जा सकता है।

एन्क्रिप्टेड कॉन्फ़िगरेशन डेटा का उपयोग करने के लिए एक उदाहरण जावास्क्रिप्ट समाधान नीचे दिखाया गया है।

const fs = require('fs');
const NodeRSA = require('node-rsa');

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));
const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');

console.log('decrypted: ', config);

डिक्रिप्ट की गई विन्यास फाइल

तो आप जावास्क्रिप्ट की कुछ पंक्तियों को लिखने के लिए एक एन्क्रिप्टेड कॉन्फ़िगर फ़ाइल को पुनर्प्राप्त कर सकते हैं।

ध्यान दें कि एक फ़ाइल config.RSAको git रिपॉजिटरी में डालने से प्रभावी रूप से यह एक बाइनरी फ़ाइल बन जाएगी और इसलिए यह Git जैसी कुछ चीज़ों के कई लाभों को खो देगी, जैसे चेरी से इसमें बदलाव करने की क्षमता।

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

ऊपर दिया गया मेरा उदाहरण इसके साथ एक परीक्षण करने के इच्छुक किसी भी व्यक्ति के लिए थोड़ा बेकार है, या एक उदाहरण के रूप में शुरू करने के लिए यह कुछ आरएसए कुंजी और एक एन्क्रिप्टेड कॉन्फ़िगरेशन फ़ाइल के अस्तित्व को मानता है config.RSA

तो यहाँ कोड की कुछ अतिरिक्त पंक्तियों को जोड़ने के लिए RSA कुंजियाँ और एक विन्यास फाइल बनाई गई है।

const fs = require('fs');
const NodeRSA = require('node-rsa');

/////////////////////////////
// Generate some keys for testing
/////////////////////////////

const examplekey = new NodeRSA({b: 2048});

fs.writeFileSync('private.key', examplekey.exportKey('pkcs8-private'));
fs.writeFileSync('public.key', examplekey.exportKey('pkcs8-public'));

/////////////////////////////
// Do this on the Machine creating the config file
/////////////////////////////

const configToStore = {Goodbye: 'Cruel world'};

let publickey = new NodeRSA();
publickey.importKey(fs.readFileSync('public.key', 'utf8'));

fs.writeFileSync('config.RSA', publickey.encrypt(configToStore, 'base64'), 'utf8');

/////////////////////////////
// Do this on the Machine consuming the config file
/////////////////////////////

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));

const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');
console.log('decrypted: ', config);

केवल मूल्यों को एन्क्रिप्ट करना

fs.writeFileSync('config.RSA', JSON.stringify(config,null,2), 'utf8');

यहां छवि विवरण दर्ज करें

आप कुछ इस तरह का उपयोग कर एन्क्रिप्टेड मूल्यों के साथ एक कॉन्फ़िगर फ़ाइल को डिक्रिप्ट कर सकते हैं।

const savedconfig = JSON.parse(fs.readFileSync('config.RSA', 'utf8'));
let config = {...savedconfig};
Object.keys(savedconfig).forEach(key => {
    config[key] = privatekey.decrypt(savedconfig[key], 'utf8');
});

एक अलग लाइन (जैसे Helloऔर Goodbyeऊपर) पर प्रत्येक कॉन्फ़िगरेशन आइटम के साथ , गिट बेहतर पहचान लेंगे कि एक फ़ाइल में क्या हो रहा है और पूरी फ़ाइलों के बजाय अंतर के रूप में जानकारी के आइटम में बदलावों को संग्रहीत करेगा। Git मर्ज और चेरी पिक्स आदि को बेहतर तरीके से प्रबंधित करने में सक्षम होगा।

हालाँकि जितना अधिक आप संवेदनशील जानकारी में परिवर्तन को नियंत्रित करना चाहते हैं, उतना ही आप SAFE REPOSITORY समाधान (2) की ओर बढ़ रहे हैं और एक अलग जानकारी (3) समाधान से दूर हैं।


3

एक तिजोरी का उपयोग कर सकते हैं जो टोकन, पासवर्ड, प्रमाण पत्र, एपीआई कुंजी आदि तक पहुंच, भंडार, और नियंत्रण को नियंत्रित करता है। उदाहरण के लिए, अंसिबल ने Ansible वॉल्ट का उपयोग किया है जो कि प्लेबुक में उपयोग किए गए पासवर्ड या प्रमाण पत्र के साथ काम करता है।


मुझे लगता है कि केवल एक उदाहरण विन्यास फ़ाइल बनाने की तुलना में निश्चित रूप से जटिल Vault को जटिल लगता है।
icc97

@ icc97 हाँ यह दुखद सच है। लेकिन हमें इस संभावना का उल्लेख करना होगा। मेरी राय में, कार्यों के लिए और अधिक जटिल तब एकल-उपयोगकर्ता वातावरण के लिए कुछ पासवर्डों को संग्रहीत करना शुरू से विशेष समाधानों का उपयोग करना बेहतर है।
एल रुसो

2
भविष्य के पाठकों की मदद करने के लिए: वॉल्ट और अन्सिबल वॉल्ट समान नामों के साथ काफी अलग-अलग असंबंधित परियोजनाएं हैं
bltavares

2

यहाँ एक तकनीक है जिसका मैं उपयोग करता हूँ:

मैं अपने होम फोल्डर में एक फोल्डर बनाता हूं: .config

उस फ़ोल्डर में मैं किसी भी संख्या में उन चीजों के लिए कॉन्फिगरेशन फाइल रखता हूं, जो मुझे पासवर्ड और कीज को एक्सटर्नल करना है।

मैं आमतौर पर रिवर्स डोमेन नाम सिंटैक्स का उपयोग करता हूं जैसे:

com.example.databaseconfig

फिर बैश स्क्रिप्ट में मैं ऐसा करता हूं:

#!/bin/bash
source $HOME/.config/com.example.databaseconfig ||exit 1

|| exit 1स्क्रिप्ट से बाहर निकलने का कारण बनता है अगर यह कॉन्फिग फाइल को लोड करने में सक्षम नहीं है।

मैंने उस तकनीक का इस्तेमाल बैश, पाइथन और चींटी स्क्रिप्ट के लिए किया।

मैं बहुत अधिक पागल हूं और यह नहीं सोचता कि अनजाने चेक-इन को रोकने के लिए एक .gitignore फ़ाइल पर्याप्त रूप से मजबूत है। इसके अलावा, इसकी निगरानी के लिए कुछ भी नहीं है, इसलिए अगर एक चेक-इन हुआ तो कोई भी इससे निपटने के लिए पता नहीं लगाएगा।

यदि किसी विशेष एप्लिकेशन को एक से अधिक फ़ाइल की आवश्यकता होती है तो मैं एक फ़ाइल के बजाय सबफ़ोल्डर बनाता हूं।


1

यदि आप रेल पर रूबी का उपयोग कर रहे हैं, तो फिगारो रत्न बहुत अच्छा, आसान और विश्वसनीय है। यह उत्पादन वातावरण के साथ कम सिरदर्द कारक भी है।


4
क्या आप उस रत्न के बारे में कुछ विवरण दे सकते हैं? इस तरह इसे (संभावित) कई भाषाओं में लागू 'अभ्यास' माना जा सकता है।
मट्टुमोटू

medium.com/@MinimalGhost/… का अवलोकन किया गया है, यह मूल रूप से एक विन्यास फाइल से सामान खींचने का प्रबंधन करता प्रतीत होता है
ट्रिपल

0

विश्वास करो किन्तु सत्यापित करो।

इसमें .gitignoreरेपो से "सुरक्षित" निर्देशिका को बाहर रखा जाएगा:

secure/

लेकिन मैं @ माइकल पॉटर के व्यामोह साझा करता हूं । तो .itignore को सत्यापित करने के लिए, यहां एक पायथन यूनिट टेस्ट है जो कि केलैक्सन को बढ़ाएगा यदि यह "सुरक्षित" निर्देशिका कभी भी चेक इन हो जाए और चेक की जांच करने के लिए, एक वैध निर्देशिका का भी परीक्षण किया जाए:

def test_github_not_getting_credentials(self):
    safety_url = 'https://github.com/BobStein/fliki/tree/master/static'
    danger_url = 'https://github.com/BobStein/fliki/tree/master/secure'

    self.assertEqual(200, urllib.request.urlopen(safety_url).status)

    with self.assertRaises(urllib.error.HTTPError):
        urllib.request.urlopen(danger_url)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.