The Art of Readable Code && High Performance Comments

AWS 與 Credential

AWS 玩弄的這幾年,常碰到開發者對 AWS Credential 一知半解;希望這篇文章能有幫助。

在 AWS 裡,所有資源係透過調用 AWS API 來控制,並且 AWS 的 API 現在相當一致:HTTPS, RESTful, Stateless。注意,這與和 AWS 內建立的資源互動不同:前者例如像透過 API 建立新 EC2 機器 (ec2:RunInstances) ,後者則例如透過 SSH (TCP:22) 與建立出的資源溝通。大部份的 AWS API 以 asynchronous 方式設計,server 因而會盡快回覆,而若結果不如預期或發生錯誤 (例:S3 GET 新上傳物件時,回傳 404) 則由 client 自行重試 (retry, 建議使用 incremental delay)。

調用 AWS API 時,須以 Credential 簽署 HTTP Request,目前最新標準是 Sig V4。每組 Credential 包含 Access Key, Secret Key 與 Session Token (STS 限定);其中 Access Key 可以公開,而 AWS 會透過比對 Signature (使用了 Secret Key) 確定簽署者的身份,並進入次一階段。

每組 Credential 都會對應到一個 AWS Identity,包含 IAM User 與 IAM Role;而 AWS 在確認調用者身份後,會檢查適用的所有 Policy (User/Role Policy 與 Resource Policy),以決定是否放行該 HTTP Request。若有任何一條 Policy 明確拒絕 (Explicit Deny),則該請求會回傳 403 Forbidden;在沒被拒絕的前提下,若任何 Policy 明確授權 (Explicit Allow) 則放行,最後則是預設拒絕 (Default Deny)。當然,請求被放行不代表執行會成功,HTTP 回應成功也不代表後續都能順利完成,因此還是要查詢 Log (CloudTrail) 或調用對應 API 除錯。例如 RunInstance EBS 達到容量上限的情況下,會執行成功,但 EC2 會在建立後自動 Terminate;要透過 DescribeInstance 取得關閉原因才能發現。

sts:AssumeRole 可以讓一個 Identity 轉換為另一個 IAM Role (以舊有 Identity 的 Credential 簽署請求,如果執行成功,AWS 會回傳代表 IAM Role 的另一組 Temporarily Credential);在執行 AssumeRole 呼叫時,可以帶入額外的 IAM Policy,則該 Policy 也會作用在回傳取得的 Credential 上。由 ARN 可推論這樣的 Identity 被稱作 assumed_role,但官方文件並沒有提及,也不影響日常操作。

透過 SDK 調用 AWS API 時,大多 SDK 都實作了 Credential 的查找順位:

  1. 呼叫參數 (包含 resource / property)
  2. 環境變數 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, ...)
  3. Profile (~/.aws/credentials)
  4. Instance Profile (透過 169.254.169.254 ,AWS EC2 限定,但在 hybrid 環境惡搞也是一招)

早期不同 SDK 對 Credential 查找的位置與變數名稱小有差異,小弟則送過 PR 給 PHP SDK 將 credential 取用方式往 boto / awscli 靠攏;無奈因牽涉安全核心被 Reject,但仍是次有趣的經驗。我確定 Python 與 PHP 毋須特別設定,而 Java 要使用 com.amazonaws.auth.DefaultAWSCredentialsProviderChain 才會進行查找。

Credential 的使用與管理方式就不贅述了,每年都會聽到不遵從 IAM Best Practices ,弄丟 Credential 被挖礦的案例;或許這才是常態吧。

發表迴響

分類

%d 位部落客按了讚: