ssh 免密登錄踩坑及解決

       最近發現 ssh 直接可以免密登錄遠程服務器,感覺挺有趣的,於是想試試順便了解下原理。首先便是百度下 ssh 的概念及登錄方式及原理,接着就是自己實踐了,一開始老是有問題,後面思考可能的原因再嘗試便慢慢解決了,結果還是不錯的。

       簡單說下  ssh 的概念吧。主要了解以下幾點就差不多了。

  1. 概念:ssh 全稱是 Secure Sshell,即安全外殼協議,由 IETF 的網絡小組(Network Working Group)所制定。
  2. 作用:爲建立在應用層基礎上的安全協議。SSH 是較可靠,專爲遠程登錄會話和其他網絡服務提供安全性的協議。利用 SSH 協議可以有效防止遠程管理過程中的信息泄露問題。ftp、pop和telnet在本質上都是不安全的,因爲它們在網絡上用明文傳送口令和數據,別有用心的人非常容易就可以截獲這些口令和數據。而且,這些服務程序的安全驗證方式也是有其弱點的, 就是很容易受到“中間人”(man-in-the-middle)這種方式的攻擊。通過使用SSH,你可以把所有傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了,而且也能夠防止DNS欺騙和IP欺騙。使用SSH,還有一個額外的好處就是傳輸的數據是經過壓縮的,所以可以加快傳輸的速度。SSH有很多功能,它既可以代替Telnet,又可以爲FTPPoP、甚至爲PPP提供一個安全的"通道"。
  3. 適應平臺:幾乎所有UNIX平臺—包括 HP-UXLinuxAIXSolarisDigital UNIXIrix,以及其他平臺,都可運行SSH。
    1. 從客戶端來看,SSH 提供兩種級別的登錄安全驗證。
      1.基於口令的安全驗證,意思就是通過賬號和密碼進行登錄到遠程主機。所有傳輸的數據都會被加密,但是不能保證你正在連接的服務器就是你想連接的服務器。可能會有別的服務器在冒充真正的服務器,也就是受到“中間人”這種方式的攻擊。
      2.基於密匙的安全驗證,需要在發起連接的機器(客戶機)建立密鑰對,即公鑰以及匹配的密鑰,將公鑰放置到要連接的目標服務器的用戶的家目錄下的 .ssh 目錄下,連接時向服務器發出請求,請求用你的密匙進行安全驗證。服務器收到請求,先在該服務器上你要連接的用戶的主目錄下尋找對應的公用密匙,然後把它和你發送過來的公用密匙進行比較。如果兩個密匙一致,服務器就用公用密匙加密“質詢”(challenge)並把它發送給客戶端軟件。客戶端軟件收到“質詢”之後就可以用你的私鑰解密再把它發送給服務器。不需要在網絡傳輸密碼(口令),不僅加密所有傳送的數據,而且“中間人”這種攻擊方式也是不可能的(因爲他沒有你的私人密匙)。
      實踐開始:我是在 win10 下測試的,使用了 win10 子系統 ubuntu 作爲其中的客戶端機器,再開啓虛擬機(centos 系統)作爲服務器。
      默認 ubuntu 和 centos 都安裝了 ssh 服務,沒有的話可以自行百度命令安裝。先查看 centos 下 sshd 服務是否開啓,未開啓的話就開啓。
      #查看 ssh 默認運行端口是否有 sshd 服務進程
      netstat -anp|grep 22
      #也可以直接查看 sshd 服務運行狀態
      ps -ef|grep sshd
      #開啓或重啓 sshd 服務
      systemctl start(restart) sshd 或 service sshd start(restart)

      linux 系統 bash 查看 ip 命令:ifconfig 獲取機器 ip 後,就可以直接在客戶機,直接 bash 敲命令:ssh [email protected] 再回車,此時會提示輸入目標服務器密碼,正確輸入即可正常登錄了。如下圖:

      如圖所示,首次連接遠程目標服務器,會提示對方身份不可確定,提供密鑰供客戶端去核實,假如是目標服務的密鑰就允許繼續連接,這也是爲了防止冒充目標服務器發送密鑰的行爲。這邊接受密鑰之後,該主機就會記錄下到  ~/.ssh/known_hosts 文件,下次就不需要再確認了。如圖連接成功發現可以正常獲取虛擬主機服務器目錄文件即成功。
      爲了免去每次連接都需要輸入密碼的麻煩,密碼也容易忘記,所以接下來測試免密登錄操作。
      1.先在客戶機生成密鑰對,有多種密鑰可選擇,可通過命令 ssh-keygen --help 查看,-b 參數指定密鑰位數(bit),-t指定密鑰類型。

      根據你生成的密鑰對,獲取對應的公鑰,比如 id_rsa.pub 或者 id_dsa.pub,將其上傳到目標服務器的需要免密登錄的用戶對應家目錄下 .ssh 目錄下並改名爲 authorized_keys ,root 用戶默認位置是:/root/.ssh/authorized_keys,其它用戶如 yibin,位置是 /home/yibin/.ssh/authorized_keys 。
      可以使用命令 ssh-copy-id 將公鑰文件複製到服務器的 authorized_keys 文件並自動設置權限爲 644 。-i 後面指定要上傳的公鑰文件,再往後就是目標服務器的 user@host。然後目標服務器對應 ~/.ssh/authorized_keys 就會自動生成。

      這裏還有個坑我一開始不知道,就是我可能出於好奇,在上面就選擇生成了 dsa 類型的密鑰對,結果一頓操作基本沒大問題,就是死活無法免密登錄。測試 n 多次也沒用,後面百度後發現是 openssh 7以上版本默認不支持 dsa 公鑰登錄了,可以 ssh -V 查看 OpenSSH 版本。然後網上說去 sshd 服務配置文件(/etc/ssh/sshd_config)新增配置項

      vim /etc/ssh/sshd_config
      #上述命令進去後新增配置項如下
      PubkeyAcceptedKeyTypes=+ssh-dss
      #保存退出重啓 sshd 服務
      systemctl restart sshd

      你們可以嘗試這樣看能否解決,我這邊測試依舊沒起作用。所以下面都是採用的 rsa 密鑰對進行測試的,基本正常。
      1、注意目錄權限:.ssh 目錄權限必須是 700,chmod -R 700 .ssh/。然後就是 authorized_keys 文件的權限了,默認文件所屬用戶是 root ,這種情況下假如你只需要在客戶機用 root 用戶訪問目標服務器的 root 用戶進行免密登錄的話,就可以設置權限爲 600,表示只有 root 用戶有 rw 權限即讀寫權限,後面 00 代表組和其它用戶無 rwx 權限。現在你就可以去客戶機在 root 用戶下執行命令:ssh [email protected] 或 ssh 192.168.43.83 (192.168.43.83 是目標服務器 ip)進行登錄操作,假如直接跳過密碼登錄,那麼恭喜你成功了!假如提示需要輸入密碼的話,就到目標服務器查看 sshd 配置文件:/etc/ssh/sshd_config,將配置參數  PubkeyAuthentication 值改爲 yes,並去掉註釋符 #,還需要看看是否允許 root 登錄,即將 PermitRootLogin 值置爲 yes,再保存文件,後重啓 sshd 服務即可。

      #ubuntu 系統重啓 sshd 服務命令
      /etc/init.d/ssh restart
      #centos 系統重啓 sshd 服務命令
      service sshd restart


      上面成功實現客戶機 root 用戶免密登錄目服務器 root 用戶,方法就是將客戶機 root 用戶生成的密鑰對中的公鑰放置到目標服務器要免密登錄的 root 用戶下的 ~/.ssh/authorized_keys 文件,並設置對應 sshd 服務的配置文件,允許公鑰認證登錄,此時 authorized_keys 文件權限可以是 600 或者 644 都沒問題。
      2、接下來我就想在客戶機用 root 用戶免密登錄目標服務器的非 root 用戶,比如 yibin 用戶,聰明的你肯定想到了,沒錯就是將客戶機 root 用戶的公鑰放置到目標服務器的 yibin 用戶家目錄下 .ssh 目錄下,改名爲 authorized_keys,完整路徑爲 /home/yibin/.ssh/authorized_keys,注意 .ssh 文件夾權限需設置爲 700,aurhoriized_keys 文件權限爲 600 或 644。
      3、客戶機非 root 用戶免密登錄服務器 root 用戶
           同樣的原理,此時需要在客戶機非 root 用戶下,我這邊是 yibin 用戶,從 root 用戶切換到 yibin 用戶命令,su yibin  ,接下來就是生成密鑰對了,可以直接使用命令 ssh-keygen 按回車默認生成 rsa 密鑰對,再將公鑰 id_rsa.pub 上傳到服務器的 root 用戶家目錄的 .ssh 目錄下,生成文件:~/.ssh/authorized_keys(即 /root/.ssh/authorized_keys),檢查 .ssh 文件夾權限是否爲 700,authorized_keys 文件權限是否爲 644,注意這裏是設置爲 644 而不是 600了,否則一直提示需要密碼登錄。失敗原因和下面第4點情況一致,所以統一在第4點解釋。

      4、客戶機非 root 用戶免密登錄服務器非 root 用戶
            比如客戶機 yibin 用戶需要免密登錄到服務器 yibin 用戶,首先在 yibin 用戶下生成密鑰對,再將公鑰複製到服務器 yibin 用戶家目錄 .ssh 目錄下,確保生成文件:~/.ssh/authorized_keys(即 /home/yibin/.ssh/authorized_keys),保證目錄 .ssh 權限爲 700,authorized_keys 文件權限爲 644,一開始我設置成權限爲 600,結果就踩坑了,一直沒緩過神來,無意間發現文件所屬還是 root,然後設置權限是 600 的話,意思是隻有 root 有讀寫權限,組和其它用戶都無權限,導致無法免密登錄。
      解決方法之一:我直接將文件所屬改爲 yibin 了,比較暴力,雖然 yibin 可以免密登錄 yibin 了,但是其它非 yibin 用戶估計就無法免密登錄服務器的 yibin 用戶了,所以還是參考解決方法二。


      解決方法之二:將文件權限設置爲 644,即 root 擁有讀寫權限,組和其它用戶都是 4 權限即 r 權限(讀權限),所以客戶機 yibin 用戶也能免密登錄服務器的 yibin 用戶,這個解決方案比較合理。見下圖:

      至此,客戶端(非)root 用戶免密登錄服務器(非)root 用戶的場景就基本講完了。假如報錯如下圖,可以查看服務器端是否正確放置 authorized_keys 文件(內容爲客戶機對應用戶的公鑰文件),並確認權限是否設置正確,再檢查 /etc/ssh/sshd_config 配置文件參數如 PermitRootLogin(假如允許 root 登錄就開啓,否則最好關閉),PubkeyAuthentication 是否設置爲 yes(免密登錄需要設置爲 yes,否則設置爲 no)等。

      /etc/ssh/sshd_config 配置文件參數

      最後假如需要使用別名連接遠程服務器,可以在客戶端的 ssh_config(/etc/ssh/ssh_config)進行配置。

      vim /etc/ssh/ssh_config
      #新增如下內容
      Host yibin
      HostName 192.168.43.83
      Port 22
      USER yibin
      IdentityFile ~/.ssh/id_rsa #這個默認的,不加也行
      #保存退出就可以使用下面命令連接了
      ssh yibin


      總結
      1、最好生成密鑰對類型爲 rsa 的,dsa 我這邊測試沒成功,一開始就踩坑了。
      2、.ssh 文件夾權限設置爲 700,authorized_keys 文件權限設置爲 644 比較穩妥,除非你客戶機都是由 root 用戶發起連接就可以設置爲 600,否則就像我一樣踩坑了!
      3、實時查看 sshd 連接日誌文件:tail -f /var/log/secure。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章