SSH Connect AWS EC2 Ubuntu Permission denied (publickey)
前言
手邊有個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大部分屬於兩種問題:
- User Name輸入錯誤
- 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無法正常連接,提供以下兩種解決辦法:
- 於.ssh/config檔案中加入以下兩行接受RSA演算法
PubkeyAcceptedAlgorithms +ssh-rsa
HostkeyAlgorithms +ssh-rsa - Ubuntu降版至20.04版本
心得與反思
最近在攻讀AWS SAA這張Certification,其中研讀到了一些關於AWS的知識,並且持續在培養”如何有效地解決問題”這個心態,學習該怎麼一步一步的排除問題,並找到好的解決方案,我相信這會非常有助於自己在Cloud這塊的發展!