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