看完這篇不在擔心刪庫跑路

大雄45發表於2020-12-10
導讀 開發人員經常需要訪問某些伺服器,做一些檢查應用程式日誌之類的工作。到目前為止,這還沒什麼問題。但是,當一名開發人員離職時又會發生什麼事情呢?

開發人員經常需要訪問某些伺服器,做一些檢查應用程式日誌之類的工作。

一般來說,訪問過程是使用公私鑰加密來控制的,每位開發人員都會生成自己的公私鑰對。並且,每個開發人員的公鑰都會新增到他們有權訪問的每臺伺服器上的 authorized_keys 檔案中。

看完這篇不在擔心刪庫跑路看完這篇不在擔心刪庫跑路

1. 痛苦的手動更改

到目前為止,這還沒什麼問題。但是,當一名開發人員離職時又會發生什麼事情呢?

在這種情況下,應該從所有伺服器上刪除這位開發人員的公鑰。根據他們有權訪問的伺服器數量,這可能會涉及很多工作。

更糟糕的是,如果這個環節都是手動操作的,那麼操作員很有可能會忘了刪除某些伺服器上的公鑰。也就是說,離職員工的訪問許可權仍然保持啟用狀態。

2. 替代解決方案

有一些商業和開源解決方案可以幫助我們解決這一問題。這裡的基本思想是,你在這類服務上新增並維護一個金鑰和訪問許可權列表,需要刪除某個金鑰時,該金鑰將從所有伺服器中刪除。

這聽起來不錯,但這種方案有一個很大的缺陷:它是潛在的單一故障源。如果某人獲取了對該服務的訪問許可權,那就意味著他可以訪問你的所有伺服器。而且,如果你無法訪問這個服務,在最壞的情況下,甚至會無法訪問所有伺服器。

解決方案:簽名金鑰

當我遇到了這個問題時,我去 HackerNews 上問了問其他人是如何解決它的。

社群提供了一些很棒的建議和見解,而這個問題的最佳解決方案似乎是對金鑰進行簽名,本文會詳細給大家介紹一下。

基本思想

這個方法的基本思想是:你還是要為每位開發人員生成一個公鑰 - 私鑰對。但是,不要把公鑰上載到伺服器上。

而是使用之前生成的,所謂的證照頒發機構(CA)金鑰對公共金鑰進行簽名。這個簽名就是生成了第三個證照檔案,你將它還給開發人員,然後讓他們放在.ssh/資料夾中,和私鑰、公鑰放在一起。

在伺服器上,你只需告訴伺服器你的 CA 的公鑰,伺服器就可以檢測使用者是否具有正確簽名的證照,並且僅允許擁有這種簽名證照的開發人員訪問自己。

優點

簽署證照時,可以定義這次簽署有效的時間。因此,如果你簽署的有效期為 3 個月,隨後開發人員離開了公司,那麼 3 個月後,他們肯定將無法訪問任何伺服器。

現在你會說:好吧,但我不想每 3 個月就對每個人的金鑰籤一次名,這個抱怨很合理。

一種辦法是讓這個流程自動化,例如,你可以構建服務,讓使用者在使用公司的電子郵件和密碼授權時可以自動獲得簽名證照,但這不在本文的討論範圍之內。

另一種簡單的替代方法是,你可以頒發有效期更長的證照。然後,如果有人離開公司,就可以撤消這個證照,也就是使其失效。你可以在伺服器上放置一個無效證照列表,它們將不再接受使用者訪問。例如,可以透過 AWS S3 或其他儲存來存放這個列表,並在每臺伺服器上定期建立一個 cronjob 來完成這一操作。

該怎麼做?

瞭解了原理後,實際上做起來非常簡單。

首先,你要生成一個證照頒發機構的公鑰 - 私鑰對,你應該把這個私鑰放在非常安全的地方:

umask 77 # you want it to be private 
 
mkdir ~/my-ca && cd ~/my-ca 
 
ssh-keygen -C CA -f ca -b 4096 # be sure to use a passphrase and store it securely

然後在你的伺服器上,設定為允許由你的 CA 簽名的所有使用者訪問該伺服器:

將 CA 的公鑰上傳到伺服器上,例如放在/etc/ssh/ca.pub

在/etc/ssh/sshd_config中新增一行,指示伺服器允許訪問由該證照籤名的使用者

TrustedUserCAKeys /etc/ssh/ca.pub # Trust all with a certificate signed by ca.pub

為了使更改生效,你應該重新載入 ssh 服務:sudo service ssh reload。現在,如果一位開發人員生成了他的公鑰 - 私鑰對(例如ssh-keygen -t ecdsa -b 521),他們只需向你傳送他們的公鑰(請注意,你永遠不需要傳送任何私鑰!)。然後,你只需簽署他們的公鑰就能生成他們的證照:

# Inside your ~/my-ca folder, sign their public key (here: id_ecdsa.pub) 
 
ssh-keygen -s ca -I USER_ID -V +12w -z 1 id_ecdsa.pub

各個部分的簡要說明:

-s ca:你要使用 CA 進行簽名
-I USER_ID:你的使用者 ID/ 使用者名稱
-V +12w:證照過期前的有效時間,這裡有效期為 12 周
-z 1:此證照的序列號,以後可用它來讓這個證照無效,序列號應唯一
id_ecdsa.pub:你要簽名的開發人員的公鑰
它將生成證照id_ecdsa-cert.pub,你可以將其傳送給開發人員,然後將其放在〜/.ssh 資料夾中的公鑰 / 私鑰對旁邊。

改進一下

聽起來不錯,但是你還可以做得更好!

你的組織裡可能有很多擁有不同經驗水平、身處不同團隊、承擔不同職責的開發人員,並不是每個人都會訪問相同的伺服器。

這樣的話,讓我們在簽名流程中新增角色吧。

這樣,你可以在伺服器上設定允許哪些角色訪問伺服器,並且在簽名過程中可以指定要簽名的開發人員的角色。

然後,這位開發人員就能訪問與其角色匹配的所有伺服器。

當你新增新的開發人員時,只需生成一個證照即可讓他們獲得授權,訪問所有相關伺服器,而無需在這些伺服器上新增任何內容。

大致上是這樣的:

看完這篇不在擔心刪庫跑路看完這篇不在擔心刪庫跑路

帶有角色的 ssh 證照籤名

下面是在伺服器上配置角色的方式:

首先,建立用於配置訪問許可權的資料夾:sudo mkdir /etc/ssh/auth_principals。在該資料夾中,你可以用允許登入伺服器的使用者名稱建立檔案。例如,要對某些角色授予 root 訪問許可權,請新增檔案/etc/ssh/auth_principals/root。

在/etc/ssh/auth_principals/root內部,你只需列出所有可以用 root 身份登入的角色,每行一個角色:

admin 
 
senior-developer

最後,再在/etc/ssh/sshd_config中新增一行,在伺服器上配置為使用角色:

AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u

為了使更改生效,你應該重新載入 ssh 服務:sudo service ssh reload。
下面是使用角色簽署金鑰的方式(它們已新增到證照中):

ssh-keygen -s ca -I USER_ID -n ROLE1,ROLE2 -V +12w -z 2 id_ecdsa.pub

這裡和之前是一樣的,但帶有-n ROLE1,ROLE2標誌。重要提示:不同角色的逗號之間不能有空格!現在,這位開發人員可以登入 auth_principals 檔案中有ROLE1或ROLE2的任何伺服器,以獲取他們嘗試登入時使用的使用者名稱。

登出金鑰

最後,如果要使證照無效,可以透過使用者名稱或證照的序列號(-z標誌)來實現。建議你在 Excel 電子表格中列出生成的證照列表,或者根據你的具體情況來建立資料庫。

ssh-keygen -k -f revoked-keys -u -s ca list-to-revoke

當你已經有一個revoked-keys列表並想要更新它時(-u標誌)就這樣做。對於初始生成,請拿掉更新標誌。list-to-revoke需要包含使用者名稱(id)或序列號(生成期間為-z標誌),如下所示:

serial: 1 
 
id: test.user

這將撤消對序列號為 1 的證照以及 ID 為test.user的所有證照的訪問許可權。

為了讓伺服器知曉已登出的金鑰,你需要將生成的 / 更新的revoked keys檔案新增到/etc/ssh/revoked-keys,並在/etc/ssh/sshd_config中再次配置:

警告:確保revoked-keys檔案可訪問且可讀,否則你可能無法訪問伺服器

RevokedKeys /etc/ssh/revoked-keys
3. 小結:ssh 金鑰管理的好方法

我認為這種解決方案是最好用的。你可以選擇透過 ssh 基於角色管理對伺服器的訪問許可權。你只需配置一次伺服器(允許哪些角色訪問伺服器)即可。對於新加入的開發人員,你只需要生成一個簽名證照,他們就能立即訪問與他們的角色 / 經驗相匹配的所有相關機器。當他們離開公司時,你也可以透過一種簡單的方式撤銷他們的訪問許可權。

即使發生不幸事故,並且開發人員在未取消訪問許可權的情況下離開,他們的證照也會在一段時間後過期,因此他們也將自動失去訪問許可權。

對小型團隊來說,你可以手動執行這些步驟,因為這些工作做起來非常快;然後隨著你的成長,可以使用基於公司身份驗證詳細資訊的登入服務來自動進行證照籤名。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2741258/,如需轉載,請註明出處,否則將追究法律責任。

相關文章