AWS Security Workshop - 권한 경계

Glen·2023년 6월 7일
0

aws security workshop

목록 보기
2/10

link

시나리오

  • 웹 애플리케이션을 배포
  • Lambda 함수에 대한 IAM 역할을 생성할 수 있어야 하는 웹 관리자를 포함하여 다양한 팀이 아키텍처의 다양한 측면에서 작업.
  • 신속하게 반복할 수 있도록 웹 관리자에게 권한을 위임하는 데 권한 경계를 사용하여 권한을 에스컬레이션하거나 다른 팀의 리소스에 영향을 주지 않고 필요한 역할을 생성할 수 있도록 함.

계정 아키텍처

실습 목표

  • 웹 관리자를 설정하여 IAM 역할을 생성하고 S3 버킷을 읽을 Lambda 함수에 연결
  • 웹 관리자는 권한을 에스컬레이션하거나 동일한 AWS 계정에 있는 다른 팀의 리소스에 영향을 주지 않고 이를 수행하는 데 필요한 권한이 필요함. 
  • 웹 관리자는 다음 리소스에만 액세스할 수 있어야 함.
    1. 생성하는 IAM 정책 및 역할
    2. 웹 관리자가 생성하는 역할은 “shared-logging” 으로 시작하고 “data”로끝나는 버킷의 webadmins 폴더에 있는 로그 파일을 나열할 수만 있어야 함.

환경설정

  • CloudFormation 사용
    • lambda, s3등 설정

1. webadmins 역할생성

  • lambda readonly 정책을 assume 받을수있는 역할을 생성
  • 실습하다보니 root는 assume 받을 수 없다는걸 알게됨.
    - 앞서 실습한 SecAdmin으로 변경함
    - arn:aws:iam:::user/SecAdmin

2. 역할을 생성할때 사용할 권한 경계 생성

  • 정책명 : webadminspermissionsboundary
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateLogGroup",
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:us-east-1:<ACCOUNT_ID>:*"
        },
        {
            "Sid": "CreateLogStreamandEvents",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:us-east-1:<ACCOUNT_ID>:log-group:/aws/lambda/*:*"
        },
        {
            "Sid": "AllowS3GetObject",
            "Effect": "Allow",
            "Action": [
                "s3:List*"
            ],
            "Resource": "arn:aws:s3:::shared-logging-<ACCOUNT_ID>-us-east-1-data",
             "Condition": {
                "StringEquals": {
                    "s3:prefix": "webadmins"
                    }
                }
        },
        {
              "Sid": "OtherPermissionsNeeded",
              "Effect": "Allow",
              "Action": [
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem"
              ],
              "Resource": "*",
              "Condition": {
                    "StringEquals": {
                    "aws:RequestedRegion": "us-east-1"
                    }
                }
        }
    ]
}
  • 허용된 정책 서비스 목록

3. ID기반 정책 생성

  • 정책명 : webadminspermissionpolicy
  • resource의 policy, role 뒤에 있는 ???는 일단 로 변경함.
    • 수정안하면 정책 생성 안됨.
    • 참고
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateCustomerManagedPolicies",
            "Effect": "Allow",
            "Action": [
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:CreatePolicyVersion",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": "arn:aws:iam::<ACCOUNT_ID>:policy/webadmins/???*"
        },
        {
              "Sid": "RoleandPolicyActionswithnoPermissionBoundarySupport",
            "Effect": "Allow",
            "Action": [
                    "iam:UpdateRole",
                    "iam:DeleteRole"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/webadmins/???*"
            ]
        },
        {
            "Sid": "CreateRoles",
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:role/webadmins/???*"
            ],
            "Condition": {"StringEquals": 
                {"iam:PermissionsBoundary": "arn:aws:iam::<ACCOUNT_ID>:policy/webadminspermissionsboundary"}
            }
        },
        {
            "Sid": "LambdaFullAccess",
            "Effect": "Allow",
            "Action": "lambda:*",
            "Resource": "arn:aws:lambda:us-east-1:<ACCOUNT_ID>:function:*"
        },
        {
            "Sid": "PassRoletoLambda",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::<ACCOUNT_ID>:role/webadmins/???*",
            "Condition": {
                "StringLikeIfExists": {
                    "iam:PassedToService": "lambda.amazonaws.com"
                }
            }
        },
        {
            "Sid": "AdditionalPermissionsforLambda",
            "Effect": "Allow",
            "Action":   ["kms:ListAliases", "logs:Describe*", "logs:ListTagsLogGroup", "logs:FilterLogEvents", "logs:GetLogEvents"],
            "Resource": "*"
        },
        {
            "Sid": "DenyPermissionBoundaryandPolicyDeleteModify",
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::<ACCOUNT_ID>:policy/webadminspermissionsboundary",
                "arn:aws:iam::<ACCOUNT_ID>:policy/webadminspermissionpolicy"
            ]
        },
        {
            "Sid": "DenyRolePermissionBoundaryDelete",
            "Effect": "Deny",
            "Action": "iam:DeleteRolePermissionsBoundary",
            "Resource": "*"
        }
    ]
}
  • 거부/허용된 서비스 정책들
  • webadmins에 정책 연결
    - lambda readonly, 위 정책 두개가 있어야 함.

권한 테스트

  • 작업을 확인하고 웹 관리자가 제대로 설정되었는지 확인

  • 테스트 계정 하나로 진행하므로 다른 어카운트로 assume하는것은 생략.

  • aws cli setting

    • .aws/config 에 작성해준다.
    • 이때 cli의 source_profile은 webadmin에 등록한 사용자이어야 한다.
    [profile webadmins]
    role_arn = arn:aws:iam::YOUR_TEAMS_ACCOUNT_ID:role/webadmins
    source_profile = SecAdmin

create policy

  • aws iam create-policy --policy-name webpolicy --policy-document file://verifypolicy.json --profile webadmins —path /webadmins/

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents",
            "s3:*"
          ],
          "Resource": "*"
        }
      ]
    }
  • 위에서 생성했던 정책에서 ???를 제거하고 로 한부분이 Arn을 가리키는걸로 보임
    - 좀더 강한 정책을 두고싶다면, 이 아닌 web이나 *policy 등으로 진행하면 될듯

  • path 옵션은 아래와 같이 분류하기 위함으로 보임
    - 업무에 적용한다면, 팀별 정책을 만들고 path로 지정하면 allow, deny하기 편할것같다.

create role

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {
      "Service": "lambda.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
  }
}
  • 아래와같은 명령어를 입력했을때 에러가 발생함.
    - assume role에 iam:createRole이 없다고함.

    aws iam create-role --role-name NAME_OF_ROLE --path /webadmins/ --assume-role-policy-document file://verifytrustpolicy.json --profile webadmins

  • permissions-boundary를 추가해야함
    - 왜? > policy의 iam:CreateRole에 조건이 있음
  • iam:CreateRole의 codition 부분
    - StringEquals
  • 앞서 만든 정책을 역할에 적용

    • role :weblambdarole
    • policy : webpolicy
    aws iam attach-role-policy --policy-arn arn:aws:iam::<accountid>:policy/webadmins/webpolicy --role-name weblambdarole --profile webadmins

Lambda

  • 파일명 : index.js

    • 이후 lambdafunction.zip으로 압
  • getKeys

    • Bucket : 위에서 생성된 버킷명
    • prefix : 뭔지모르니 임의로 test로 넣음
    const AWS = require('aws-sdk');
    const s3 = new AWS.S3();
    
    exports.handler = async (event) => {
      console.log('Loading function');
      const allKeys = [];
      await getKeys({ Bucket: 'shared-logging-<accountid>-us-east-1-data' , Prefix: 'test'}, allKeys);
      return allKeys;
    };
    
    async function getKeys(params, keys){
      const response = await s3.listObjectsV2(params).promise();
      response.Contents.forEach(obj => keys.push(obj.Key));
    
      if (response.IsTruncated) {
        const newParams = Object.assign({}, params);
        newParams.ContinuationToken = response.NextContinuationToken;
        await getKeys(newParams, keys); 
      }
    }
  • lambda 생성

    aws lambda create-function --function-name verifyfunction --runtime nodejs14.x --role arn:aws:iam::<accountid>:role/webadmins/weblambdarole --handler index.handler --region us-east-1 --zip-file fileb://lambdafunction.zip --profile webadmins
  • labmda 생성 결과

  • 생성한 lambda 실행
    - 실패.
  • outfile.txt

    • 왜? > prefix 때문
    {"errorType":"AccessDenied","errorMessage":"Access Denied","trace":["AccessDenied: Access Denied","    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:711:35)","    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)","    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)","    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:686:14)","    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)","    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)","    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10","    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)","    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:688:12)","    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"]}
  • webadminspermissionsboundary의 s3 정책 조건을 살펴보자
    - prefix 확인가능

  • index.js의 prefix를 수정하고 function-name과 fileb 이름을 2로 변경하여 배포하고 invoke 시도
  • outputfile2.txt
    • 성공
    ["webadmins/you-should-SEE-this-file--webadmins_logging1","webadmins/you-should-SEE-this-file--webadmins_logging2","webadmins/you-should-SEE-this-file--webadmins_logging3","webadmins/you-should-SEE-this-file--webadmins_logging4"]
profile
어제보다 나은 엔지니어가 되기 위해서 공부중

0개의 댓글