SSH Connect AWS EC2 Ubuntu Permission denied (publickey)

Leo Liao | 廖鴻林
Leo Liao
Published in
Jul 26, 2022

前言

手邊有個Project使用Gitlab CI/CD部署至AWS EC2 Instance,需要將Instance更換Region從新加坡移到東京,在重新設定IP與SSH Private Key後遇到連接Instance時Permission Denied的問題,藉著這次的機會重新梳理一次對SSH的理解並寫出本篇文章,但文章不會提到太深入SSH原理。

情境

在Gitlab CI/CD Yaml設定檔有個Stage執行Deploy的動作,如下:

這份Yaml會依據Schedule設定的排程時間觸發,將設定在Gitlab CI/CD Variables變數(ex. ${Server_SSH}、${Server_Name}、${Server_IP}),代入值到上述的Script中,將Server_SSH寫入SSH的私鑰檔案並授權,在所有before_script都完成後,會利用SSH連線至Server,並執行一些Docker指令。

在Pipeline的結果出現以下錯誤畫面,如下圖:

以下內容會簡述一些SSH概念與Debug方法,如果已經有先備知識,可以跳到解法的部分。

SSH

SSH是一種加密的網路傳輸協定,能夠在不安全的網路中進行安全的資料交換等動作,透過將訊息經過公私鑰的加解密,來確保你是被允許的人。SSH最常見出現在登入遠端伺服器,現已有非常多種OS支援SSH,如Linux、MacOS與Window等。

SSH使用port 22進行溝通,將Client端的公鑰,儲存於Server端的authorized_keys檔案內,就會視為這個Client端是被Server端所允許的登入的使用者。

在Client端登入時,Server端會傳送一段隨機字串給Client端,Client端利用本身的私鑰加密這串隨機字串給Server端,Server端收到加密過的資料後,利用儲存在authorized_keys內的公鑰進行解密,確認是否與當初傳送給Client端的隨機字串是一致的,以此確保不管是登入上或是資料上的安全性。

產生SSH公私鑰

可以透過ssh-keygen這個command來建立成對的公私鑰。

ssh-keygen \
-b 2048 #私鑰長度
-a rsa #私鑰加密類型

輸入上述指令後,會詢問你是否要添加passphrase,可以為空,如果有填寫每次使用產生的private key時皆需要輸入相同的值,用來避免當private key被拿走時可以被直接使用,增加了安全性,但缺點就是每次使用皆需輸入。

指令完成後,會在~/.ssh資料夾下產生兩個檔案,分別是private key(id_rsa)與public key(id_rsa.pub),這個public key就是上面提到要放在遠端主機裡authorized_keys檔案內檔案。

SSH連線

將公私鑰都設定好後,就可以使用ssh command來對遠端主機做連線,如下:

ssh [User Name]@[IP address]

如果你拿到一個private key檔案(ex .pem),可以直接指定這個檔案位置進行連線,就不用特別設定Client端的公私鑰,AWS EC2就是用這種方式,在建立Instance時可以指定或是創建Key pair,也就是這篇的SSH,讓你直接下載對應的private key,可以直接指定private key進行的登入,使用方法如下:

ssh -i key.pem [User Name]@[IP address]

聚焦問題

在SSH登入時如果遇到Permission Denied大部分屬於兩種問題:

  1. User Name輸入錯誤
  2. Private Key Error

解決歷程

首先要確認不是User Name輸入錯誤,我在AWS EC2創建的Instance Type是Ubuntu,Ubuntu Platform預設將User Name設為ubuntu,我沒有進行異動且在shell script裡面有echo查看Gitlab Variables帶入的變數是對的,排除此問題。

再來確認是否是第二點的問題,這個AWS給的Private Key Pem File,我在本地端是可以直接使用連入Server是沒問題的,並且我也手動建立了一個新的Docker Container來模擬Gitlab CI/CD的環境,執行相同的script,也確認沒問題可以連入EC2 Instance,所以確認這個Private Key是沒問題的。

解法

利用ssh debug console看詳細連接資訊,如下:

ssh -vvv [User Name]@[IP address]

執行後發現以下錯誤:

想了想這應該是連線時產生的temp檔,應該不是這個問題,就在我又研究了幾個小時後,我才發現更上面的錯誤訊息,如下:

結論就是,在SSH加密的演算法中,RSA已經被認為不夠安全,建議使用ed25519,並且在Ubuntu 22.04版本已經納入該項規則,所以導致SSH無法正常連接,提供以下兩種解決辦法:

  1. 於.ssh/config檔案中加入以下兩行接受RSA演算法
    PubkeyAcceptedAlgorithms +ssh-rsa
    HostkeyAlgorithms +ssh-rsa
  2. Ubuntu降版至20.04版本

心得與反思

最近在攻讀AWS SAA這張Certification,其中研讀到了一些關於AWS的知識,並且持續在培養”如何有效地解決問題”這個心態,學習該怎麼一步一步的排除問題,並找到好的解決方案,我相信這會非常有助於自己在Cloud這塊的發展!

--

--

Leo Liao | 廖鴻林
Leo Liao

Frontend Engineer | Web Developer,覺得分享經驗就跟潛水一樣,不知不覺在每段旅途中多認識了自己一點