Instance Metadata Service(實例中繼資料服務)
實例中繼資料服務(instance metadata service,IMDS)是雲端業者在每台主機上提供的一個 HTTP 端點,位址固定是 169.254.169.254,只有主機自己連得到。主機上的程式向它查詢這台主機的資訊:主機 ID、所在區域與可用區、網路設定、建立時放進去的 SSH 公鑰與初始化腳本,以及業者發給這台主機的身分憑證(讓主機上的程式不必存放長期金鑰就能呼叫雲端 API,見 Service Account(服務帳號))。
概念位置
開機流程依賴它:cloud-init 在主機第一次開機時從中繼資料服務讀出 SSH 公鑰寫進 authorized_keys、讀出初始化腳本並執行。業者的代理程式也從這裡讀主機的設定。
同一個特性也是它的風險:主機上任何能發 HTTP 請求的程式都讀得到它。網頁應用程式有 SSRF(server-side request forgery,伺服器端請求偽造)漏洞時,攻擊者可以讓應用程式替他去讀 169.254.169.254,取得主機的身分憑證,再拿那份憑證在雲端帳號裡以主機的權限行事。
第二版的存取方式(AWS 與 Oracle Cloud 叫 IMDSv2)要求請求帶上證明:AWS 要先用 PUT 請求取得一個 token、之後每個請求在標頭帶著它,Oracle Cloud 要每個請求帶 Authorization: Bearer Oracle 標頭並改打 /opc/v2 路徑。兩版可以並存,主機的設定改成只允許第二版之後,不帶證明的第一版請求才會被拒絕。多數 SSRF 漏洞只讓攻擊者控制網址、控制不了標頭,所以這一個要求就擋掉了大部分的攻擊路徑。Google Cloud 的中繼資料伺服器固定要求 Metadata-Flavor: Google 標頭,作用的方向相同:擋掉只能控制網址、帶不了標頭的請求;AWS 的 token 另外要先用 PUT 取得,擋的範圍更大一些。
可觀察訊號
- 建立頁上有「Require an authorization header」(Oracle Cloud)、「Metadata version: V2 only (token required)」(AWS)這類選項
- 主機上的舊程式或舊版工具讀不到中繼資料、請求回錯誤:它還在用第一版的請求方式
- 安全掃描報告指出某台主機允許 IMDSv1:那台主機上的應用程式一旦有 SSRF 漏洞,身分憑證就讀得到
設計責任
- 新主機:映像檔支援第二版時開啟強制要求。Oracle Cloud 官方列出支援的平台映像是 Oracle Linux 與 Oracle Autonomous Linux,其他平台映像(包括 Ubuntu)、多數自訂映像與多數市集映像不支援;自訂的 Linux 映像在 cloud-init 20.3 以上、Oracle Cloud Agent 0.0.19 以上時可能支援(官方給自訂映像的條件)。在不支援的映像上強制第二版,cloud-init 讀不到公鑰,主機會連不上。Oracle Cloud 上這個設定建立後可以在主機頁面改回兩版都允許、再重開,判斷與處置見 代理程式、中繼資料服務、初始化腳本、維護行為與標籤 的〈中繼資料服務與 Authorization header〉
- 既有主機改成只允許第二版:先確認主機上讀中繼資料的程式(代理程式、SDK、自己的腳本)都已支援第二版,再切換
- 主機的身分權限:主機被授權呼叫雲端 API 時(例如主機上的程式要寫物件儲存),業者經由中繼資料服務把代表主機身分的憑證交給主機上的程式——Oracle Cloud 叫 instance principal(權限由 dynamic group 加 policy 授予),AWS 是掛在主機上的 IAM role(經由 instance profile),Google Cloud 是掛在主機上的服務帳號。這份憑證帶著主機身分的全部權限,所以權限只給這台主機上的程式需要的那些
鄰卡
- Service Account(服務帳號) — 中繼資料服務發放的憑證代表的身分
- IAM — 決定那份憑證能做什麼
- 代理程式、中繼資料服務、初始化腳本、維護行為與標籤 — 建立主機時的中繼資料服務選項