2012-07-20 21 views
122

我保留了我的版本控制系統中的重要設置,例如開發和生產服務器的主機名和端口。但是我知道它是壞習慣在VCS存儲庫中保留機密(如私鑰和數據庫密碼)。如何在我的版本控制系統中安全地保存我的密鑰和密碼?

但是,像其他任何設置一樣,密碼看起來應該是版本化的。那麼什麼保持密碼版本控制的正確方法?

我想這將涉及保持祕密在自己的「祕密設置」文件,該文件加密和版本控制有。但是什麼技術?如何正確地做到這一點?有沒有更好的方法去完成它?


我問的問題一般,但在我的具體情況我想用來存儲密鑰和密碼使用混帳github上一個Django的/ Python的網站。

而且,理想解決方案時,我把用git /拉會做一些不可思議 - e.g,如果加密的密碼文件變化的腳本運行它要求輸入密碼,並解密到位。


編輯:爲清楚起見,我 詢問在哪裏存儲 生產祕密。

+1

實際上拿出一些錢保持整個回購私人。 – 2012-07-20 08:22:13

+22

@JohnMee我實際上已經爲私人存儲庫付錢了,但問題依然存在 - 你不應該在你的存儲庫中保存敏感信息。 – 2012-07-20 08:25:10

+1

我認爲滿足答案的很大一部分原因很難得到,即連接到數據庫的老式明文密碼是一個不那麼敵對的時代的遺蹟。正確的答案就像「你的代碼不需要祕密」,但你訪問的系統並沒有給你太多的選擇。 – msw 2012-07-26 11:54:34

回答

4

既然問了這個問題,我已經解決了一個解決方案,我使用這個解決方案在小團隊中開發小應用程序。

git-crypt

混帳墓穴使用GPG時,他們的名稱與特定模式來透明地加密文件。對於intance,如果您添加到您的.gitattributes文件...

*.secret.* filter=git-crypt diff=git-crypt 

...然後像config.secret.json文件總是會被推到加密的遠程回購,但你的本地文件系統上保持不加密。

如果我想添加一個新的GPG鍵(一個人)到您的回購能夠解密受保護的文件,然後運行git-crypt add-gpg-user <gpg_user_key>。這會創建一個新的提交。新用戶將能夠解密後續提交。

11

一個選項是將項目綁定憑證放入加密容器(TrueCrypt或Keepass)中並將其推送。

更新從下面我的評論答案:

有趣BTW問題。我剛剛發現這個:github.com/shadowhand/git-encrypt它看起來很有前途的自動加密

+0

這將是不錯的我可以自動化的東西。這樣,如果我的加密密碼文件發生更改,它會自動解密新文件。 – 2012-07-20 08:21:22

+7

有趣的問題btw。我剛剛發現了這個:https://github.com/shadowhand/git-encrypt,它對於自動加密看起來很有希望。 – schneck 2012-07-20 08:24:37

+1

哇,太好了。 「git-encrypt」的描述聽起來像我正在尋找的內容「在使用託管在第三方存儲服務器上的遠程git存儲庫時,數據機密性有時成爲問題。本文將逐步介紹這些過程設置您的本地工作目錄正常(未加密)的git存儲庫,但提交的內容已加密。「 (當然,我只希望我的內容的一個子集加密...) – 2012-07-20 08:27:26

9

我建議使用配置文件,而不是版本他們。

然而,您可以使用這些文件的版本示例。

我沒有看到任何共享開發設置的問題。根據定義,它不應包含有價值的數據。

+0

但是,那麼在哪裏存儲規範的密碼記錄?這讓我感到緊張,只能將這些數據放在一臺機器上的配置文件中,而這臺機器有一天可能會被炸燬。 – 2012-07-20 08:23:38

+0

@ChrisW。如果機器發生故障,您不一定需要密碼......但是,如果您的生產機器上只有一個數據副本,則應該產生紅旗。但這並不意味着它應該在VCS中。應該有RAID,完整備份以及磁盤和光盤上的增量備份。許多公司都有一個變更控制程序,可能會規定如何以及在哪裏在紙上存儲密碼和其他敏感材料。 – 2012-07-29 16:58:52

+0

@ChrisW我不''想粗糙,但它似乎你不告訴我們真相,你想存儲的密碼不用於開發,但在生產。這不正確嗎?否則,爲什麼你會關心開發或測試機器和開發密碼?沒有人會這樣做。 – tiktak 2012-07-30 17:59:47

2

通常,我將密碼分隔爲一個配置文件。並讓他們分開。

/yourapp 
    main.py 
    default.cfg.dist 

當我運行main.py,放在default.cfg真正的密碼複製。

ps。當你使用git或hg工作時。你可以忽略*.cfg文件製作.gitignore.hgignore

+0

我不熟悉'.dist'文件 - 它們是如何工作的? – 2012-07-30 16:53:38

+0

.dist文件就是我所說的:真實配置文件的例子。一個好的做法是,應該可以僅通過刪除「.dist」擴展名(或更好地:複製)來重命名來運行軟件,也就是說,您應該可以在幾秒鐘內嘗試軟件,而無需在進行配置時整整一天。 – tiktak 2012-07-30 18:04:18

16

我認爲最簡潔的方法是使用環境變量。你將不必處理。例如,文件名爲,生產環境中的項目狀態與本地機器相同。

我建議您閱讀The Twelve-Factor App的配置章節,如果您有興趣,也可以閱讀其他章節。

+6

似乎環境變量是使用祕密設置運行應用程序的好方法......但它仍然不能回答這些設置保留在哪裏的問題。 – 2012-07-27 21:22:35

+2

您通常應該爲每個應用程序都有一個自述文件。在那裏,指定應設置哪些環境變量,並且每次部署項目時,只需按照步驟進行設置即可。 你也可以用許多'export MY_ENV_VAR ='創建一個shell腳本,當你部署時,只需要用正確的值和'source'來填充它。 如果通過*保留*你的意思是版本的設置,你不應該這樣做的第一個地方。 – 2012-07-27 22:46:36

+0

另外,upvote爲[十二因子應用程序](http://www.12factor.net/config) - 非常好的東西。 – 2012-08-01 07:05:15

4

編輯:我假設你想跟蹤你以前用過的密碼版本的 - 比如說,一個腳本,將防止密碼重用等

我覺得GnuPG是去的最佳途徑 - 它已經使用在一個git相關項目(git-annex)中加密存儲在雲服務上的存儲庫內容。 GnuPG(gnu pgp)提供了一個強大的基於密鑰的加密。

  1. 您在本地計算機上保留密鑰。
  2. 您將'mypassword'添加到忽略的文件。
  3. 在預提交鉤子上,您將mypassword文件加密到由git跟蹤的mypassword.gpg文件中,並將其添加到提交中。
  4. 在合併後掛鉤上,您只需將mypassword.gpg解密爲mypassword。

現在,如果你的「MYPASSWORD」文件並沒有改變,然後將其加密會導致與相同的密文,它不會被添加到索引(無冗餘)。對mypassword進行最細微的修改會導致完全不同的密文,並且臨時區域中的mypassword.gpg與存儲庫中的密碼不同,因此會被添加到提交中。即使攻擊者獲得了你的gpg密鑰,他仍然需要暴力破解密碼。如果攻擊者以密文訪問遠程存儲庫,他可以比較一堆密文,但是他們的數量不足以給他帶來任何不可忽略的優勢。

稍後,您可以使用.gitattributes爲您的密碼的退出git diff提供即時解密。

您也可以爲不同類型的密碼等的單獨按鍵

5

我問的問題一般,但在我的具體情況,我想 存儲密鑰和密碼一個Django/Python的網站使用git 和github。

不,只是不要,即使它是你的私人回購,你從不打算分享它,不要。

您應該創建一個local_settings.py把它放在VCS忽略並在settings.py這樣做

from local_settings import DATABASES, SECRET_KEY 
DATABASES = DATABASES 

SECRET_KEY = SECRET_KEY 

如果你的祕密設置是通用的,我渴望說,你正在做的事情錯誤

+7

但我仍然需要跟蹤那些祕密*的某處*。例如,keypass或者其他的東西,對嗎? – 2012-07-20 21:44:29

+0

存儲私人數據的管理和實施取決於項目所在公司的政策。我非常懷疑項目的源代碼是否正確,因爲任何第三方測試人員或程序員都可以看到這些 – 2016-11-24 11:25:48

2

加密密碼文件,例如使用GPG。將密鑰添加到本地計算機和服務器上。解密該文件並將其放在回購文件夾之外。

我使用一個passwords.conf,位於我的homefolder。每次部署時,這個文件都會被更新。

+0

然後軟件需要解密密碼文件。 – tiktak 2012-07-30 18:05:38

+0

那麼,只有在部署該網站時將密碼解密並寫入純文本密碼文件 – Willian 2012-07-31 07:21:40

50

Heroku的推動the use of environment variables的設置和密鑰:

處理這種配置瓦爾是將它們放在源的傳統做法 - 在某種屬性文件。這是一個容易出錯的過程,對於開源應用程序尤其複雜,因爲這些應用程序通常必須使用應用程序特定的配置來維護單獨的(和專用的)分支機構。

更好的解決方案是使用環境變量,並將代碼保留在外。在傳統主機上或在本地工作,您可以在您的bashrc中設置環境變量。在Heroku上,你使用config vars。

隨着工頭和.env文件Heroku提供了一個令人羨慕的工具鏈來導出,導入和同步環境變量。


個人而言,我相信將密鑰與代碼一起保存是錯誤的。它與源代碼控制從根本上不一致,因爲這些密鑰用於服務外部代碼爲。一個好處是開發人員可以克隆HEAD並在沒有任何設置的情況下運行應用程序。但是,假設開發人員檢查代碼的歷史版本。他們的副本將包含去年的數據庫密碼,所以應用程序將會在今天的數據庫中失敗。

使用上面的Heroku方法,開發人員可以簽出去年的應用程序,使用今天的密鑰進行配置,然後在今天的數據庫中成功運行。

+1

這個答案沒有足夠的重視,但它最符合linux的方式。 – 2012-08-01 08:53:41

+10

因此,如果環境變量設置在你的bashrc中,並且你正在部署一個新的服務器,那麼什麼創建了bashrc?這不僅僅是將密碼從您的源代碼倉庫中移出,而是移入您的部署配置中? (這大概也在源代碼回購,或在它自己的回購?) – 2013-02-01 16:14:21

+0

@JonathanHartley您的.bashrc不應該在您的Django應用程序的代碼回購。 – Steve 2015-05-11 01:26:41

94

您完全正確地想要加密您的敏感設置文件,同時仍然在版本控制中維護該文件。正如你所提到的,最好的解決方案是,當你推送它們時,Git會透明地加密某些敏感文件,以便在本地(即在任何擁有你的證書的機器上)使用設置文件,但Git或Dropbox或任何人將文件存儲在VC下不能以純文本形式讀取信息。按期間

教程上的透明加密/解密/拉

這個要點https://gist.github.com/873637顯示瞭如何使用Git的污跡/清潔過濾器驅動程序使用OpenSSL透明地加密文件推的教程。你只需要做一些初始設置。

摘要它是如何工作

你基本上可以創建一個包含3個的bash腳本.gitencrypt文件夾,

這是使用Git的解密,加密,並支持git的差異
clean_filter_openssl 
smudge_filter_openssl 
diff_filter_openssl 

。主密碼和salt(固定!)在這些腳本內部定義,並且您必須確保.gitencrypt從不被實際推送。 例clean_filter_openssl腳本:

#!/bin/bash 

SALT_FIXED=<your-salt> # 24 or less hex characters 
PASS_FIXED=<your-passphrase> 

openssl enc -base64 -aes-256-ecb -S $SALT_FIXED -k $PASS_FIXED 

類似爲smudge_filter_open_ssldiff_filter_oepnssl。參見Gist。

您的敏感信息回購應該有一個.gitattribute文件(未加密幷包含在回購中)引用。gitencrypt目錄(其中包含Git透明地加密/解密項目所需的所有內容)以及本地計算機上存在的目錄。

.gitattribute內容:

* filter=openssl diff=openssl 
[merge] 
    renormalize = true 

最後,您還需要將以下內容添加到您的.git/config文件

[filter "openssl"] 
    smudge = ~/.gitencrypt/smudge_filter_openssl 
    clean = ~/.gitencrypt/clean_filter_openssl 
[diff "openssl"] 
    textconv = ~/.gitencrypt/diff_filter_openssl 

現在,當你把包含您的敏感信息發送到遠程倉庫存儲庫,這些文件將被透明加密。當您從具有.gitencrypt目錄的本地機器(包含您的密碼短語)中取出時,這些文件將被透明地解密。

注意

我要指出,本教程不描述了一種只加密您的敏感設置文件。這將透明地加密推送到遠程VC主機的整個存儲庫,並對整個存儲庫進行解密,以便在本地完全解密。爲了實現你想要的行爲,你可以將一個或多個項目的敏感文件放在一個sensitive_settings_repo中。如果您確實需要將敏感文件放在同一個存儲庫中,則可以調查此透明加密技術如何與Git子模塊http://git-scm.com/book/en/Git-Tools-Submodules一起使用。

如果攻擊者可以訪問許多加密的Repos /文件,則使用固定密碼短語理論上可能導致強力漏洞。國際海事組織,這個可能性非常低。正如本教程底部提到的一樣,不使用固定密碼短語會導致不同機器上的本地版本的回購站點總是顯示使用'git status'發生的更改。

+1

哦很有意思。這聽起來*幾乎*完全像我想要的(除了它加密整個存儲庫)。 – 2012-07-27 21:21:23

+0

您可以將多個應用程序的所有敏感設置文件保存在一個加密存儲庫中,或者將敏感設置的加密存儲庫作爲Git子模塊添加到項目中,如http://git-scm.com/book/en/ Git-Tools-Submodules。 – dghubble 2012-07-27 23:17:40

+0

將生產密碼/設置存儲在(加密的)子模塊中並不少見。 http://stackoverflow.com/questions/11207284/put-only-a-single-file-in-git-submodule-repository。它甚至可以更輕鬆地管理跨項目的設置。 – dghubble 2012-07-27 23:22:50

3

提供一種方法來覆蓋配置

這是管理一套健全的默認設置爲您無需配置完整,或含有類似的事情主機名和憑據籤的配置的最佳途徑。有幾種方法可以覆蓋默認配置。

環境變量(如其他人已經提到過的)是這樣做的一種方式。

最好的方法是查找覆蓋默認配置值的外部配置文件。這使您可以通過Chef,Puppet或Cfengine等配置管理系統管理外部配置。配置管理是配置管理與代碼庫分開管理的標準答案,因此您不必執行發佈來更新單個主機或一組主機上的配置。

僅供參考:加密信用並不總是最佳實踐,尤其是在資源有限的地方。可能是這樣的情況,加密信用將無法獲得額外的風險緩解並簡單地添加不必要的複雜層。確保在做出決定之前做適當的分析。

2

不,私鑰和密碼不屬於修訂控制。沒有理由讓每個讀取存儲庫的人都知道敏感的服務憑證,因爲他們很可能不是所有人都可以訪問這些服務。

從Django開始1。4,您的Django項目現在隨附project.wsgi模塊,該模塊定義了application object,它是開始強制使用包含站點特定配置的project.local設置模塊的理想場所。

此設置模塊在版本控制中被忽略,但是當您將項目實例作爲WSGI應用程序運行時(在生產環境中通常使用它)時,此設置模塊是必需的。這是應該的樣子:

import os 

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.local") 

# This application object is used by the development server 
# as well as any WSGI server configured to use this file. 
from django.core.wsgi import get_wsgi_application 
application = get_wsgi_application() 

現在你可以有一個local.py模塊誰是所有者和組可進行配置,以便只有授權人員和Django的過程中可以讀取該文件的內容。

0

如果你的系統提供了,你可以使用EncFS。因此,您可以將加密的數據作爲存儲庫的子文件夾,同時爲您的應用程序提供解密的視圖,以便將數據放在一邊。由於加密是透明的,所以在拉或推時不需要特殊操作。

然而,它需要掛載EncFS文件夾,這可以由您的應用程序根據存儲在版本化文件夾以外的密碼(例如環境變量)來完成。

2

如果你需要VCS的祕密,你至少應該把它們放在與你實際代碼分開的第二個倉庫中。所以你可以讓你的團隊成員訪問源代碼庫,他們不會看到你的憑據。此外,在其他地方(例如,在您自己的服務器上使用加密文件系統,而不是在github上)託管此存儲庫,並將其檢出到生產系統,您可以使用類似git-submodule之類的東西。

7

BlackBox最近由StackExchange發佈,雖然我還沒有使用它,但它似乎正好解決了這個問題中的問題並支持這些功能。

從說明書上https://github.com/StackExchange/blackbox

安全存儲在VCS回購(即GIT中或水銀)祕密。這些 命令可讓您輕鬆地對GPO中的特定文件進行加密,使其在存儲庫中處於「靜態加密」狀態。但是,當您需要查看或編輯 這些腳本時, 腳本可以很容易地解密它們,並將它們解密以便在生產中使用。

1

另一種方法可以完全避免在版本控制系統保存的祕密,而使用的工具像vault from hashicorp,與主要軋製和審計祕密儲存,使用API​​和嵌入式加密。

相關問題