AWS IAM Anywhere 使用 X.509 數位憑證交換 IAM Role session token

2022-09-12 AWS

2022/07/06,AWS 發佈了 AWS IAM Anywhere 這項功能「Extend AWS IAM roles to workloads outside of AWS with IAM Roles Anywhere」,在這之前如果在 AWS 以外的環境都只能使用 IAM AKSK (Access key, Access secret key) 來存取 AWS resources,但如果企業期望能更有效的控管 credentials 其實並不容易,尤其是自動化工具常常遇到要寫死 AKSK 一不小心就丟失在 Github 的茫茫大海中被撈去挖礦,風險非常高。這篇作者會紀錄 IAM Anywhere 的實作過程,過程中會採用 OpenSSL 產生的 private CA 來換發 X.509 憑證,所以至少你需要有一個能執行 OpenSSL 的環境 (e.g. Linux)

How to works

How to works

  1. Non-AWS workloads 拿著 X.509 certificates 去跟 IAM Roles Anywhere (CA) 驗證
  2. IAM Roles Anywhere 使用 CreateSession API 換到 AWS STS (Security token service)
  3. AWS STS 返回給 Non-AWS workloads
  4. AWS CLI / SDK 拿著 AWS STS 存取 AWS resources

IAM Roles Anywhere components

  • Trust anchors:關聯 IAM Roles Anywhere 與 CA certificate 間的信任關係
  • Profiles:定義 “who” 可以 assume role,通常以 workload、server 或是 device 為一個單位。
  • Roles:IAM Role

Requirements

在開始之前,請詳閱公開說明書中的一些限制:

CA (Trust Anchor)

  • 必須要是 PEM 格式
  • 使用 v3 certificate
  • CA basic constraints 必須要是 CA:TRUE

Client Certificates

  • 使用 v3 的 X.509 certificate
  • Client certificate basic constraints 必須要是 CA:FALSE
  • Key 必須支援 digital signature (standard SigV4-compatible session credential)
  • 至少基於 SHA256 或更強的演算法

Networking (Domain)

  • 必須能夠訪問以下 domain name
    • rolesanywhere.amazonaws.com
    • rolesanywhere.{AWS_REGION}.amazonaws.com
  • 或是使用 VPC endpoint

CA certificate 建立

AWS IAM Anywhere 支援 AWS ACM Private CA 或者自簽 CA 由 IAM Trust Anchor 託管,在這篇選擇用 OpenSSL 自簽 CA certificate。如果你跟作者一樣使用 Linux 那麼在 /etc/ssl/openssl.cnf 需要修改以下參數

[ v3_ca ]
basicConstraints        = critical, CA:TRUE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, cRLSign, digitalSignature, keyCertSign
  • basicConstraints 必須要是 CA:TRUE
  • keyUsage 要支援 digitalSignature

使用 OpenSSL 產生 v3 CA certificate

$ openssl genrsa -out ca.key 4096
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.pem -extensions v3_ca

驗證產生出來的 CA certificate:

$ openssl x509 -text -noout -in ca.pem

Certificate:
    Data:
        Version: 3 (0x2)
        ...
        Signature Algorithm: sha256WithRSAEncryption
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
...

上述列出的參數都是 IAM Anywhere 對於 CA certificate 的基本要求。

Client certificates 簽發

建立 v3_client_extension.conf 用來產生 client certificates

# v3_client_extension.conf
authorityKeyIdentifier=keyid, issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment

使用 OpenSSL 產生 v3 client certificates

$ openssl genrsa -out client.key 4096
$ openssl req -new -key client.key -out client.csr
$ openssl x509 -req -in client.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client.pem -days 3650 -sha256 -extfile v3_client_extension.conf

此時我們用 OpenSSL 產生了 CA、Client certificates:

ca.key
ca.pem
client.key
client.csr
client.pem

AWS IAM Roles Anywhere 設定

IAM Roles Anywhere 建立 Trust anchor,將 ca.pem 填入 External certificate bundle

建立 IAM Role 並且允許 IAM Roles Anywhere assume 這個 IAM Role。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "rolesanywhere.amazonaws.com"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:SetSourceIdentity",
                "sts:TagSession"
            ]
        }
    ]
}

授予這個 IAM Role 訪問 Amazon S3 bucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<DOC-EXAMPLE-BUCKET>/*"
        }
    ]
}

建立 Profile 並且綁定 IAM Role

在 Profile 這邊有幾項設定需要注意:

  • 一個 Role 只能綁定一個 Profile,但是一個 Profile 可以綁定多個 Roles
  • Profile session policy 優先 IAM Role policy
    • IAM Role 擁有 AdministratorAccess Allow action: “*”
    • Profile session policy Deny action “s3:*”
    • 則不能訪問 Amazon S3,但可以訪問其他 AWS services
  • Profile session policy 更常用 Condition 限制來源 e.g. aws:PrincipalTag/x509Subject/TW, aws:SourceIp

Test & result

IAM Roles Anywhere 提供 aws_signing_helper 工具處理與 IAM Role Anywhere X.509 的認證

$ aws_signing_helper credential-process \
    --certificate ca.pem \
    --private-key ca.key \
    --trust-anchor-arn <TA_ARN> \
    --profile-arn <PROFILE_ARN> \
    --role-arn <IAM_Role_ARN>

然後拿到一個 AWS STS token 用來 AWS CLI, SDK 訪問。

{
  "Version":1,
  "AccessKeyId":"foo ...",
  "SecretAccessKey":"bar ....",
  "SessionToken": "qwe ...",
  "Expiration": "2022-09-09T20:55:27Z"}
}

另一種方法是 AWS configuration 直接將授權寫在 ~/.aws/config

[default]
credential_process = /usr/local/bin/aws_signing_helper credential-process
    --certificate ca.pem 
    --private-key ca.key 
    --trust-anchor-arn <TA_ARN>
    --profile-arn <PROFILE_ARN>
    --role-arn <IAM_Role_ARN>

最後測試一下

$ aws s3 cp sample.txt s3://sample-bucket/

使用 X.509 與過去最大的不同是,以往企業在做金鑰管理時 IAM AKSK 是存放在 AWS IAM 裏面並不容易進行 rotate 以及管理,尤其是在 multi-account 下的環境更是頭痛,但是在有一定規模需要做金鑰管理的企業中 Private CA 算是常見的信任機制,而 IAM Roles Anywhere 基於 Private CA 讓企業等級的公司有更容易集中管理 IAM credentials 的方法。

References

給 Mr. 沙先生一點建議

彙整

分類

展開全部 | 收合全部

License

訂閱 Mr. 沙先生 的文章

輸入你的 email 用於訂閱