本文講述了如何通過 Linux中國 所開發(fā)的微信小程序“運維密碼”實現(xiàn)在 Linux 系統(tǒng)上 OpenSSH 雙因子認證,從而對 SSH 進行安全加固。
近來很多知名企業(yè)都出現(xiàn)了密碼泄露,通過單一的密碼對敏感和重要信息進行保護已經(jīng)面臨越來越多的挑戰(zhàn),因此業(yè)內(nèi)對多重認證的呼聲也越來越高,而其中的雙因子認證得到了業(yè)界的普遍認可。
雙因子認證Two-factor authentication(即 2FA),是一種通過組合兩種不同的驗證方式進行用戶身份驗證的機制。
在這種多重認證的系統(tǒng)中,用戶需要通過兩種不同的認證程序:
在 SSH 服務器端安裝 Google 身份驗證器服務器端組件,這樣,在使用密碼或密鑰登錄 SSH 服務器時,同時通過與 Google 身份驗證器相匹配的客戶端所提供的驗證信息來確認登錄者的身份和權限。這里的客戶端可以使用Google 身份驗證器Google Authenticator應用,也可以使用我們開發(fā)的、采用同一個 RFC 規(guī)范的“運維密碼”微信小程序。
Google 身份驗證器所采用的算法規(guī)范基于 TOTP RFC 草案。
(題外話,RSA 硬件令牌,也是采用了類似的機制,只不過客戶端是硬件的;而最近 Apple 公司的一些服務所需要的雙因子認證也是一樣的,但是其用于呈現(xiàn)驗證信息的是手機或平板上的 iOS 內(nèi)部組件,非獨立應用。)
為了鼓勵廣泛采用雙因子認證的方式,Google 公司發(fā)布了Google 身份驗證器Google Authenticator,這是一款開源的、可基于開放規(guī)則(如 HMAP/ 基于時間)生成一次性密碼的軟件。它是一款跨平臺軟件,可運行在 Linux、Android、iOS 上。Google 公司同時也支持插件式鑒別模塊pluggable authentication module PAM ,使其能和其它適用于 PAM 進行驗證的工具(如 OpenSSH)協(xié)同工作。
Google 身份驗證器分為兩個部分,分別是服務器端組件和客戶端應用,都稱之為“Google 身份驗證器”,這里,我們?yōu)榱顺吻迤鹨姡瑫谡f明時指明。
Google 公司所開發(fā)的身份驗證器以簡潔著稱,但也因此缺乏一些必要的特性,比如備份功能——這使得使用該身份驗證器的人時時處于手機丟失的恐慌之中。(雖然 Google 提供的服務器端和自身的服務也提供了緊急驗證碼,以用于這種情況下的自救,但是很多采用 Google 身份驗證器的服務并不支持和提供緊急驗證碼)
作為一家緊密關注于運維安全、積極倡導信息安全的技術社區(qū),Linux 中國 久已有開發(fā)一個新的替代品的想法。恰逢微信推出小程序平臺,我們感覺到這正是一個良機,可以充分利用到微信和小程序的便利之處,又適合小程序的使用情境。因此,由 Linux 中國旗下的 LCTT 技術組的白宦成同學獨立開發(fā)了一款旨在移動互聯(lián)網(wǎng)場景中提供更好的多因子認證體驗的小程序:運維密碼。
順便說一句,在產(chǎn)品初步成熟之后,我們已經(jīng)將該小程序開源給社區(qū),代碼托管于 GitHub:LCTT/WeApp-Password ,希望更多的人能夠受益和共同完善它,有什么功能需求、錯誤反饋請到 GitHub 上提出 issue,也歡迎發(fā)送拉取請求給我們。
此外,大家在使用過程中,發(fā)現(xiàn)什么問題或需要幫助,也可以加入微信體驗群:
或添加開發(fā)者的微信號:ixiqin_com ,添加備注:“運維密碼”,直接與開發(fā)者溝通。
言歸正傳,我們來看看如何使用“運維密碼”來為你的 SSH 服務提供雙因子認證支持。
首先我們需要一些準備工作:
第一步需要在運行著 OpenSSH 服務的 Linux 主機上安裝 Google 身份驗證器服務器端組件。按照如下步驟安裝 Google 身份驗證器及其 PAM 模塊。
如果你不想自己構建 Google 身份驗證器服務器端組件,在幾個主流 Linux 發(fā)行版上有已經(jīng)編譯好的安裝包。安裝包里面包含 Google 身份驗證器服務器端組件的二進制程序和 PAM 模塊。
在 Ubuntu 上安裝 Google 身份驗證器服務器端組件:
sudo apt-get install libpam-google-authenticator
在 Fedora 上安裝 Google 身份驗證器服務器端組件:
sudo dnf install google-authenticator
在 CentOS 上安裝 Google 身份驗證器服務器端組件,需要首先啟用 EPEL 軟件庫,然后運行如下命令:
sudo yum install google-authenticator
首先,安裝構建 Google 身份驗證器所需的軟件包。
在 Debian、 Ubuntu 或 Linux Mint 上:
sudo apt-get install wget make gcc libpam0g-dev
在 CentOS、 Fedora 或 RHEL 上:
sudo yum install wget make gcc pam-devel
然后下載 Google 身份驗證器服務器端組件的源代碼:
git clone https://github.com/google/google-authenticator.git
編譯安裝 Google 身份驗證器服務器端組件:
cd google-authenticator/libpam./bootstrap.sh./configuremake
如果構建成功,你會在目錄中看到 pam_google_authenticator.so 和 google-authenticator 兩個二進制文件。
最后,將 Google 身份驗證器的服務器端組件安裝到合適位置。其默認會安裝到 /usr/local/lib/security 下,根據(jù)你的系統(tǒng)不同,你可能需要將其符號鏈接到 pam 庫的位置(比如 CentOS 7 會在 /usr/lib64/security)。如下圖所示:
sudo make install
至此,Google 身份驗證器服務器端組件安裝完成。
完成 Google 身份驗證器服務器端組件的安裝我們僅僅完成了第一步,接著需要對 Google 身份驗證器服務器端組件、“運維密碼”、OpenSSH 進行配置才能達到我們預期的效果。
使用以下命令生成驗證密鑰:
./google-authenticator
生成驗證密鑰的時候,會再次確認信息。
Do you want authentication tokens to be time-based (y/n)
意思是:你想要生成基于時間生成驗證碼嗎?這里需要需要輸入 y。
輸入 y之后你將看到一個代表著該“場景”密鑰的二維碼和密鑰字符串,它使用如下二維碼圖形格式表示我們數(shù)字形態(tài)的密鑰(這里也提供了一個用于在瀏覽器中再次顯示該二維碼的 URL,但是需要翻墻)。接著我們要用到它在“運維密碼”上完成配置。
在二維碼和密鑰字符串后面,接著顯示了一個當前的校驗碼和幾個緊急密鑰。緊急密鑰你可以另行保存的一個安全的地方,以防你在無法使用 Google 身份驗證器應用或“運維密碼”時使用(緊急密鑰是 8 位的,不同于普通的 6 位密鑰,也是一次性使用的)。
保存 Google 服務器端組件的配置文件,Google 身份驗證器雖然運行了,但是相關設置還沒有保存,接下來會提示保存:
Do you want me to update your "/root/.google_authenticator" file? (y/n)
意思是:你想將配置文件更新到 /root/.google_authenticator 保存嗎?
輸入 y 回車。
禁止同一令牌多次登錄
Do you want to disallow multiple uses of the same authenticationtoken? This restricts you to one login about every 30s, but it increasesyour chances to notice or even prevent man-in-the-middle attacks (y/n)
意思是:你是否要禁用同一密鑰多次登錄,這將限制你每 30 秒只能使用該密鑰登錄一次,但這能夠讓你可以更多地被提醒受到了中間人攻擊,甚至能夠防止這種攻擊。
輸入 y 回車。
時間容錯設置
By default, tokens are good for 30 seconds. In order to compensate forpossible time-skew between the client and the server, we allow an extratoken before and after the current time. If you experience problems withpoor time synchronization, you can increase the window from its defaultsize of +-1min (window size of 3) to about +-4min (window size of17 acceptable tokens).Do you want to do so? (y/n)
意思是:默認情況下,密鑰在 30 秒內(nèi)有效,為了防止由于客戶端與服務器時間偏移(時間相差太大)導致認證失敗,google 身份驗證器設計了時間容錯措施。可以讓你使用與當前時間偏移 1 到 4 分鐘的密鑰。
這個可根據(jù)實際情況進行配置,一般一分鐘就足夠了。
輸入 y回車。
暴力破解防護
If the computer that you are logging into isn't hardened against brute-forcelogin attempts, you can enable rate-limiting for the authentication module.By default, this limits attackers to no more than 3 login attempts every 30s.Do you want to enable rate-limiting (y/n)
意思是:為了避免暴力破解,可以啟用速率限制,默認情況下,每 30 秒只能嘗試 3 次。
輸入 y回車。
配置完成
配置完成后會在home目錄下生成一個權限為 400 的隱藏文件,如下圖所示:
打開微信小程序
打開微信,依次點擊“發(fā)現(xiàn)”,“小程序”:
輸入“運維密碼”并搜索:
點擊“運維密碼”進入應用,然后點擊右下角二維碼圖標:
掃一掃配置 google-authenticator 時所生成的二維碼,然后會識別出該場景信息,你可以根據(jù)需要修改場景信息,點擊確定添加場景:
添加完成:
這樣 Google 身份驗證器就和“運維密碼”匹配上了。下面我們要使 SSH 服務可以支持該驗證。
添加認證模塊
使用如下命令在 /etc/pam.d/sshd 文件添加認證模塊:
echo "auth required pam_google_authenticator.so" >>/etc/pam.d/sshd
配置挑戰(zhàn)式密碼認證:
sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
重啟 sshd 服務:
systemctl restart sshd.service
切記,如果你是遠程登錄到服務器上配置,切勿退出當前的 SSH 會話,而應該另外開一個會話去測試 SSH 登錄。重啟不會中斷當前的 SSH 會話。
以上配置完成基本上就搞定了,下面我們進行測試。
另外開一個終端窗口進行連接,不要關閉當前的 SSH 連接。
輸入命令登錄主機:
ssh root@10.112.2.3
首先輸入服務器的密碼,接著會讓輸入“運維密碼”生成的 6 位數(shù)字密鑰。
如下圖:
我們可以看到,在登錄的時候,需要配合“運維密碼”才能登錄服務器。
如果使用公鑰登錄呢?以上配置是不是也是需要配合“運維密碼”才能登錄的,我們進行驗證一下:
首先,我們將本機的公鑰復制到遠程機器的 authorized_keys 文件中。
ssh-copy-id root@10.112.2.3
登錄測試:
我們可以看到,不需要輸入任何密碼和一次性密鑰,直接登錄到了系統(tǒng)。
針對上面公鑰登錄的測試,如果認為還不是很安全,我們可以設定如下登錄場景:公鑰 + 密碼 + 運維密碼,我們需要如何做呢?
配置 SSH 公鑰雙因子
修改 /etc/ssh/sshd_config 配置文件:
echo "AuthenticationMethods publickey,keyboard-interactive:pam" >>/etc/ssh/sshd_config
重啟 SSH 服務:
systemctl restart sshd.service
登錄測試(同樣,請新開窗口):
ssh root@10.112.2.3
可以看到,登錄的時候是需要驗證公鑰、密碼,及輸入“運維密碼”生成的密鑰才能登錄到系統(tǒng)。
沒有密鑰的情況下嘗試登錄測試,如下圖:
至此,本文結束,更多的使用細節(jié)可以參照小程序內(nèi)的幫助,或此文。
如有錯誤及不足歡迎指正。也歡迎大家加入到這個小程序的開發(fā)當中,乃至將這個小程序應用到你的應用場景中。