原文發表于:如何在 linux 服務器上配置基于 SSH 密鑰的身份驗證
SSH 是用于管理與服務器通信的加密協議。當你使用 Linux 服務器時,你的大部分時間有可能都花費在通過 SSH 連接到服務器的終端會話中。
盡管有許多不同的通過 SSH 登錄服務器的方法,但在這篇文章中,我們將重點介紹 SSH 密鑰方式。 SSH 密鑰提供了一種簡單,但極其安全的登錄服務器的方法,這是我們向所有用戶推薦的方法。
SSH 服務器可以使用許多不同的方法來驗證客戶端。其中最基本的是密碼認證,這易于使用,但不是最安全的。
盡管密碼是以安全的方式發送到服務器,但是它們通常不夠復雜或者不夠長,難以抵抗重復的,持久的攻擊者。盡管有其他方法可以給密碼認證額外添加一些安全性(fail2ban 等),但是 SSH 密鑰的方式已經是一個可靠和安全的替代方法。
SSH 密鑰對是兩個加密的安全密碼,可用于給 SSH 服務器驗證客戶端,每個密鑰對由公鑰和私鑰組成。
私鑰由客戶端保留,應該保持絕對隱私。私鑰一旦泄漏,攻擊者就可以直接登錄到相關聯的公鑰配置的服務器,而不需要額外的認證。而作為一個額外的保護措施,私鑰可以用密碼再次加密。
相關的公鑰可以自由共享,沒有任何負面后果。公鑰可以用于加密只有私鑰可以解密的消息。可以根據這個特性進行認證。
公鑰被上傳到你希望能夠使用 SSH 登錄的遠程服務器。該密鑰將添加到你用于登錄的用戶帳戶目錄下 ~/.ssh/authorized_keys 文件中
當客戶端嘗試使用 SSH 密鑰進行身份驗證時,服務器可以測試客戶端是否擁有私鑰。如果客戶端可以證明它擁有私鑰,則生成一個終端會話或執行請求的命令。
基本流程如圖所示:

圖中表示的是筆記本電腦連接到服務器,但它也可以認為一個服務器連接到另一個服務器。
要為服務器配置基于 SSH 密鑰的身份驗證,第一步是在本地計算機上生成 SSH 密鑰對。
為此,我們可以使用 ssh-keygen 命令,它就包含在標準的 OpenSSH 工具套件中。默認情況下,它會創建一個 2048 位的 RSA 密鑰對,大多數情況這就足夠了。
在本地計算機上,通過輸入以下命令生成 SSH 密鑰對:
ssh-keygenGenerating public/PRivate rsa key pair.Enter file in which to save the key (/home/username/.ssh/id_rsa):這是提示你輸入密鑰對要放置的位置。默認情況下,密鑰會存儲在 ~/.ssh 目錄下,id_rsa 是私鑰,公鑰是 id_rsa.pub。
通常情況,使用默認位置即可,這樣可以讓 SSH 客戶端在嘗試進行身份驗證時自動查找 SSH 密鑰。如果不想使用默認路徑,可以現在輸入。
如果你先前已經生成過 SSH 密鑰對,可能會看到類似如下的提示:
/home/username/.ssh/id_rsa already exists.Overwrite (y/n)?如果你選擇覆蓋,你就無法使用之前的密鑰進行身份驗證。所以選擇 “y” 時要非常小心,因為這是一個不可逆轉的過程。
Created directory '/home/username/.ssh'.Enter passphrase (empty for no passphrase):Enter same passphrase again: 接下來,系統會提示你輸入密鑰的密碼,這可用于加密硬盤上的私鑰文件。
這時候你可能想知道如果你還是需要輸入密碼,那 SSH 密鑰到底有什么優勢。下面列出了一些:
SSH 私鑰(可以密碼保護的部分)永遠不會暴露在網絡上。密碼僅用于解密本地機器上的密鑰。這意味著無法針對私鑰密碼使用基于網絡的暴力破解。
私鑰保存在受限目錄中,SSH 客戶端不會識別未保存在受限目錄中的私鑰。密鑰本身也必須具有受限權限(只能所有者讀寫),這表示系統上的其他用戶無法窺探。
任何希望破解 SSH 私鑰密碼的攻擊者都必須已經可以訪問系統,這意味著他們已經可以訪問您的用戶帳戶或 root 帳戶。如果您處于這種狀況下,密碼可以防止攻擊者立即登錄到其他服務器,這樣你就有時間創建和部署一個新的 SSH 密鑰對,并移除受攻擊的密鑰的訪問。
因為私鑰永遠不會暴露在網絡中并且通過文件權限來保護,因此除了你(和 root 用戶)之外的任何人都不能夠訪問此文件。私鑰密碼則在這些條件都被破壞的情況下作為額外的保護。
私鑰密碼是可選的,如果設置了,你就必須在每次使用此密鑰時提供(除非您使用了存儲解密密鑰的 SSH 代理軟件)。我們建議使用私鑰密碼,但如果您不想設置,只需按確認鍵跳過此提示。
Your identification has been saved in /home/username/.ssh/id_rsa.Your public key has been saved in /home/username/.ssh/id_rsa.pub.The key fingerprint is:a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_hostThe key's randomart image is:+--[ RSA 2048]----+| ..o || E o= . || o. o || .. || ..S || o o. || =o.+. ||. =++.. ||o=++. |+-----------------+您現在有了一個公鑰和一個私鑰,您可以使用它來進行身份驗證。下一步則是將公鑰放到服務器上,以便可以使用 SSH 密鑰身份驗證登錄。
如何把公鑰拷貝到服務器上
如果你已經有一個可用服務器,你可以上傳你的公鑰,并使用它來驗證。
你可以使用的方法取決于你可用的工具和當前配置。以下方法都會得到相同的結果,第一個是最簡單,最自動化的方法,如果你無法使用前面的方法,那么之后的方法都需要額外的手動步驟。
使用 SSH-Copy-ID 復制公鑰
將公鑰復制到服務器上的最簡單方法是使用 ssh-copy-id 命令。由于它足夠簡單,如果可用,建議使用此方法。
ssh-copy-id 命令包含在許多發行版本的 OpenSSH 軟件包中。要讓此方法起效,你必須已經可以通過 SSH 訪問你的服務器。
要使用該命令,你只需要指定要連接到的遠程主機和你有 SSH 訪問權限的用戶帳戶。你的 SSH 公鑰會被復制到該帳戶目錄下。
語法如下:
ssh-copy-id username@remote_host您可能會看到這樣的消息:
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes這只是表示你的本地計算機不能識別遠程主機,它只會在你第一次連接到新主機時出現。鍵入 “yes”,然后按確認鍵繼續。
接下來,程序將掃描你本地帳戶下的 id_rsa.pub 文件。如果找到,它會提示輸入遠程用戶帳戶的密碼:
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysusername@111.111.11.111's passWord:輸入密碼(出于安全考慮,你的輸入內容不會顯示出來),然后按確認鍵。該程序將使用你提供的密碼連接到遠程主機上的帳戶,然后把 ~/.ssh/id_rsa.pub 的內容,加入到遠程帳戶的 ~/.ssh/authorized_keys 文件中。
你會看到如下的輸出:
Number of key(s) added: 1Now try logging into the machine, with: "ssh 'username@111.111.11.111'"and check to make sure that only the key(s) you wanted were added.此時,你的 id_rsa.pub 內容已上傳到遠程帳戶。
使用 SSH 復制公鑰
如果你不能使用 ssh-copy-id 方法,但是你可以用密碼訪問服務器上的帳戶,那可以使用傳統的 SSH 方法上傳密鑰。
我們可以在本地輸出 SSH 公鑰的內容,然后通過 SSH 連接到遠程服務器來處理。同時,確保我們正在使用的賬戶下有 ~/.ssh 目錄,然后將本地的 SSH 公鑰通過管道輸出到此目錄中名為 authorized_keys 的文件中。
我們會使用 >> 符號來附加內容,而不是覆蓋。這樣,我們可以添加公鑰而不破壞以前添加的公鑰。
完整命令如下所示:
cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"您可能會看到這樣的消息:
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes這只是說明你的本地計算機不能識別遠程主機,它只會在你第一次連接到新主機時出現。鍵入 “yes”,然后按確認鍵繼續。
之后,系統會提示你輸入嘗試連接到的帳戶的密碼:
username@111.111.11.111's password:輸入密碼后,你的 id_rsa.pub 的內容就被復制到遠程用戶帳戶的 authorized_keys 文件的末尾。
手動復制公鑰
如果你不能通過基于密碼的 SSH 訪問服務器,那你必須手動完成上述操作。
你本地 ~/.ssh/id_rsa.pub 的內容必須添加到服務器上的 ~/.ssh/authorized_keys 文件中。
顯示你本地的 ~/.ssh/id_rsa.pub 內容:
cat ~/.ssh/id_rsa.pub你會看到類似下面的密鑰內容:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCQQl6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVipSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywpsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test然后使用你任何可用的方法訪問遠程主機。
一旦在遠程服務器上訪問了你的帳戶后,你首先要確保已經創建了 ~/.ssh 目錄。如果還沒有,可以用如下命令創建:
mkdir -p ~/.ssh現在,你可以在此目錄下創建或修改 authorized_keys 文件。您可以把 id_rsa.pub 的內容添加到 authorized_keys 文件的末尾,命令如下:
echo public_key_string >> ~/.ssh/authorized_keys在上面的命令中,使用之前顯示出的公鑰內容替換 public_key_string。合法的公鑰應該以 ssh-rsa AAAA 開頭。
如果這步成功了,你可以退出然后嘗試使用不需要密碼的 SSH 登錄服務器。
基于SSH密鑰對您的服務器進行身份驗證
如果你已經完成了上述其中一個過程,你應該能夠無需密碼就登錄到遠程主機。
基本過程是一樣的:
ssh username@remote_host如果這是你第一次連接到這個主機(前面一段的最后一個方法),你可能會看到這樣的提示:
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.Are you sure you want to continue connecting (yes/no)? yes這只是表示你的本地計算機不能識別遠程主機,它只會在你第一次連接到新主機時出現。鍵入 “yes”,然后按確認鍵繼續。
如果你沒有為你的私鑰設置密碼,你就能立即登錄。如果你在創建密鑰時為私鑰設置了密碼,那現在需要輸入私鑰密碼。這時候,就會創建新的終端會話。
成功之后,繼續看如何禁用服務器密碼驗證。
在服務器上禁用密碼驗證
如果你可以直接使用 SSH 而不是賬戶密碼登錄服務器,這表示你已成功配置了基于 SSH 密鑰的身份驗證。但是,這時基于密碼的身份驗證機制依然可用,這表示你的服務器仍然暴露在暴力攻擊之下。
在完成本節中的步驟之前,請確保你的服務器上的 root 帳戶或者最好是具有 sudo 訪問權的的帳戶配置了基于 SSH 密鑰的身份驗證。此步驟將禁止基于密碼的登錄,因此確保你依然能夠獲得管理訪問權限是非常重要的。
一旦上述條件都滿足了,以 root 身份或使用具有 sudo 權限的帳戶使用 SSH 密鑰登錄到遠程服務器,打開 SSH 后臺程序的配置文件:
sudo nano /etc/ssh/sshd_config在文件中,搜索一個名為 PasswordAuthentication 的指令,它可能是被注釋掉的,取消注釋并將值設置為 “no”。這樣就可以禁止使用帳戶密碼通過 SSH 登錄:
PasswordAuthentication no完成以后保存并關閉文件。要讓剛才的修改起效,你必須重新啟動服務。
在 Ubuntu 或者 Debian 機器上,你可以用如下命令:
sudo service ssh restart在 CentOS/Fedora 機器上,后臺進程叫 sshd:
sudo service sshd restart完成這一步之后,你就成功將 SSH 后臺進程切換為僅響應 SSH 密鑰驗證。
總結
你現在應該已經在服務器上配置并運行了基于 SSH 密鑰的身份驗證,所以你可以直接登錄服務器而不需要提供帳戶密碼了。
新聞熱點
疑難解答