Git depolarındaki parolalarla başa çıkmak için en iyi uygulama hangisidir?


225

Twitter'a erişmek ve belirli durumlarda bir Growl bildirimi açmak için kullandığım küçük bir Bash betiğim var. Şifremi script ile saklamanın en iyi yolu nedir?

Git komut deposuna bu komut dosyasını vermek ve GitHub'da kullanılabilir hale getirmek istiyorum, ancak bunu yaparken girişimi / şifremi gizli tutmanın en iyi yolunun ne olduğunu merak ediyorum. Şu anda, şifre betiğin kendisinde saklanmaktadır. Tüm eski taahhütler şifreyi içereceğinden, itmeden hemen önce kaldıramıyorum. Parola olmadan geliştirme bir seçenek değildir. Şifreyi harici bir yapılandırma dosyasında saklamam gerektiğini hayal ediyorum, ancak bir şey denemeden ve bir araya getirmeden önce bunu işlemek için yerleşik bir yol olup olmadığını kontrol edeceğimi düşündüm.

Yanıtlar:


256

Bunu yapmanın tipik yolu, bir yapılandırma dosyasından şifre bilgisini okumaktır. Yapılandırma dosyanız çağrılırsa foobar.config, foobar.config.exampleörnek veri içeren depoya çağrılan bir dosya yürütürsünüz. Programınızı çalıştırmak için, adı verilen bir yerel (izlenmez) dosyası yaratacak foobar.configsizin ile gerçek şifre verisi.

Mevcut şifrenizi önceki işlemlerden filtrelemek için Hassas verileri kaldırma konusundaki GitHub yardım sayfasına bakın .


4
Btw, repo için örnek bir foobar.config ekleyebilir ve sonra .ignore dosyasına foobar.config ekleyebilirsiniz. Bu şekilde klonlandığında foobar.config örneği görünecek ve gerçek parolalarınız repoya eklenmeyecektir.
Mr_Chimp

16
@Mr_Chimp: .gitignoreDosya zaten depoda olan izlenen dosyalar için geçerli değildir . Örneğin git add -u, zaten değiştirilmiş olsa bile değiştirilmiş bir dosya ekler .gitignore.
Greg Hewgill

1
Tamamlayıcı olarak, yapılandırma dosyasını yanlışlıkla eklemeniz
Loïc Lopes

16
Bu şifreleri ekibinizle nasıl paylaşırsınız? Bir şey yerel bir kopyaya sahip olmak (repoya bağlı değil), diğeri otomatik araçlarla (dağıtım için vb.) Daha büyük bir ekiple paylaşmaktır
blueFast

2
@Dangonfast ile aynı sorum var. Bu büyük bir ekip için pratik görünmüyor.
Jacob Stamm

26

Bir yaklaşım, bir ortam değişkeni kullanarak parola (veya API anahtarı) ayarlamak olabilir. Yani bu şifre revizyon kontrolü dışında.

Bash ile ortam değişkenini aşağıdakileri kullanarak ayarlayabilirsiniz:

export your_env_variable='your_password'

Bu yaklaşım Travis gibi sürekli entegrasyon hizmetleriyle kullanılabilir , bir GitHub deposunda saklanan kodunuz (parola olmadan) Travis tarafından yürütülebilir (parolanız ortam değişkeni kullanılarak ayarlanır).

Bash ile aşağıdakileri kullanarak bir ortam değişkeninin değerini elde edebilirsiniz:

echo "$your_env_variable"

Python ile aşağıdakileri kullanarak bir ortam değişkeninin değerini elde edebilirsiniz:

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

Not: muhtemelen biraz riskli olduğunu unutmayın (ancak oldukça yaygın bir uygulamadır) https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment-variables/

PS2: "API anahtarları nasıl güvenli bir şekilde saklanır"dev.to başlıklı bu makaleyi okumak ilginç olabilir.


1
Potansiyel "güvensiz" kod beeing yapısının ortam değişkeninizin içeriğini okumasını nasıl önleyebilirim?
gorootde


16

Ne Greg dedi ama bir dosyada kontrol etmek iyi bir fikir olduğunu eklemek istiyorum foobar.config-TEMPLATE.

Örnek adlar, parolalar veya diğer yapılandırma bilgilerini içermelidir. O zaman, değerlerin bulunması gereken tüm koda bakmak zorunda kalmadan, gerçek foobar.config dosyasının ne içermesi gerektiği çok açıktır.foobar.config ve hangi formata sahip .

Genellikle yapılandırma değerleri, veritabanı bağlantı dizeleri ve benzeri şeyler gibi belirgin olmayabilir.


7

Depolardaki parolalarla uğraşmak, sorunun ne olduğuna bağlı olarak farklı şekillerde ele alınacaktır.

1. Yapma.

Ve yapmaktan kaçınmanın yolları bazı yanıtlarda ele alınmıştır - .gitignore, config.example, vb.

veya 2. Havuzu yalnızca yetkili kişiler için erişilebilir hale getirin

Yani şifreyi bilen insanlar. chmodve kullanıcı grupları akla geliyor; ayrıca depolarınızı veya sunucularınızı dışarıda barındırıyorsanız Github veya AWS çalışanlarının bir şeyler görmesine izin verilmeli mi?

veya 3. Hassas verileri şifreleyin (bu cevabın amacı)

Hassas bilgiler içeren (şifreler gibi) yapılandırma dosyalarınızı herkese açık bir yerde saklamak istiyorsanız, şifrelenmesi gerekir. Depodan kurtarıldığında dosyaların şifresi çözülebilir, hatta doğrudan şifrelenmiş formlarından kullanılabilir.

Şifreli yapılandırma verilerinin kullanımına ilişkin örnek bir javascript çözümü aşağıda gösterilmiştir.

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);

Şifresi Çözülmüş Yapılandırma Dosyası

Böylece, sadece birkaç satır Javascript yazarak şifrelenmiş bir yapılandırma dosyasını kurtarabilirsiniz.

Bir dosyayı config.RSAgit deposuna koymanın, dosyayı ikili bir dosya haline getireceğini ve bu nedenle Git gibi bir şeyin faydalarının çoğunu kaybedeceğini unutmayın, örneğin değişiklikleri kiraz alma yeteneği.

Bunun çözümü, anahtar / değer çiftlerini veya belki de sadece değerleri şifrelemek olabilir. Örneğin hassas bilgiler için ayrı bir dosyanız varsa tüm değerleri şifreleyebilir veya bir dosyadaki tüm değerlere sahipseniz yalnızca hassas değerleri şifreleyebilirsiniz. (aşağıya bakınız)

Yukarıdaki örneğim, onunla bir test yapmak isteyen veya bazı RSA anahtarlarının ve şifreli bir yapılandırma dosyasının varlığını kabul ettiği için başlamak için bir örnek olarak işe yaramaz config.RSA.

RSA anahtarları ve oynatılacak bir yapılandırma dosyası oluşturmak için ek kod satırları eklendi.

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);

Yalnızca değerleri şifreleme

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

resim açıklamasını buraya girin

Böyle bir şey kullanarak şifrelenmiş değerlere sahip bir yapılandırma dosyasının şifresini çözebilirsiniz.

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

Her yapılandırma öğesi ayrı bir satırda (ör. HelloVe Goodbyeüstü), Git bir dosyada neler olup bittiğini daha iyi tanır ve bilgi öğelerindeki değişiklikleri tam dosyalar yerine farklılıklar olarak depolar. Git ayrıca birleştirme ve kiraz seçimlerini vb. Daha iyi yönetebilecektir.

Bununla birlikte, denetimin ne kadar çok sürümünü hassas bilgi olarak değiştirirseniz, GÜVENLİ BİR DEPOLAMA çözümüne (2) ve ENCRYPTED INFO (3) çözümünden o kadar uzaklaşırsınız.


3

Bir kullanabilirsiniz Vault Örneğin vb jeton, şifreler, sertifikalar API anahtarları e sabitler, mağazalar ve kontroller erişim yanıtlayıcı ' kullanan yanıtlayıcı' Vault şifre veya sertifikalarla fırsatlar playbooks kullanılan


Ansible Vault'u sadece örnek bir yapılandırma dosyası oluşturmaya kıyasla kesinlikle karmaşık buluyorum.
icc97

@ icc97 Evet, üzgün gerçek. Ancak bu olasılıktan bahsetmemiz gerekiyor. Benim düşünceme göre, daha karmaşık görevler için tek kullanıcılı ortam için birkaç parola depolamaktan başlayarak özel çözümler kullanmak daha iyidir.
El Ruso

2
Gelecekteki okuyuculara yardımcı olmak için: Vault ve Ansible Vault benzer isimlerle oldukça farklı ilgisiz projelerdir
bltavares

2

İşte kullandığım bir teknik:

Giriş klasörümde şu klasörü oluşturuyorum: .config

Bu klasöre, şifreleri ve anahtarları haricileştirmek istediğim çok sayıda şey için yapılandırma dosyalarını yerleştiriyorum.

Genellikle gibi ters etki alanı adı sözdizimi kullanın:

com.example.databaseconfig

Sonra bash betiğinde bunu yaparım:

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

|| exit 1O yapılandırma dosyası yüklemek mümkün değilse çıkmak için komut dosyası neden olur.

Bu tekniği bash, python ve ant komut dosyaları için kullandım.

Oldukça paranoyakım ve bir .gitignore dosyasının yanlışlıkla check-in yapılmasını önlemek için yeterince sağlam olduğunu düşünmüyorum. Ayrıca, bunu izleyen hiçbir şey yoktur, bu yüzden bir check-in olursa kimse bununla başa çıkmayı öğrenemezdi.

Belirli bir uygulama birden fazla dosya gerektiriyorsa, tek bir dosya yerine alt klasör oluştururum.


1

Raylarda yakut kullanıyorsanız, Figaro mücevher çok iyi, kolay ve güvenilirdir. Üretim ortamı ile de düşük bir baş ağrısı faktörüne sahiptir.


4
Bu gem'in ne yaptığı hakkında biraz ayrıntı verebilir misiniz? Bu şekilde (potansiyel olarak) birçok dilde uygulanabilir bir 'uygulama' olarak düşünülebilir.
mattumotu

medium.com/@MinimalGhost/… genel bir bakışa sahiptir, temel olarak bir yapılandırma dosyasından malzeme çekmeyi yönetir
tripleee

0

Güven ama doğrula.

Burada .gitignore"güvenli" bir dizin depodan hariç tutulur:

secure/

Ama ben paylaşıyorum @ Michael Potter paranoyasını . Bu yüzden .gitignore'u doğrulamak için, bu "güvenli" dizin check-in yaparsa bir klakson geliştirecek bir Python birim testi . Ve kontrolü kontrol etmek için, meşru bir dizin de test edilir:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.