如何在Linux上最妥善地管理加密密鑰?
譯文存儲(chǔ)SSH加密密鑰和牢記密碼可能是一件讓人很頭痛的事兒。不過遺憾的是,在如今惡意黑客和漏洞猖獗的年頭,做好基本的安全防范措施是必不可少的做法。對(duì)于許多普通用戶來說,這就意味著只是牢記密碼,可能還要找到一款存儲(chǔ)密碼的優(yōu)秀軟件,因?yàn)槲覀兲嵝哑胀ㄓ脩舨灰總€(gè)網(wǎng)站都使用一樣的密碼。但是對(duì)于從事不同IT行業(yè)領(lǐng)域的我們這些人來說,我們就需要在此基礎(chǔ)上更進(jìn)一步。我們還要處理SSH密鑰之類的加密密鑰,而不僅僅是密碼。
一種場(chǎng)景如下:我在云上運(yùn)行一臺(tái)服務(wù)器,用于我的主git軟件庫(kù)。我有好多臺(tái)辦公用的計(jì)算機(jī)。所有那些計(jì)算機(jī)都需要登錄進(jìn)入到那臺(tái)中央服務(wù)器,以便推送和獲取內(nèi)容。我設(shè)置了git以便使用SSH。git使用SSH時(shí),git登錄進(jìn)入到服務(wù)器的方式實(shí)際上與啟動(dòng)命令行、使用SSH命令接入到服務(wù)器一樣。為了配置一切,我在.ssh目錄中創(chuàng)建了一個(gè)配置文件,里面含有的Host項(xiàng)提供了服務(wù)器名稱、主機(jī)名稱、登錄用戶以及密鑰文件路徑。然后,我只要輸入下列命令,就可以測(cè)試一下這個(gè)配置:
ssh gitserver
很快我就看到了服務(wù)器的bash外殼?,F(xiàn)在,我可以配置git,使用這同一個(gè)項(xiàng),用存儲(chǔ)的密鑰登錄進(jìn)去。容易得很,除了有一個(gè)問題:對(duì)于用來登錄進(jìn)入到那臺(tái)服務(wù)器的每臺(tái)計(jì)算機(jī)而言,我都需要有一個(gè)密鑰文件。這意味著會(huì)有不止一個(gè)密鑰文件。我在這臺(tái)計(jì)算機(jī)上有幾個(gè)這樣的密鑰,在其他計(jì)算機(jī)上有幾個(gè)這樣的密鑰。正如普通用戶有無數(shù)個(gè)密碼那樣,我們IT人員到頭來很容易會(huì)有無數(shù)個(gè)密鑰文件。這該如何是好?
清理亂局
在開始使用一款軟件幫助管理密鑰之前,你得做好一些基礎(chǔ)工作,弄清楚應(yīng)該如何處理密鑰、我們提出的問題到底是否合理。而這首先需要你明白自己的公鑰放在哪里、私鑰又放在哪里。假設(shè)你已知道下列這些:
1. 公鑰與私鑰的區(qū)別
2. 為什么無法利用公鑰生成私鑰,但是卻可以利用私鑰生成公鑰。
3. authorized_keys文件的用途以及它放在何處。
4. 你如何使用私鑰,登錄進(jìn)入到在authorized_keys文件中有對(duì)應(yīng)公鑰的服務(wù)器。
這里有個(gè)例子。你在亞馬遜網(wǎng)絡(luò)服務(wù)(AWS)平臺(tái)上創(chuàng)建一臺(tái)云服務(wù)器時(shí),就得提供一個(gè)SSH密鑰,用來連接到你的服務(wù)器。每把密鑰都有公開部分和私密部分。因?yàn)槟阆M约旱姆?wù)器保持安全,乍一看,你似乎把私鑰放在那臺(tái)服務(wù)器上,并將公鑰貼身帶著。畢竟,你不希望那臺(tái)服務(wù)器可以公開訪問,不是嗎?但其實(shí)正好相反。
保管那把私鑰,并放在身邊,而不是放在某臺(tái)遠(yuǎn)程服務(wù)器上。
你把公鑰放在AWS服務(wù)器上,牢牢保管用來登錄進(jìn)入到服務(wù)器的私鑰。你保管那把私鑰,并放在身邊,而不是放在某臺(tái)遠(yuǎn)程服務(wù)器上,如上圖所示。
原因如下:即便公鑰被別人知道了,他們也無法登錄進(jìn)入到服務(wù)器,因?yàn)樗麄儧]有私鑰。此外,如果有人確實(shí)設(shè)法闖入了你的服務(wù)器,他們發(fā)現(xiàn)的只是公鑰。無法利用公鑰生成私鑰。所以,如果你在其他服務(wù)器上使用同樣這個(gè)密鑰,他們無法用該密鑰來登錄進(jìn)入到其他那些計(jì)算機(jī)。
這就是為什么你把公鑰放在自己的服務(wù)器上,用來通過SSH登錄進(jìn)入到服務(wù)器。私鑰是你貼身帶著的。你不允許那些私鑰落到別人手里。
但是仍然有問題。以我的git服務(wù)器為例。我要做幾個(gè)決定。有時(shí)候,我登錄進(jìn)入到托管在別處的開發(fā)服務(wù)器。在那臺(tái)開發(fā)服務(wù)器上,我需要連接到我的那臺(tái)git服務(wù)器。開發(fā)服務(wù)器如何才能連接到git服務(wù)器?通過使用私鑰。而這里就存在問題。這種場(chǎng)景需要我把私鑰放在托管在別處的服務(wù)器上,這么做可能很危險(xiǎn)。
現(xiàn)在看看進(jìn)一步的場(chǎng)景:如果我使用單一密鑰登錄進(jìn)入到多臺(tái)服務(wù)器,會(huì)怎樣?如果入侵者設(shè)法弄到了這樣一把私鑰,他有了該私鑰后可以進(jìn)而訪問整個(gè)服務(wù)器虛擬網(wǎng)絡(luò),準(zhǔn)備搞一些嚴(yán)重的破壞。這可不是什么好事。
而這當(dāng)然引出了另一個(gè)問題:我是否應(yīng)該對(duì)另外那些服務(wù)器使用同一把密鑰?就像我剛才描述的那樣,這可能很危險(xiǎn)。
最后,這聽起來一團(tuán)糟,不過有一些簡(jiǎn)單的解決辦法。不妨逐一介紹。
(注意:除了僅僅登錄進(jìn)入到服務(wù)器外,還有許多地方要用到密鑰,不過我介紹這一種場(chǎng)景是為了表明你在處理密鑰時(shí)面臨的問題。)
重視通行碼
你在創(chuàng)建密鑰時(shí),可以選擇添加通行碼(passphrase),使用私鑰時(shí)需要通行碼。有了這個(gè)通行碼,私鑰文件本身使用通行碼來加密。比如說,如果你將公鑰存儲(chǔ)在服務(wù)器上,使用私鑰登錄進(jìn)入到該服務(wù)器,就會(huì)看到輸入通行碼的提示。要是沒有通行碼,密鑰就沒法使用。另外,你可以配置私鑰,一開始沒有通行碼。那樣,你只需要登錄進(jìn)入到服務(wù)器的密鑰文件。
對(duì)用戶來說通常不用通行碼更容易,但是我強(qiáng)烈建議在許多情況下使用通行碼,一個(gè)理由是,如果私鑰文件被偷,偷走文件的人還是沒法使用它,除非他能查明通行碼。從理論上來說,這可以為你贏得時(shí)間,因?yàn)槟憧梢栽诠粽甙l(fā)現(xiàn)通行碼之前將公鑰從服務(wù)器上刪除,因而保護(hù)系統(tǒng)。使用通行碼還有其他理由,不過光這個(gè)理由就值得我在許多情況下使用它。(舉例說,我在安卓平板電腦上裝有VNC軟件。平板電腦存有我的私鑰。如果平板電腦被偷了,我可以立即從平板電腦登錄進(jìn)入的服務(wù)器廢除公鑰,讓私鑰毫無用處,有沒有通行碼都沒有關(guān)系。)不過在一些情況下,我并不使用通行碼,因?yàn)槲业卿涍M(jìn)入的服務(wù)器可能沒有太多的寶貴數(shù)據(jù)在上面。這要看具體情況。
服務(wù)器基礎(chǔ)設(shè)施
你如何設(shè)計(jì)服務(wù)器基礎(chǔ)設(shè)施將影響到如何管理密鑰。比如說,如果你有多個(gè)用戶要登錄,就需要確定每個(gè)用戶是否獲得單獨(dú)的密鑰。(通常來說,他們應(yīng)該獲得單獨(dú)的密鑰;你不希望用戶共享私鑰。那樣一來,如果某個(gè)用戶離開了企業(yè)或者失去了信任,你就可以廢除該用戶的密鑰,沒必要為另外每個(gè)用戶生成新密鑰。同樣,如果共享密鑰,他們就能以彼此的身份登錄進(jìn)去,這同樣不好。)但是另一個(gè)問題是,你如何分配服務(wù)器。比如說,你使用某種工具(比如Puppet)來分配許多服務(wù)器嗎?是否基于自己的映像來創(chuàng)建多臺(tái)服務(wù)器?如果你復(fù)制服務(wù)器,每臺(tái)服務(wù)器是否需要有同樣的密鑰?不同的云服務(wù)器軟件讓你可以配置這方面,具體看你怎么選擇了??梢宰尫?wù)器獲得同一密鑰,也可以為每臺(tái)服務(wù)器生成新的密鑰。
如果你處理的是復(fù)制的服務(wù)器,要是用戶需要使用不同的密鑰登錄進(jìn)入到兩臺(tái)其他方面相似的不同服務(wù)器,就會(huì)讓人犯暈。但是另一方面,讓幾臺(tái)服務(wù)器共享同一密鑰存在安全風(fēng)險(xiǎn)?;蛘吡硪环矫?,如果你的密碼需要用于登錄之外的用途(比如掛載加密的驅(qū)動(dòng)器),那么你就需要同一密鑰在多個(gè)地方。正如你所見,是否需要在不同的服務(wù)器上使用同一密鑰不是我可以為你做出的決定;有一些地方需要取舍,你要自行決定什么最合適。
最后,你可能會(huì)有:
•需要登錄進(jìn)入的多臺(tái)服務(wù)器;
•登錄進(jìn)入不同服務(wù)器的多個(gè)用戶,每個(gè)用戶有各自的密鑰;
•每個(gè)用戶有多把密鑰,以便登錄進(jìn)入到不同的服務(wù)器。
(如果你在其他情況下使用密鑰――你可能會(huì)這樣,說到如何使用密鑰,需要多少密鑰,是否共享密鑰以及你如何處理密鑰的公共部分和私密部分,同樣的基本概念仍會(huì)適用。)
安全方法
知道自己的基礎(chǔ)設(shè)施和獨(dú)特情況后,你就需要制定一項(xiàng)密鑰管理方案,幫助你指導(dǎo)如何分發(fā)和存儲(chǔ)密鑰。比如說,正如前文所述,如果我的平板電腦被偷,但愿平板電腦被用來訪問服務(wù)器之前,我可以從服務(wù)器上廢除公鑰。正因?yàn)槿绱?,我在總體計(jì)劃中需要考慮到下列情況:
1. 私鑰存放在移動(dòng)設(shè)備上沒關(guān)系,但是它們必須包通行碼。
2. 必須有一種方法可以從服務(wù)器迅速?gòu)U除公鑰。
在你的情況下,你可能決定根本不想要為頻繁登錄的系統(tǒng)使用通行碼;比如說,系統(tǒng)可能是開發(fā)人員每天登錄好多次的測(cè)試機(jī)器。那很好,但是那樣的話你就需要稍微調(diào)整一下規(guī)則。你可能要添加一條規(guī)則,規(guī)定不得從移動(dòng)設(shè)備登錄進(jìn)入到該機(jī)器。換句話說,你需要根據(jù)自己的情況來制定規(guī)程,而不是想當(dāng)然地認(rèn)為有一應(yīng)俱全的做法。
軟件
再來說說軟件。奇怪的是,沒有許多優(yōu)秀而可靠的軟件解決方案用來存儲(chǔ)和管理你的私鑰??紤]這一點(diǎn):如果有一款軟件為你的所有服務(wù)器存儲(chǔ)所有密鑰,該軟件又由一個(gè)快捷密碼所保護(hù),你的密鑰果真安全嗎?或者類似的是,如果你的私鑰放在硬驅(qū)上以便SSH軟件快速訪問,密鑰管理軟件果真提供得了任何保護(hù)嗎?
但是就整個(gè)基礎(chǔ)設(shè)施和創(chuàng)建及管理公鑰而言,還是有一些解決方案。我已經(jīng)提到了Puppet。在Puppet界,你可以創(chuàng)建模塊,以不同的方式來管理服務(wù)器。其想法在于,服務(wù)器是動(dòng)態(tài)的,未必是彼此的精確副本。這里有一種巧妙的方法:http://manuel.kiessling.net/2014/03/26/building-manageable-server-infrastructures-with-puppet-part-4/,在不同服務(wù)器上使用同一密鑰,但是為每個(gè)用戶使用不同的Puppet模塊。這種解決辦法可能適合你,也可能不適合你。
或者,另一種辦法就是完全改弦易轍。在Docker界,你可以采取一種不同的方法,關(guān)于SSH和Docker的這篇博文作了詳細(xì)介紹:http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/。
但是管理私鑰怎么樣?如果你搜索一下,找不到許多軟件方案,我在上面提到了原因;私鑰放在你的硬驅(qū)上,管理軟件可能無法提供太多的額外安全。但是我確實(shí)使用這種方法來管理密鑰:
首先,我在.ssh/config文件中有多個(gè)Host項(xiàng)。我有一個(gè)項(xiàng)用于登錄的主機(jī),但是有時(shí)候我有多個(gè)項(xiàng)用于單個(gè)主機(jī)。如果我要多次登錄,就會(huì)出現(xiàn)這種情況。我有兩種不同的機(jī)制來登錄托管git軟件庫(kù)的那臺(tái)服務(wù)器;一種完全用于git,另一種用于一般用途的bash訪問。用于git的那種登錄大大限制了那臺(tái)機(jī)器上的權(quán)限。還記得我前面說的放在遠(yuǎn)程開發(fā)機(jī)器上的git密鑰嗎?雖然那些密鑰可以用來登錄進(jìn)入到我的其中一臺(tái)服務(wù)器,但使用的帳戶受到了嚴(yán)重限制。
其次,大多數(shù)這些私鑰包括通行碼。(如果遇到非要多次輸入通行碼,可以考慮使用ssh-agent。)
第三,我確實(shí)有一些服務(wù)器想更認(rèn)真一點(diǎn)地得到保護(hù),我在Host文件中沒有對(duì)應(yīng)的項(xiàng)。這更像是社會(huì)工程學(xué)層面,因?yàn)槊荑€文件仍在那里,但是需要入侵者花更長(zhǎng)一點(diǎn)的時(shí)間來找到密鑰文件,弄清楚對(duì)哪臺(tái)機(jī)器下手。那種情況下,我只要手動(dòng)輸入長(zhǎng)長(zhǎng)的ssh命令(這其實(shí)不是那么差勁)。
你能看到,我并不使用任何特殊軟件來管理這些私鑰。
沒有一應(yīng)俱全的做法
我們偶爾會(huì)接到讀者拋出的問題,問有什么好的軟件可用于管理密鑰。但是不妨先冷靜想一想。這個(gè)問題其實(shí)需要用不同的方式來表達(dá),因?yàn)楦静淮嬖谝粦?yīng)俱全的解決方案。你應(yīng)該根據(jù)自己的情況提出問題。你只是試圖找個(gè)地方來存儲(chǔ)密鑰文件?還是在尋找一種辦法來管理多個(gè)用戶,每個(gè)用戶有各自的公鑰,這些公鑰又需要插入到authorized_keys文件?
我在這篇文章中介紹了基本方面,但愿現(xiàn)在你能明白,只有你提出了正確的問題,才知道如何管理密鑰,以及應(yīng)該尋找什么樣的軟件(如果你果真需要額外軟件的話)。
英文:How to Best Manage Encryption Keys on Linux