Vinc3nt's Life

AWS STS & Hands on

2024-06-08
develop
aws
aws-sts
security
最後更新:2025-01-26
9分鐘
1601字

什麼是 AWS STS

AWS Security Token Service (STS) 是 Amazon Web Services 提供的一個 Web 服務,用於臨時地提供一組受限的安全憑證。這些憑證允許用戶或應用程式在指定的時間內訪問 AWS 資源,而不需要擁有長期的 AWS 認證。STS 的主要用途包括跨帳戶訪問、臨時升級權限以及移動和 Web 應用程式中的身份聯合(Federation)。

為什麼要用 AWS STS

傳統上,我們都是使用 IAM User 長期的 AWS Access Keys 憑證來訪問 AWS 資源。然而,這種做法存在一些風險:

  • 安全問題:User 長期憑證如果洩露,風險極大。
  • 管理困難:多個帳戶和角色的長期憑證管理起來相當麻煩。

這時候,AWS STS 就派上用場了。它可以發放臨時憑證,並且這些憑證都有時效性,減少了被濫用的風險。

AWS STS 的主要用途

  • 短期存取權限:適合需要臨時存取 AWS 資源的情況,例如執行敏感操作。
  • 應用程式存取:應用程式可以通過 STS 取得臨時憑證,避免長期憑證暴露的風險。
  • Federation:整合外部身份提供者(如 Google 或 Azure),用戶可以通過外部提供者登入 AWS。
  • 跨帳戶存取:讓一個帳戶中的用戶臨時存取其他帳戶中的資源,避免繁瑣的身份管理。

如果你有用過 AWS IAM Identity Center,你會發現這個服務的底層原理也是透過 STS 頒發臨時憑證。

default

Switching accounts from the User Portal - AWS Blogs

default

Methods to request credentials from AWS STS - AWS Blogs

AWS STS 是怎麼運作的

成功的 STS 交易會經歷以下的步驟:

  1. 創建 User 和 Role:AWS 管理員創建一個 IAM User 和一個 IAM Role。User 需被附加 sts:AssumeRole Policy 使其可以扮演 Role,而 Role 要附加想要給予的 Policy,比如查看 S3 的權限。
  2. 配置 Trust Policy:管理員為 User 和 Role 配置 Trust Policy。一旦 Trust Policy 被創建,User 可以調用 STS 服務請求該 Role 的憑證。
  3. 請求扮演 Role:當 User 需要 Role 的權限時,調用 STS API 並請求扮演該 Role。STS 通過檢查適當的 Trust Policy 來驗證請求。
  4. 生成臨時憑證:STS 動態生成一組新憑證並在 API 回應中發給用戶的應用程式。這些憑證不會存儲在用戶上,只在過期前有效。
  5. 調用 AWS API:使用剛剛得到的新憑證,調用所需的 AWS API 進行訪問。

如果想要深入淺出了解 STS,可以到 Benefits of ROSA STS 看看他們的講解。

Hands On

接下來,我會演示 AWS STS 資源建置,以及如何透過 STS 賦予臨時憑證,來訪問 S3 資源。

以下操作的 AWS CLI Credentials 預設使用的是系統管理員身份,建立的臨時憑證將會設為 profile 管理。

建立 S3

首先,創建當作示範的 AWS S3,這裡命名為 vince987-sts-demo,bucket 位置設定在 us-west-2

Terminal window
1
$ aws s3api create-bucket --bucket vince987-sts-demo --create-bucket-configuration LocationConstraint=us-west-2
2
{
3
"Location": "http://vince987-sts-demo.s3.amazonaws.com/"
4
}

建立 IAM User

我們需要創建 User,這個 User 可以透過 STS 取得臨時憑證,來訪問 S3。

  • 創建 IAM User - temp-user

    Terminal window
    1
    $ aws iam create-user --user-name temp-user
    2
    {
    3
    "User": {
    4
    "Path": "/",
    5
    "UserName": "temp-user",
    6
    "UserId": "AIDAYZKJQNIYGPXY6GJFV",
    7
    "Arn": "arn:aws:iam::344227375522:user/temp-user",
    8
    "CreateDate": "2024-06-08T08:42:12+00:00"
    9
    }
    10
    }
  • 創建 Access Key

    Terminal window
    1
    $ aws iam create-access-key --user-name temp-user
    2
    {
    3
    "AccessKey": {
    4
    "UserName": "temp-user",
    5
    "AccessKeyId": "AKIAYZKJQNIYECUDIXUQ",
    6
    "Status": "Active",
    7
    "SecretAccessKey": "tG3K8HonKZlVNiDYbJ+X9ptLOAI172kDMrHWbYqe",
    8
    "CreateDate": "2024-06-08T08:43:10+00:00"
    9
    }
    10
    }
  • 在 Terminal 添加新的 profile:

    • ~/.aws/config 加上新的配置:

      1
      [profile sts]
      2
      region=us-west-2
      3
      output=json
    • ~/.aws/credentials 加上新的憑證信息:

      1
      [sts]
      2
      aws_access_key_id=AKIAYZKJQNIYECUDIXUQ
      3
      aws_secret_access_key=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
  • 使用剛剛建立的 User 進行測試:

    Terminal window
    1
    $ aws s3api list-buckets --profile sts
    2
    3
    An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

被拒絕是正常的,因為這個使用者並沒有任何權限,也沒有扮演任何角色

允許使用者扮演 roles - 建立 IAM Policy - Assume roles

為了讓 user 可以透過 STS 扮演角色,需要給他 IAM permission – sts:AssumeRole

  • assume_roles.json 內容如下:

    1
    {
    2
    "Version": "2012-10-17",
    3
    "Statement": [
    4
    {
    5
    "Effect": "Allow",
    6
    "Action": [
    7
    "sts:AssumeRole"
    8
    ],
    9
    "Resource": "*"
    10
    }
    11
    ]
    12
    }
  • 透過 assume_roles.json 創建 policy

    Terminal window
    1
    $ aws iam create-policy --policy-name sts-assume-roles --policy-document file://assume_roles.json
    2
    {
    3
    "Policy": {
    4
    "PolicyName": "sts-assume-roles",
    5
    "PolicyId": "ANPAYZKJQNIYMF66RJEUA",
    6
    "Arn": "arn:aws:iam::344227375522:policy/sts-assume-roles",
    7
    "Path": "/",
    8
    "DefaultVersionId": "v1",
    9
    "AttachmentCount": 0,
    10
    "PermissionsBoundaryUsageCount": 0,
    11
    "IsAttachable": true,
    12
    "CreateDate": "2024-06-08T08:57:14+00:00",
    13
    "UpdateDate": "2024-06-08T08:57:14+00:00"
    14
    }
    15
    }
  • 附加 Policy 到 temp-user

    Terminal window
    1
    $ aws iam attach-user-policy --user-name temp-user --policy-arn "arn:aws:iam::344227375522:policy/sts-assume-roles"
  • 使用 aws iam list-attached-user-policies 檢查結果

    Terminal window
    1
    $ aws iam list-attached-user-policies --user-name temp-user
    2
    {
    3
    "AttachedPolicies": [
    4
    {
    5
    "PolicyName": "sts-assume-roles",
    6
    "PolicyArn": "arn:aws:iam::344227375522:policy/sts-assume-roles"
    7
    }
    8
    ]
    9
    }

建立 User 將要扮演的 Role

接下來,增加一個 IAM Role user-trust-policy-role,這個 Role 擁有剛好的權限,允許我們訪問特定的 S3。

不過在這之前,先建立 Policy。

  • s3-readonly-role.json 內容如下:

    1
    {
    2
    "Version": "2012-10-17",
    3
    "Statement": [
    4
    {
    5
    "Effect": "Allow",
    6
    "Action": [
    7
    "s3:Get*",
    8
    "s3:List*"
    9
    ],
    10
    "Resource": "*"
    11
    }
    12
    ]
    13
    }
  • 透過 s3-readonly-role.json 創建 Policy

    Terminal window
    1
    aws iam create-policy --policy-name s3-readonly --policy-document file://s3-readon
    2
    ly-role.json
    3
    {
    4
    "Policy": {
    5
    "PolicyName": "s3-readonly",
    6
    "PolicyId": "ANPAYZKJQNIYJCA3V22KR",
    7
    "Arn": "arn:aws:iam::344227375522:policy/s3-readonly",
    8
    "Path": "/",
    9
    "DefaultVersionId": "v1",
    10
    "AttachmentCount": 0,
    11
    "PermissionsBoundaryUsageCount": 0,
    12
    "IsAttachable": true,
    13
    "CreateDate": "2024-06-08T11:30:00+00:00",
    14
    "UpdateDate": "2024-06-08T11:30:00+00:00"
    15
    }
    1 collapsed line
    16
    }

建立 Trust policy

接下來,我們需要在創建 Role 的同時,使用 Trust policy 將 User 和 Role 關聯在一起。

  • user-trust-policy.json 內容如下:

    1
    {
    2
    "Version": "2012-10-17",
    3
    "Statement": {
    4
    "Effect": "Allow",
    5
    "Principal": {
    6
    "AWS": "arn:aws:iam::344227375522:user/temp-user"
    7
    },
    8
    "Action": "sts:AssumeRole"
    9
    }
    10
    }
  • 創建 Role - user-trust-policy-role,同時將 Trust Policy 添加到這個 Role

    Terminal window
    1
    $ aws iam create-role --role-name user-trust-policy-role --assume-role-policy-document file://user-trust-policy.json
    2
    {
    3
    "Role": {
    4
    "Path": "/",
    5
    "RoleName": "user-trust-policy-role",
    6
    "RoleId": "AROAYZKJQNIYLHNL7TQOJ",
    7
    "Arn": "arn:aws:iam::344227375522:role/user-trust-policy-role",
    8
    "CreateDate": "2024-06-08T19:01:52+00:00",
    9
    "AssumeRolePolicyDocument": {
    10
    "Version": "2012-10-17",
    11
    "Statement": {
    12
    "Effect": "Allow",
    13
    "Principal": {
    14
    "AWS": "arn:aws:iam::344227375522:user/temp-user"
    15
    },
    5 collapsed lines
    16
    "Action": "sts:AssumeRole"
    17
    }
    18
    }
    19
    }
    20
    }
  • 別忘了將 Policy - s3-readonly 附加到 user-trust-policy-role

    Terminal window
    1
    $ aws iam attach-role-policy --role-name user-trust-policy-role --policy-arn "arn:aws:iam::344227375522:policy/s3-readonly"

現在,temp-user 可以透過 STS,扮演 user-trust-policy-role (擁有 Policy s3-readonly),達成訪問 S3 的目的。

使用 STS 承擔角色

我們來實際使用 STS 來演示:

  • 使用 aws sts assume-role 取得臨時憑證

    Terminal window
    1
    $ aws sts assume-role --role-arn "arn:aws:iam::344227375522:role/user-trust-policy-role" --role-session-name demo-session --profile sts
    2
    {
    3
    "Credentials": {
    4
    "AccessKeyId": "ASIAYZKJQNIYFP2D4E53",
    5
    "SecretAccessKey": "sTT2UNJ6hiNckG0kp4sfsunUlWKmSaqFDQaBVitR",
    6
    "SessionToken": "FwoGZXIvYXdzEJX//////////wEaDDL6IaMES/D3Fsz0OiKwAZx0Jb2jz/q0L6XGu3i6aWb9qQIHxLqP1w41ypXdQwJnjMLfYwHYIXJ1m+CNoAUGKPV1fr2TULrd1iKRDgWxweaPE0NAYTnNnSBk2r2oUIumgJhIDWMtrTMDzIOmPNazkNbLrIVn8RyDoIDastWUqsyKqoTedToDHw9muTgDn4IRaETMepIs+GL8QzLlSPBlblnjX/+/4KpgZkJtUhsyNye1jIqoo9HogciJ1kCKEbZEKNLZkrMGMi0w4Lk3b7iw/dx2mFHDIoPZGI4nDqdEK/Y4EwYxtmXafXYpSVWD3KDgwJg+T4s=",
    7
    "Expiration": "2024-06-08T20:11:14+00:00"
    8
    },
    9
    "AssumedRoleUser": {
    10
    "AssumedRoleId": "AROAYZKJQNIYLHNL7TQOJ:demo-session",
    11
    "Arn": "arn:aws:sts::344227375522:assumed-role/user-trust-policy-role/demo-session"
    12
    }
    13
    }

    (Option) 預設的憑證過期時間是 1 天,如果想要控制過期時間,可以使用以下指令:

    Terminal window
    1
    # 300 秒過期
    2
    $ aws sts assume-role --role-arn "<your_trust_policy_role_arn>" --role-session-name demo-session --duration-seconds 300
  • 在 Terminal 添加臨時憑證的 profile

    • ~/.aws/config 加上新的配置:

      1
      [profile demo-session]
      2
      region=us-west-2
      3
      output=json
    • ~/.aws/credentials 加上新的憑證信息:

      1
      [demo-session]
      2
      aws_access_key_id=ASIAYZKJQNIYFP2D4E53
      3
      aws_secret_access_key=sTT2UNJ6hiNckG0kp4sfsunUlWKmSaqFDQaBVitR
      4
      aws_session_token=FwoGZXIvYXdzEJX//////////wEaDDL6IaMES/D3Fsz0OiKwAZx0Jb2jz/q0L6XGu3i6aWb9qQIHxLqP1w41ypXdQwJnjMLfYwHYIXJ1m+CNoAUGKPV1fr2TULrd1iKRDgWxweaPE0NAYTnNnSBk2r2oUIumgJhIDWMtrTMDzIOmPNazkNbLrIVn8RyDoIDastWUqsyKqoTedToDHw9muTgDn4IRaETMepIs+GL8QzLlSPBlblnjX/+/4KpgZkJtUhsyNye1jIqoo9HogciJ1kCKEbZEKNLZkrMGMi0w4Lk3b7iw/dx2mFHDIoPZGI4nDqdEK/Y4EwYxtmXafXYpSVWD3KDgwJg+T4s=
  • 使用 s3api 進行測試

    1
    $ aws s3api list-buckets --profile demo-session
  • 使用 aws sts get-caller-identity 可以查看目前用於驗證請求的 IAM 身分的相關資訊

    1
    $ aws sts get-caller-identity --profile demo-session
    2
    {
    3
    "UserId": "AROAYZKJQNIYLHNL7TQOJ:demo-session",
    4
    "Account": "344227375522",
    5
    "Arn": "arn:aws:sts::344227375522:assumed-role/user-trust-policy-role/demo-session"
    6
    }

通過以上步驟,我們完成了使用 AWS STS 來管理臨時憑證的基本操作。這樣可以大幅提升安全性,並簡化多帳戶和多角色管理的難度。

參考

本文標題:AWS STS & Hands on
文章作者:Vincent Lin
發布時間:2024-06-08