web-dev-qa-db-ja.com

gitリポジトリでパスワードを処理するためのベストプラクティスは何ですか?

特定の状況でTwitterにアクセスしてGrowl通知をポップアップするために使用する小さなBashスクリプトがあります。スクリプトでパスワードの保存を処理する最良の方法は何ですか?

このスクリプトをgitリポジトリにコミットしてGitHubで利用できるようにしたいと思いますが、これを行う際にログイン/パスワードを非公開にしておく最善の方法は何だと思います。現在、パスワードはスクリプト自体に保存されています。古いコミットにはすべてパスワードが含まれるため、プッシュする直前に削除することはできません。パスワードなしで開発することは選択肢ではありません。外部の設定ファイルにパスワードを保存する必要があると思いますが、何かを試して組み立てる前に、これを処理する確立された方法があるかどうかを確認したいと思いました。

196
kubi

これを行う一般的な方法は、構成ファイルからパスワード情報を読み取ることです。構成ファイルの名前がfoobar.configの場合、foobar.config.exampleというファイルをサンプルデータを含むリポジトリにコミットします。プログラムを実行するには、realパスワードデータを使用して、foobar.configというローカル(追跡されない)ファイルを作成します。

以前のコミットから既存のパスワードを除外するには、 機密データの削除 のGitHubヘルプページを参照してください。

230
Greg Hewgill

環境変数を使用してパスワード(またはAPIキー)を設定する方法があります。したがって、このパスワードはリビジョン管理の対象外です。

Bashでは、次を使用して環境変数を設定できます。

export your_env_variable='your_password'

このアプローチは、 Travis などの継続的統合サービスで使用でき、コード(パスワードなし)は GitHubに格納されます リポジトリはTravisで実行できます(パスワードは環境変数を使用して設定されます)。

Bashでは、次を使用して環境変数の値を取得できます。

echo "$your_env_variable"

Pythonでは、次を使用して環境変数の値を取得できます。

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

PS:それはおそらく少し危険であることに注意してください(しかし、それは非常に一般的な方法です) https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment -変数/

PS2:このdev.toというタイトルの記事 「APIキーを安全に保存する方法」 は興味深いものです。

24
scls

Gregが言った しかし、ファイルfoobar.config-TEMPLATEをチェックインすることをお勧めします。

サンプル名、パスワード、またはその他の構成情報を含める必要があります。そうすれば、foobar.configに値が存在する必要があるすべてのコードと、そのフォーマットを調べる必要なく、実際のfoobar.configに何を含めるべきかが非常に明確になります。

多くの場合、構成値は、データベース接続文字列などのように明白ではない場合があります。

16
Prof. Falken

トークン、パスワード、証明書、APIキーなどへのアクセスを保護、格納、制御する Vault を使用できます。たとえば、 Ansible は、Playbookで使用されるパスワードまたは証明書を扱う Ansible Vault を使用します

2
El Ruso

私が使用するテクニックは次のとおりです。

ホームフォルダーに.configというフォルダーを作成します

そのフォルダーに、パスワードとキーを外部化したいものをいくつでも構成ファイルを配置します。

通常、次のような逆ドメイン名構文を使用します。

com.example.databaseconfig

次に、bashスクリプトでこれを行います。

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

|| exit 1により、構成ファイルをロードできない場合にスクリプトが終了します。

私はbash、python、およびantスクリプトにこの手法を使用しました。

私はかなり妄想的であり、.gitignoreファイルが不注意なチェックインを防ぐのに十分なほど堅牢であるとは思わない。さらに、それを監視するものは何もありません。したがって、チェックインが発生した場合、誰もそれを処理することができません。

特定のアプリケーションが複数のファイルを必要とする場合、単一のファイルではなくサブフォルダーを作成します。

2
Michael Potter

リポジトリ内のパスワードの処理は、正確な問題が何であるかに応じて異なる方法で処理されます。

1.それをしないでください。

そして、回避する方法はいくつかの応答でカバーされています-.gitignore、config.exampleなど

または2.許可された人だけがリポジトリにアクセスできるようにします

つまりパスワードを知ることを許可されている人々。 chmodとユーザーグループが思い浮かびます。また、リポジトリまたはサーバーを外部でホストしている場合、GithubまたはAWSの従業員が物事を閲覧できるようにする必要があるなどの問題もありますか?

または3.機密データを暗号化する(この返信の目的)

機密情報(パスワードなど)を含む構成ファイルを公共の場所に保存する場合は、暗号化する必要があります。ファイルは、リポジトリから復元されるときに復号化されるか、暗号化された形式から直接使用されることさえあります。

暗号化された構成データを使用するJavaScriptソリューションの例を以下に示します。

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

Decrypted Config File

そのため、数行のJavascriptを書き込むだけで、暗号化された構成ファイルを回復できます。

ファイルconfig.RSAをgitリポジトリに配置すると、事実上それがバイナリファイルになり、Gitなどの利点の多くが失われることに注意してください。変更をチェリーピックする機能。

その解決策は、キーと値のペアまたはおそらく値のみを暗号化することです。たとえば、機密情報用の別のファイルがある場合はすべての値を暗号化し、1つのファイルにすべての値がある場合は機密値のみを暗号化します。 (下記参照)

上記の私の例は、それを使ってテストをしたい人や、いくつかのRSAキーと暗号化された構成ファイル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');

enter image description here

このようなものを使用して、暗号化された値で構成ファイルを復号化できます。

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はファイル内で行われていることをよりよく認識し、情報のアイテムへの変更を完全なファイルではなく差分として保存します。 Gitは、マージやチェリーピックなどをより適切に管理することもできます。

ただし、機密情報への変更をバージョン管理したいほど、SAFE REPOSITORYソリューション(2)およびENCRYPTED INFO(3)ソリューションから離れることになります。

1
Ivan

RailsでRubyを使用している場合、Figaro gemは非常に優れており、簡単で、信頼性があります。本番環境でも頭痛の要因は低いです。

0
ahnbizcad

信頼するが検証する。

.gitignoreでは、これは「セキュア」ディレクトリをリポジトリから除外します。

secure/

しかし、私は@ Michael Potter のパラノイアを共有しています。 .gitignoreを検証するために、ここに Pythonunit testがあります。そして、チェックをチェックするために、正当なディレクトリもテストされます:

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)
0
Bob Stein