목차

1️⃣ 서버 접근통제란
2️⃣ Session Manager란

2-1 계획
2-2 아키텍처

3️⃣ Session Manager 설정하기

3-1 사전 조건
3-2 엔드포인트 설정
3-3 EC2 설정
3-4 IAM 설정
3-5 S3 Logging 설정
3-6 로그 확인

4️⃣ 마치며


안녕하세요. 클라우드메이트 TE팀 이도현입니다.
AWS의 서비스 중 간편하게 서버 접근통제를 구현할 수 있는 Session Manager에 대해 공유하고자 합니다.
테스트하실 수 있게 핸즈온으로 구성했습니다.

서버 접근통제란

접근통제란 적절한 권한이 인가된 사용자만 해당 시스템에 접근할 수 있도록 하고, 권한이 없는 사용자는 접근하지 못하도록 통제하는 것입니다.
또한 인가된 사용자의 부인 방지를 위해 작업 이력에 대한 로깅을 할 수 있어야 합니다.

Session Manager란

간단하게 Session Manager의 기능에 대해 설명드리겠습니다.

Session Manager는 Systems Manager의 기능 중 하나로써,
EC2 인스턴스, 엣지 디바이스, 온프레미스 서버 및 가상 머신을 브라우저 기반 셸 또는 AWS CLI를 통해 관리할 수 있습니다.

또한 Session Manager는 4가지 장점이 있습니다.

  • 인바운트 포트를 열 필요가 없습니다.
  • Bastion 호스트를 사용하지 않습니다.
  • SSH 키를 사용하지 없습니다.
  • 세션 활동을 로깅 및 감사가 가능합니다.

로깅 및 감사 기능은 다음과 같은 AWS 서비스와의 통합을 통해 제공됩니다.

  • S3
  • CloudTrail
  • CloudWatch Logs
  • EventBridge 및 SNS

계획

1️⃣ 인터넷이 되지 않는 Private 환경을 구성합니다.
2️⃣ 특정 사용자만 특정 EC2 인스턴스에 접근이 가능하도록 합니다.
3️⃣ MFA 인증이 되지 않으면 접근하지 못하도록 합니다.
4️⃣ 사용자가 인스턴스에 접근할 때 접근 이력과 명령어 실행 이력이 로깅되도록 합니다.

IAM 정책을 이용하여 특정 사용자에게만 권한을 부여하고 특정 인스턴스에만 접근할 수 있도록 합니다.
또한 Session Manager의 장점을 좀 더 살리고 싶어 보안성을 높여 폐쇄망에서 사용하는 것을 전제로 하고 MFA 인증을 강제하였습니다.
그리고 인스턴스 내부의 명령어 실행 이력을 S3 버킷에 로깅하도록 하겠습니다.

아키텍처

편의상 User를 Admin으로 표시하였지만,
테스트 환경에서는 User A는 EC2-A에만 User B는 EC2-B에만 접근할 수 있도록 구성하겠습니다.

Session Manager의 작동 방식을 잠시 살펴보겠습니다.
사용자가 세션을 시작하라는 첫 번째 명령을 보내면, Session Manager 서비스에서 사용자의 ID를 인증하고, IAM 정책에 따라 사용자에게 부여된 권한을 확인한 다음 구성 설정을 확인하고, SSM Agent에 양방향 연결을 열라는 메시지를 보냅니다.
연결이 설정되어 사용자가 다음 명령을 입력하면 SSM Agent의 명령 출력이 이 통신 채널로 업로드되고 다시 사용자의 로컬 시스템으로 전송됩니다.

Session Manager 설정하기

이 글에서는 VPC를 생성하는 설명은 생략하도록 하겠습니다.
실습을 진행하는 환경은 인터넷 게이트웨이 또는 NAT 게이트웨이가 없는 프라이빗 서브넷에서 이루어집니다.

사전 조건

Session Manager 사용을 시작하기 전에 환경이 다음 요구 사항을 충족하는지 사전 조건을 확인해 보아야 합니다.

1️⃣ 지원되는 운영체제인지 확인

2️⃣ 관리형 노드에 SSM Agent가 설치되어 있는지 확인

3️⃣ 엔드포인트에 연결

  • ec2messages.region.amazonaws.com
  • ssm.region.amazonaws.com
  • ssmmessages.region.amazonaws.com
  • s3.region.amazonaws.com
    • S3 로깅을 위한 게이트웨이 엔드포인트 추가

ec2messages, ssm, ssmmessages의 엔드포인트를 생성하는 것은 Private 환경에서 사용하기 위한 필수 조건입니다.
여기서는 S3 버킷에 로깅하기 위해 S3 게이트웨이 엔드포인트까지 추가적으로 생성하겠습니다.

엔드포인트 설정

3가지 서비스에 대해 엔드포인트 생성을 한 후에, 해당 엔드포인트들의 보안 그룹에 HTTPS 인바운드 트래픽을 허용해 줘야 합니다.

먼저 엔드포인트용 보안 그룹을 생성하겠습니다.

인바운드 규칙에 자신의 VPC 대역을 소스로 두고 443 포트를 허용해 줍니다.

엔드포인트 3개를 각각 하나씩 생성합니다.


위에서 만든 엔드포인트용 보안 그룹을 적용해 줍니다.

위와 같은 방법으로 ec2messages, ssm, ssmmessages 엔드포인트를 생성합니다.

S3 게이트웨이 엔드포인트도 생성합니다.

EC2 인스턴스가 존재하는 서브넷이 연결되어 있는 라우팅 테이블을 선택합니다.

필요한 엔드포인트를 모두 생성하였습니다.

EC2 설정

먼저 EC2용 보안 그룹을 생성하겠습니다.

아웃바운드 규칙은 interface 엔드포인트들이 포함되어 있는 서브넷 대역에 443 포트를 허용합니다.
로깅을 위해 s3 게이트웨이 엔드포인트를 대상으로도 443 포트를 허용합니다.

다음으로 프라이빗 서브넷에 EC2 인스턴스를 생성합니다.

인스턴스를 생성할 때 네트워크 설정 > 기존 보안 그룹 선택 > 위에서 만든 EC2용 보안 그룹을 선택합니다.

특정 사용자만 특정 인스턴스에 접근하는 것을 테스트하기 위해 2대의 인스턴스를 생성했습니다.

그리고 세션 매니저를 사용하기 위해 EC2에 IAM Role을 설정해 주어야 합니다.
IAM > 역할 > 역할 생성을 통해 설정합니다.


AWS 관리형 정책인 Amazon SSM Managed Instance Core를 꼭 포함시켜야 합니다.
이 관리형 정책은 Systems Manager 서비스 핵심 기능을 사용하도록 설정하는 EC2 역할 정책입니다.
그리고 해당 역할에 인라인 정책을 추가하여 EC2 인스턴스가 로깅할 특정 S3 버킷에 쓰기 권한을 갖도록 설정합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LoggingS3",
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::[YOUR_S3_BUCKET_NAME]/*"
        }
    ]
}

다시 EC2 콘솔로 돌아와 EC2 인스턴스 2대 모두 IAM 역할을 수정해 줍니다.
해당 EC2를 선택 후 작업 > 보안 > IAM 역할 수정을 클릭하여 위에서 만들어두었던 IAM 역할을 선택한 후 IAM 역할 업데이트를 클릭합니다.

IAM 역할 업데이트를 진행했다면 꼭 해당 인스턴스를 재부팅해 줍니다.

IAM 설정

IAM 사용자 2명을 추가해 줍니다.

  • dohyeon_A
  • dohyeon_B

그리고 각각 새로 정책을 생성 후 사용자에게 권한을 추가해 줍니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession"
            ],
            "Resource": [
                "arn:aws:ec2:[region]:[YOUR_ACCOUNT_NUMBER]:instance/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ssm:resourceTag/[KEY]": [
                        "[VALUE]"
                    ]
                },
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession",
                "ssm:ResumeSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/${aws:username}-*"
            ]
        }
    ]
}

Condition의 ssm:resourceTag/[KEY][VALUE]는 사용자가 접근하고자 하는 EC2 인스턴스의 태그 Key와 Value를 뜻합니다.
aws:MultiFactorAuthPresenttrue로 설정하여 MFA 인증을 해야 접근할 수 있도록 합니다.

그리고 추가적으로 두 사용자 모두 동일한 정책을 추가하여 MFA 디바이스를 삭제하거나 추가하고 패스워드를 바꿀 수 있도록 설정합니다.
또한 로그인 후 MFA 인증을 하지 않으면 나열해놓은 서비스를 제외하고는 접근할 수 없도록 설정합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": [
                "iam:ListVirtualMFADevices",
                "iam:ListUsers",
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowChangeOwnPasswordsOnFirstLogin",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:GetUser"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowChangeOwnPasswordsAfterMFAEnabled",
            "Effect": "Allow",
            "Action": [
                "iam:GetLoginProfile",
                "iam:UpdateLoginProfile"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:mfa/${aws:username}"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken",
                "iam:ListUsers",
                "iam:ChangePassword"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

S3 Logging 설정

Systems Manager > 세션 관리자 > 기본 설정 > 편집을 클릭하여 S3 logging 설정을 합니다.

로그 확인

이후 생성한 사용자에 로그인 후 MFA 디바이스 할당을 합니다.
로그아웃 후 MFA 인증을 하여 재로그인을 합니다.

접근하고자 하는 EC2 인스턴스에 SSM을 통해 접근해 보고, 다른 인스턴스에도 접근하여 테스트해 봅니다.

로깅 설정을 했던 S3 버킷에서 로그를 확인합니다.

해당 로그를 다운로드해 확인해 보면 명령어 실행 이력과 결과를 확인할 수 있습니다.

마치며

Session Manager는 EC2 인스턴스에 접근할 때 추가 요금이 발생하지 않습니다.
하지만 프라이빗 환경에서 사용하기 위해 생성한 인터페이스 엔드포인트가 시간당 0.013 달러이므로 3개의 엔드포인트를 생성하였으니 시간당 0.039 달러가 청구되긴 합니다.

사실 서버 접근통제를 위한 다양한 3rd Party 솔루션이 존재할 것입니다.
하지만 AWS를 사용하는 고객이라면 Session Manager로 보다 간편하게 설정 및 관리하며, 비용 측면에서도 이점을 누리는 것이 어떨까요?

긴 글 읽어주셔서 감사합니다. 🙂