AWS Step Functions를 이용한 보안 사고 대응 아키텍처

2020. 01. 31 | 블로그

이번 포스팅에서는 AWS Step Functions 중 Standard Workflow의 콜백 패턴을 구현하는 방법을 소개합니다. 이 방법은 자동화된 보안 사고 대응 프레임워크에 수동 승인 단계를 추가합니다. 이 프레임워크는 정의된 개별 정책 Action(작업)에 따라 Action을 자동으로 조정할 수도 있습니다. 예를 들어, 대체 Action을 적용하거나 특정 ARN(Amazon Resource Names)으로 Action을 제한합니다.

이 애플리케이션은 IAM 정책을 생성할 때 Amazon EventBridge를 사용하여 Step Functions Standard Workflow를 트리거합니다. Workflow는 정책 Action을 커스터마이징이 가능한 제한 Action 목록과 비교합니다. 이후 AWS Lambda 및 Step Functions를 이용하여 정책을 일시적으로 되돌린 다음 관리자에게 알리고 Action이 승인 또는 거부될 때까지 기다립니다.

그림 1 : High-level 아키텍처 다이어그램

중요 : 해당 애플리케이션은 다양한 AWS 서비스를 사용하며 프리 티어 사용량을 모두 사용하면, 서비스와 관련된 비용이 발생합니다. 자세한 내용은 AWS 요금 페이지를 참조하세요.

AWS Serverless Application Repository에서 이 애플리케이션을 배포할 수 있습니다. 이후 규칙을 트리거하고 애플리케이션을 실행하기 위해 새 IAM 정책을 생성합니다.

Serverless Application Repository에서 애플리케이션 배포

1. Serverless Application Repository에서 “Automated-IAM-policy-alerts-and-approvals“앱을 찾으세요.

2. 필요한 애플리케이션 설정을 완료하세요.

◆ 애플리케이션 이름 : 애플리케이션의 식별 가능한 이름입니다.

◆ EmailAddress(이메일 주소) : 승인 요청을 받기위한 관리자 이메일 주소입니다.

◆ limitedActions(제한 정책) : 제한하려는 IAM 정책 작업입니다.

3. 배포를 선택하세요.

그림 2 배포 필드

배포 프로세스가 완료되면 21 개의 새로운 리소스가 생성됩니다. 여기에는 아래 내용이 포함됩니다.

⊙ 비즈니스 로직을 포함하는 5 개의 Lambda 함수

⊙ Amazon EventBridge 규칙.

Amazon SNS 주제 및 구독.

⊙ 두 개의 리소스(Allow, Deny)가 포함된 Amazon API Gateway REST API.

⊙ AWS Step Functions 상태 머신

애플리케이션 관리자로서 Amazon SNS 알림을 받으려면 SNS 주제에 대한 구독을 확인해야합니다. 확인을 위해 애플리케이션을 배포할 때 전송 확인된 이메일에서 구독 확인 링크를 클릭합니다.

EventBridge는 디폴트 이벤트 버스에서 새 이벤트를 받습니다. 새로 받은 이벤트는 관련된 규칙과 비교됩니다. 각 규칙은 이벤트 패턴이 정의되어 있으며 새로 받은 이벤트를 해당 규칙에 매칭시키는 필터 역할을 합니다. 이 애플리케이션에서 매칭된 이벤트 규칙은 AWS Step Functions 실행을 트리거하여 정책 생성 이벤트에서 이벤트 페이로드(핵심 정보)를 가져옵니다.

■ 애플리케이션 실행

AWS Management Console 또는 AWS Command Line Interface(AWS CLI)를 통해 정책을 생성하여 애플리케이션을 트리거합니다.

AWS CLI 사용

먼저 AWS CLI를 설치구성한 후 다음 명령을 실행합니다.

[Bash]

aws iam create-policy --policy-name my-bad-policy1234 --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketObjectLockConfiguration",
                "s3:DeleteObjectVersion",
                "s3:DeleteBucket"
            ],
            "Resource": "*"
        }
    ]
}'

AWS Management Console 사용

​1. 서비스> IAM (Identity Access Management) 대시 보드로 이동하세요.

2. 정책 생성을 선택하세요.

​3. JSON 탭을 선택하세요.

​4. 다음의 JSON을 붙여 넣습니다.

[Js]
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketObjectLockConfiguration",
                "s3:DeleteObjectVersion",
                "s3:DeleteBucket"
            ],
            "Resource": "*"
        }
    ]
}

5. 정책 검토를 선택하세요.

6. 이름 필드에 my-bad-policy를 입력하세요.

7. 정책 생성을 선택하세요.

상기 2개의 명령은 Amazon S3 버킷을 삭제하는 데 필요한 권한이 있는 정책을 생성합니다. S3 버킷 삭제는 Serverless Application Repository에서 애플리케이션을 배포할 때 설정한 제한 Actions(작업) 중 하나입니다.

그림 3 디폴트 제한 Actions

위와 같은 정책 생성은 이벤트를 EventBridge로 전송한 다음 Step Functions 상태 머신을 트리거합니다. Step Functions 상태 머신은 Workflow의 각 상태 객체를 가지고 있습니다. 일부 상태 객체는 배포 중에 생성된 Lambda 함수를 사용하여 데이터를 처리합니다.

그 외의 상태 객체는 Amazon States Language (ASL)를 사용하여 애플리케이션의 조건에 따라 분기(branch), 대기(wait) 및 다음 상태로 전환(transition) 합니다. 상태 머신을 사용하면 비즈니스 로직과 컴퓨팅 기능이 분리됩니다.

애플리케이션을 트리거한 후 Step Functions 대쉬보드로 이동하여 새로 작성된 상태 머신을 선택한 뒤 실행 테이블에서 현재 실행중인 상태 머신을 선택합니다.

그림 4 상태 머신 실행

AskUser 상태에서 Workflow가 일시 중지된 현재 실행단계의 시각적 워크플로우가 표시됩니다.

그림 5 일시 중지된 Workflow

Workflow의 상태는 다음과 같습니다.

Modify Data (데이터 변형)

상태 유형 : Pass(통과)

입력 데이터를 Workflow 전체에 전달되는 객체로 재구성합니다.

ValidataPolicy (정책 인증)

상태 유형 : Task(작업), 서비스: AWS Lamda

제한된 조치에 대해 새 정책 문서를 확인하는 ValidatePolicy Lambda 함수를 호출합니다.

ChooseAction (작업 선택)

상태 유형 : Choice(선택)

ValidatePolicy 단계의 입력에 따라 분기(branch)합니다.

TempRemove (Temp삭제)

상태 유형 : Task(작업). 서비스: AWS Lambda

Amazon CloudWatch Logs에 대한 권한만으로 새로운 기본 버전의 정책을 생성하고 이전에 생성된 버전의 정책을 삭제합니다.

AskUser (사용자 질의)

상태 유형 : Choice(선택)

SNS를 통해 사용자에게 콜백 패턴을 시작하는 작업 토큰과 승인 이메일을 보냅니다.

UsersChoice (사용자 선택)

상태 유형 : Choice(선택)

사용자 Action인 승인 또는 거부를 기반으로 한 분기점(branch)입니다.

Denied (거부)

상태 유형 : Pass(통과)

추가 Action(작업)없이 실행을 종료합니다.

Approved (승인)

상태 유형 : Task(작업). 서비스: AWS Lambda

새로운 버전으로 생성함으로써 초기 정책 문서를 복구합니다.

AllowWithNotification (알림과 함께 허용)

상태 유형 : Task(작업). 서비스 : AWS Lambda

제한된 Action이 감지되지 않으면 실행이 끝나기 전에 SNS의 전자 메일을 통해 변경 사항을 사용자에게 계속 알립니다.

■ 콜백 패턴

이 애플리케이션의 중요한 기능은 관리자가 새로운 정책을 승인하거나 거부할 수 있다는 점입니다. Step Functions 콜백 패턴이 이를 가능하게 하죠. 콜백 패턴은 작업 중에 Workflow를 일시 중지시키고 외부 프로세스가 작업 토큰을 반환할 때까지 대기하도록 합니다. 작업 토큰은 작업이 시작될 때 생성됩니다. AskUser 함수가 호출되면 작업 토큰이 전달됩니다. 해당 작업 토큰은 승인 및 거부를 위한 API 리소스와 함께 SNS 주제에 게시됩니다. 이러한 API 리소스는 애플리케이션을 처음 배포할 때 생성됩니다.

관리자가 승인 또는 거부 링크를 클릭하면 API 요청이 있는 토큰을 receiveUser Lambda 함수로 전달합니다. 해당 Lambda 함수는 들어오는 작업 토큰을 사용하여 AskUser 상태를 재개합니다.

각 서비스를 통해 전환되는 작업 토큰의 수명주기는 다음과 같습니다.

​ 1. 이 콜백 패턴을 호출하기 위해 askUser 상태 정의는 .waitForTaskToken 식별자를 사용하여 선언(declared)되며 작업 토큰은 Lambda 함수에 페이로드 매개 변수로 전달됩니다. :

[Json]
"AskUser":{
 "Type": "Task",
 "Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
 "Parameters":{  
 "FunctionName": "${AskUser}",
 "Payload":{  
 "token.$":"$$.Task.Token"
  }
 },
  "ResultPath":"$.taskresult",
  "Next": "usersChoice"
  },

2. askUser Lambda 함수는 이벤트 객체 내에서 이 토큰에 액세스 할 수 있습니다.

[Js]
exports.handler = async (event,context) => {
    let approveLink = `process.env.APIAllowEndpoint?token=${JSON.stringify(event.token)}`
    let denyLink = `process.env.APIDenyEndpoint?token=${JSON.stringify(event.token)}
//code continues

3. 작업 토큰은 메시지 텍스트 매개 변수와 함께 SNS 주제에 게시됩니다.

[Js]
let params = {
 TopicArn: process.env.Topic,
 Message: `A restricted Policy change has been detected Approve:${approveLink} Or Deny:${denyLink}` 
}
 let res = await sns.publish(params).promise()
//code continues

4. 관리자는 두 개의 링크 (승인과 거부)가 포함된 이메일을 받습니다. 작업 토큰은 token이라는 요청 쿼리 문자열 매개 변수로 해당 링크에 추가됩니다.

그림 7 이메일 승인 / 거부

5. Amazon API Gateway 프록시 통합을 사용하면 작업 토큰은 API 리소스에서 recieveUser Lambda 함수로 직접 전달되고 이벤트의 queryStringParameter 객체의 일부로 함수 코드 내에서 액세스 할 수 있습니다.

[Js]
exports.handler = async(event, context) => {
//some code
    let taskToken = event.queryStringParameters.token
//more code

6. 이후 해당 토큰은 recieveUser Lambda 함수 내에서 API 호출을 통해 askUser 상태로 다시 전송됩니다. 또한 이 API 호출은 Workflow가 수행할 다음 작업 과정을 정의합니다.

[Js]
//some code 
let params = {
        output: JSON.stringify({"action":NextAction}),
        taskToken: taskTokenClean
    }
let res = await stepfunctions.sendTaskSuccess(params).promise()
//code continues

각 단계의 함수 실행은 최대 1년 동안 지속될 수 있으므로 관리자가 조치를 취할 수 있는 대기 시간이 길어집니다. 이 대기 시간 동안은 비용이 청구되지 않고 상태 전환 횟수에 대한 비용만 청구됩니다. 즉, 대기 시간이 길어져도 추가 비용이 발생하지 않습니다.

■ 결론

EventBridge를 사용하여 IAM 정책 생성 이벤트를 AWS Step Functions로 직접 라우팅하면 불필요한 통신 계층의 필요성이 줄어듭니다. 이렇게 하면, Lambda를 사용하여 데이터를 조정하거나 전송하지 않아도 데이터를 변환할 수 있어 컴퓨팅 리소스의 올바른 사용을 촉진합니다.

서비스를 순차적으로 호출하기 위해 Step Functions를 이용하는 것은 이 애플리케이션에 두 가지 중요한 이점이 있습니다. 1. 제한된 정책 사용을 빠르고 자동으로 식별할 수 있습니다. 2. 정책이 승인될 때까지 ‘보류 중’ 상태로 유지하거나 제거할 수 있습니다.

Step Functions Standard Workflow의 콜백 패턴은 관리자가 승인 또는 거부하기 전에 각 변경 사항을 검토할 수 있는 강력한 조정 계층을 만들 수 있습니다.

전체 코드 기반은 GitHub 리포지토리를 참조하세요. https://github.com/bls20AWS/AutomatedPolicyOrchestrator.

TAGS: automation, AWS Lambda, AWS Serverless Application Repository, Security, serverless, Step Functions

원문주소: https://aws.amazon.com/ko/blogs/compute/orchestrating-a-security-incident-response-with-aws-step-functions/

작성 : Benjamin Smith

번역 : 영업컨설팅2팀

홈페이지:​ www.didim365.com

페이스북 : https://www.facebook.com/didim365/

유튜브 : https://www.youtube.com/channel/UCYg7jSrU3sYDICSX5lb_7nw