您的位置:首頁>科技>正文

SSH安全加固篇:通過“運維密碼”小程式實現SSH雙因數認證

本文導航

-背景 …… 01%

-什麼是雙因數認證 …… 03%

-SSH 雙因數認證實現思路 …… 06%

-關於Google 身份驗證器 …… 12%

-關於運維密碼 …… 17%

-如何開始 …… 28%

-在 Linux 系統中安裝 Google 身份驗證器伺服器端元件 …… 30%

-用安裝包安裝 Google 身份驗證器伺服器端組件 …… 31%

-編譯安裝 Google 身份驗證器伺服器端元件 …… 37%

-配置 Google 身份驗證器伺服器端元件及“運維密碼”小程式 …… 45%

-配置 google-authenticator 及生成驗證金鑰 …… 47%

-配置運維密碼 …… 71%

-配置 SSH 服務 …… 78%

-測試登錄 …… 82%

-密碼登錄測試 …… 83%

-公開金鑰登錄測試 …… 87%

-結合運維密碼配置增強型SSH安全選項 …… 91%

-總結 …… 98%

作者: netb2c

背景

近來很多知名企業都出現了密碼洩露, 通過單一的密碼對敏感和重要資訊進行保護已經面臨越來越多的挑戰, 因此業內對多重認證的呼聲也越來越高, 而其中的雙因數認證得到了業界的普遍認可。

什麼是雙因數認證

雙因數認證Two-factor authentication(即 2FA), 是一種通過組合兩種不同的驗證方式進行使用者身份驗證的機制。

在這種多重認證的系統中,

使用者需要通過兩種不同的認證程式:

提供他們知道的資訊(如用戶名/密碼)

再借助其他工具提供使用者所不知道的資訊(如用手機生成的一次性密碼)

SSH 雙因數認證實現思路

Google 身份驗證器所採用的演算法規範基於 TOTP RFC 草案[3]。

(題外話, RSA 硬體權杖, 也是採用了類似的機制, 只不過用戶端是硬體的;而最近 Apple 公司的一些服務所需要的雙因數認證也是一樣的, 但是其用於呈現驗證資訊的是手機或平板上的 iOS 內部元件, 非獨立應用。 )

關於Google 身份驗證器

為了鼓勵廣泛採用雙因數認證的方式, Google 公司發佈了Google 身份驗證器Google Authenticator[4], 這是一款開源的、可基於開放規則(如 HMAP/ 基於時間)生成一次性密碼的軟體。 它是一款跨平臺軟體, 可運行在 Linux、Android、iOS 上。 Google 公司同時也支援外掛程式式鑒別模組pluggable authentication module PAM ,

使其能和其它適用於 PAM 進行驗證的工具(如 OpenSSH)協同工作。

Google 身份驗證器分為兩個部分, 分別是伺服器端元件和用戶端應用, 都稱之為“Google 身份驗證器”, 這裡, 我們為了澄清起見, 會在說明時指明。

關於運維密碼

Google 公司所開發的身份驗證器以簡潔著稱, 但也因此缺乏一些必要的特性, 比如備份功能——這使得使用該身份驗證器的人時時處於手機丟失的恐慌之中。 (雖然 Google 提供的伺服器端和自身的服務也提供了緊急驗證碼, 以用於這種情況下的自救, 但是很多採用 Google 身份驗證器的服務並不支援和提供緊急驗證碼)

順便說一句, 在產品初步成熟之後, 我們已經將該小程式開源給社區, 代碼託管於 GitHub:https://github.com/LCTT/WeApp-Password , 希望更多的人能夠受益和共同完善它,

有什麼功能需求、錯誤回饋請到 GitHub 上提出 issue, 也歡迎發送拉取請求給我們。

言歸正傳, 我們來看看如何使用“運維密碼”來為你的 SSH 服務提供雙因數認證支援。

如何開始

首先我們需要一些準備工作:

一台運行著 OpenSSH 服務(版本大於 6.2)的 Linux 主機

一台支援 SSH 登錄的終端

在 Linux 系統中安裝 Google 身份驗證器伺服器端元件

第一步需要在運行著 OpenSSH 服務的 Linux 主機上安裝 Google 身份驗證器伺服器端組件。 按照如下步驟安裝 Google 身份驗證器及其 PAM 模組。

用安裝包安裝 Google 身份驗證器伺服器端元件

如果你不想自己構建 Google 身份驗證器伺服器端元件, 在幾個主流 Linux 發行版本上有已經編譯好的安裝包。 安裝包裡面包含 Google 身份驗證器伺服器端元件的二進位程式和 PAM 模組。

在 Ubuntu 上安裝 Google 身份驗證器伺服器端組件:

sudo apt-get install libpam-google-authenticator

在 Fedora 上安裝 Google 身份驗證器伺服器端組件:

sudo dnf install google-authenticator

在 CentOS 上安裝 Google 身份驗證器伺服器端元件, 需要首先啟用 EPEL 軟體庫[6], 然後運行如下命令:

sudo yum install google-authenticator編譯安裝 Google 身份驗證器伺服器端組件

首先, 安裝構建 Google 身份驗證器所需的套裝軟體。

在 Debian、 Ubuntu 或 Linux Mint 上:

sudo apt-get install wget make gcc libpam0g-dev

在 CentOS、 Fedora 或 RHEL 上:

sudo yum install wget make gcc pam-develgit clone https://github.com/google/google-authenticator.git

編譯安裝 Google 身份驗證器伺服器端組件:

cd google-authenticator/libpam

./bootstrap.sh

./configure

make

如果構建成功, 你會在目錄中看到 pam_google_authenticator.so 和 google-authenticator 兩個二進位檔案。

最後, 將 Google 身份驗證器的伺服器端組件安裝到合適位置。 其預設會安裝到 /usr/local/lib/security 下, 根據你的系統不同, 你可能需要將其符號連結到 pam 庫的位置(比如 CentOS 7 會在 /usr/lib64/security)。 如下圖所示:

sudo make install

至此, Google 身份驗證器伺服器端組件安裝完成。

配置 Google 身份驗證器伺服器端元件及“運維密碼”小程式

完成 Google 身份驗證器伺服器端元件的安裝我們僅僅完成了第一步, 接著需要對 Google 身份驗證器伺服器端元件、“運維密碼”、OpenSSH 進行配置才能達到我們預期的效果。

配置 google-authenticator 及生成驗證金鑰

使用以下命令生成驗證金鑰:

./google-authenticator

生成驗證金鑰的時候,會再次確認資訊。

Do you want authentication tokens to be time-based (y/n)

意思是:你想要生成基於時間生成驗證碼嗎?這裡需要需要輸入 y。

輸入 y之後你將看到一個代表著該“場景”金鑰的二維碼和金鑰字串,它使用如下二維碼圖形格式表示我們數位形態的金鑰(這裡也提供了一個用於在流覽器中再次顯示該二維碼的 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 authentication

token? This restricts you to one login about every 30s, but it increases

your 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 for

possible time-skew between the client and the server, we allow an extra

token before and after the current time. If you experience problems with

poor time synchronization, you can increase the window from its default

size of +-1min (window size of 3) to about +-4min (window size of

17 acceptable tokens).

Do you want to do so? (y/n)

意思是:預設情況下,金鑰在 30 秒內有效,為了防止由於用戶端與伺服器時間偏移(時間相差太大)導致認證失敗,google 身份驗證器設計了時間容錯措施。可以讓你使用與當前時間偏移 1 到 4 分鐘的金鑰。

這個可根據實際情況進行配置,一般一分鐘就足夠了。

輸入 y回車。

暴力破解防護

If the computer that you are logging into isn't hardened against brute-force

login 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 的隱藏檔,如下圖所示:

配置運維密碼

輸入“運維密碼”並搜索:

點擊“運維密碼”進入應用,然後點擊右下角二維碼圖示:

掃一掃配置 google-authenticator 時所生成的二維碼,然後會識別出該場景資訊,你可以根據需要修改場景資訊,點擊確定添加場景:

添加完成:

這樣 Google 身份驗證器就和“運維密碼”匹配上了。下面我們要使 SSH 服務可以支援該驗證。

配置 SSH 服務

添加認證模組

使用如下命令在 /etc/pam.d/sshd 檔添加認證模組:

echo "auth required pam_google_authenticator.so" >>/etc/pam.d/sshd

配置挑戰式密碼認證:

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 位元數字金鑰。

如下圖:

我們可以看到,在登錄的時候,需要配合“運維密碼”才能登錄伺服器。

公開金鑰登錄測試

如果使用公開金鑰登錄呢?以上配置是不是也是需要配合“運維密碼”才能登錄的,我們進行驗證一下:

首先,我們將本機的公開金鑰複製到遠端機器的 authorized_keys 檔中。

ssh-copy-id root@10.112.2.3

登錄測試:

我們可以看到,不需要輸入任何密碼和一次性金鑰,直接登錄到了系統。

結合運維密碼配置增強型SSH安全選項

針對上面公開金鑰登錄的測試,如果認為還不是很安全,我們可以設定如下登錄場景:公開金鑰 + 密碼 + 運維密碼,我們需要如何做呢?

配置 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

可以看到,登錄的時候是需要驗證公開金鑰、密碼,及輸入“運維密碼”生成的金鑰才能登錄到系統。

沒有金鑰的情況下嘗試登錄測試,如下圖:

總結

至此,本文結束,更多的使用細節可以參照小程式內的説明,或此文[7]。

如有錯誤及不足歡迎指正。也歡迎大家加入到這個小程式的開發當中,乃至將這個小程式應用到你的應用場景中。

[1]: 運維密碼 - https://linux.cn/article-8317-1.html

[2]: Google 身份驗證器 - https://github.com/google/google-authenticator

[3]: TOTP RFC 草案 - http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.html

[4]: Google 身份驗證器 - https://github.com/google/google-authenticator

[5]: 運維密碼 - https://linux.cn/article-8317-1.html

[6]: 啟用 EPEL 軟體庫 - https://linux.cn/article-2324-1.html

[7]: 此文 - https://linux.cn/article-8317-1.html

接著需要對 Google 身份驗證器伺服器端元件、“運維密碼”、OpenSSH 進行配置才能達到我們預期的效果。

配置 google-authenticator 及生成驗證金鑰

使用以下命令生成驗證金鑰:

./google-authenticator

生成驗證金鑰的時候,會再次確認資訊。

Do you want authentication tokens to be time-based (y/n)

意思是:你想要生成基於時間生成驗證碼嗎?這裡需要需要輸入 y。

輸入 y之後你將看到一個代表著該“場景”金鑰的二維碼和金鑰字串,它使用如下二維碼圖形格式表示我們數位形態的金鑰(這裡也提供了一個用於在流覽器中再次顯示該二維碼的 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 authentication

token? This restricts you to one login about every 30s, but it increases

your 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 for

possible time-skew between the client and the server, we allow an extra

token before and after the current time. If you experience problems with

poor time synchronization, you can increase the window from its default

size of +-1min (window size of 3) to about +-4min (window size of

17 acceptable tokens).

Do you want to do so? (y/n)

意思是:預設情況下,金鑰在 30 秒內有效,為了防止由於用戶端與伺服器時間偏移(時間相差太大)導致認證失敗,google 身份驗證器設計了時間容錯措施。可以讓你使用與當前時間偏移 1 到 4 分鐘的金鑰。

這個可根據實際情況進行配置,一般一分鐘就足夠了。

輸入 y回車。

暴力破解防護

If the computer that you are logging into isn't hardened against brute-force

login 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 的隱藏檔,如下圖所示:

配置運維密碼

輸入“運維密碼”並搜索:

點擊“運維密碼”進入應用,然後點擊右下角二維碼圖示:

掃一掃配置 google-authenticator 時所生成的二維碼,然後會識別出該場景資訊,你可以根據需要修改場景資訊,點擊確定添加場景:

添加完成:

這樣 Google 身份驗證器就和“運維密碼”匹配上了。下面我們要使 SSH 服務可以支援該驗證。

配置 SSH 服務

添加認證模組

使用如下命令在 /etc/pam.d/sshd 檔添加認證模組:

echo "auth required pam_google_authenticator.so" >>/etc/pam.d/sshd

配置挑戰式密碼認證:

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 位元數字金鑰。

如下圖:

我們可以看到,在登錄的時候,需要配合“運維密碼”才能登錄伺服器。

公開金鑰登錄測試

如果使用公開金鑰登錄呢?以上配置是不是也是需要配合“運維密碼”才能登錄的,我們進行驗證一下:

首先,我們將本機的公開金鑰複製到遠端機器的 authorized_keys 檔中。

ssh-copy-id root@10.112.2.3

登錄測試:

我們可以看到,不需要輸入任何密碼和一次性金鑰,直接登錄到了系統。

結合運維密碼配置增強型SSH安全選項

針對上面公開金鑰登錄的測試,如果認為還不是很安全,我們可以設定如下登錄場景:公開金鑰 + 密碼 + 運維密碼,我們需要如何做呢?

配置 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

可以看到,登錄的時候是需要驗證公開金鑰、密碼,及輸入“運維密碼”生成的金鑰才能登錄到系統。

沒有金鑰的情況下嘗試登錄測試,如下圖:

總結

至此,本文結束,更多的使用細節可以參照小程式內的説明,或此文[7]。

如有錯誤及不足歡迎指正。也歡迎大家加入到這個小程式的開發當中,乃至將這個小程式應用到你的應用場景中。

[1]: 運維密碼 - https://linux.cn/article-8317-1.html

[2]: Google 身份驗證器 - https://github.com/google/google-authenticator

[3]: TOTP RFC 草案 - http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.html

[4]: Google 身份驗證器 - https://github.com/google/google-authenticator

[5]: 運維密碼 - https://linux.cn/article-8317-1.html

[6]: 啟用 EPEL 軟體庫 - https://linux.cn/article-2324-1.html

[7]: 此文 - https://linux.cn/article-8317-1.html

Next Article
喜欢就按个赞吧!!!
点击关闭提示