들어가며
NestJS와 PostgreSQL, TypeORM을 활용하여 프로덕트를 만들고 있습니다. 프로덕트가 성장하면서 AWS 콘솔에 접근해야 하는 팀원이 조금씩 늘었습니다. 팀원들이 보다 안전하게 AWS 콘솔에 접근할 수 있는 환경을 구성하고 싶었습니다. 이를 위해 MFA 인증을 등록해야만 AWS 콘솔에 접근할 수 있도록 환경을 구축했습니다. 그럼 AWS 콘솔에 처음 접근하는 사용자에게 MFA 설정을 강제하려면 어떻게 해야 하는지 공유해 보려 합니다.
MFA
MFA는 사용자가 계정에 로그인할 때 패스워드 입력 후 OTP와 같은 추가적인 인증 단계를 거쳐 보안을 강화하는 기술입니다. MFA를 활용하면 계정에 대한 무단 접근을 방지하고 보안을 강화할 수 있습니다. AWS는 고객의 데이터를 보호하기 위해 다양한 보안 기능을 제공하고 있습니다. 그중에서도 MFA는 계정 보안 강화에 매우 중요한 역할을 수행합니다. 이를 통해 계정에 대한 무단 접근을 방지하고, 악의적인 공격자로부터 계정이 탈취될 수 있는 위험에서 크게 벗어날 수 있습니다.
MFA 강제화를 위해 다음의 두 가지를 만족하는 IAM이 필요합니다.
- IAM 사용자가 MFA 인증을 하지 않은 경우에는 AWS 서비스를 이용할 수 없도록 제한한다.
- IAM 사용자가 자신이 직접 MFA를 등록할 수 있도록 권한을 부여한다.
그럼 위와 같이 동작할 수 있도록 IAM 설정을 어떻게 적용해야 할지 알아보겠습니다.
적용 방법
먼저 IAM 사용자가 MFA 인증을 하지 않은 경우에는 AWS 서비스를 이용할 수 없도록 제한하고, IAM 사용자가 자신이 직접 MFA를 등록할 수 있도록 권한을 부여하기 위해 정책을 생성하겠습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowManageOwnPasswords",
"Effect": "Allow",
"Action": [
"iam:GetAccountPasswordPolicy",
"iam:ChangePassword",
"iam:GetUser"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "ViewAndUpdateAccessKeys",
"Effect": "Allow",
"Action": [
"iam:UpdateAccessKey",
"iam:CreateAccessKey",
"iam:ListAccessKeys"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:ListMFADevices"
],
"Resource": [
"arn:aws:iam::*:mfa/*",
"arn:aws:iam::*:user/${aws:username}"
]
},
{
"Sid": "AllowIndividualUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ResyncMFADevice"
],
"Resource": [
"arn:aws:iam::*:mfa/*",
"arn:aws:iam::*:user/${aws:username}"
]
},
{
"Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice"
],
"Resource": [
"arn:aws:iam::*:mfa/*",
"arn:aws:iam::*:user/${aws:username}"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"iam:GetUser",
"iam:ChangePassword",
"iam:UpdateAccessKey",
"iam:CreateAccessKey",
"iam:ListAccessKeys"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
정책을 요약하면, MFA 인증을 받지 않는 유저는 패스워드 변경과 MFA 등록에 필요한 권한 이외의 서비스는 이용할 수 없도록 하는 것입니다. 저는 이 정책의 이름을 MFA라고 설정했습니다.
IAM 사용자 그룹 생성
그 후 MFA라는 사용자 그룹을 생성하고 그룹에 방금 위에서 생성한 정책을 추가하겠습니다.
권한 정책에 MFA가 등록됐다면 그룹에 추가할 사용자를 생성합니다.
사용자 생성
AWS Console을 활용할 사용자를 생성할 때 비밀번호를 임시로 입력하고, 계정을 사용하는 구성원이 비밀번호를 직접 설정할 수 있도록 ‘사용자는 다음 로그인 시 새 암호를 생성해야 합니다’를 선택하여 생성합니다.
그 후 정책이 추가된 사용자 그룹에 사용자를 추가하여 MFA 정책을 적용시킵니다. 그럼 방금 생성한 사용자 정보를 활용해서 AWS 콘솔에 접근하겠습니다.
사용자 로그인
AWS 콘솔에 처음 로그인하면, 사용자가 직접 자신의 비밀번호를 등록할 수 있는 화면이 나옵니다. 여기서 새로운 비밀번호를 설정해 줍니다.
만약 MFA 권한 정책 설정이 제대로 안되면, 패스워드 변경 시 ChangePassword 권한이 없다는 이유로 새로운 비밀번호를 입력할 수 없는 문제가 나올 수 있습니다. 이런 화면이 나오지 않는다면 AWS 콘솔로 접근했을 것입니다.
일단 사용자의 MFA 설정을 하지 않고, 특정 AWS 서비스를 이용해 보겠습니다. 접근했을 때, 접근할 수 있는 권한이 없기에 서비스를 이용하지 못하는 것을 확인할 수 있을 것입니다. 그럼 다음으로 넘어가서 MFA를 등록했을 때 서비스를 활용할 수 있는지 확인해 보겠습니다.
MFA 추가를 위해 IAM으로 들어갑니다. 그 후 MFA 추가 버튼을 클릭합니다.
MFA 디바이스를 어떤 것으로 활용할 것인지 선택합니다. Authenticator app을 선택합니다.
iOS의 경우
안드로이드의 경우
위 앱을 설치해서 MFA device를 등록하겠습니다.
앱 설치 후 등록을 완료하면 위와 같이 나옵니다. 이렇게 설정이 완료되면 로그아웃 후 다시 로그인합니다.
재 로그인 후, MFA 인증까지 거치고 나서 다시 AWS의 특정 서비스를 이동합니다. 저는 사용자에 MFA 등록 정책뿐 아니라 AWS Athena에 접근할 수 있는 권한을 추가했기 때문에 서비스에 접근할 수 있는 권한이 생긴 것을 확인했습니다. 이 과정을 통해 MFA를 등록하지 않은 유저는 AWS의 자원에 접근할 수 없도록 구성할 수 있습니다.
마치며
공부를 하며 그동안 아주 기초적인 것들을 제대로 공부하지 않았다는 것을 깨닫습니다. 좋은 기술을 배우는 것도 좋지만, 기술의 기반이 되는 기초적인 지식을 먼저 쌓는 것이 중요하다는 것을 다시금 깨달았습니다. 기초가 튼튼한 개발자가 되고 싶습니다.
출처
'Project > 서버 개발' 카테고리의 다른 글
[Project] 프로젝트 삽질기63 (feat 나이스 인증 1) (0) | 2024.06.24 |
---|---|
[Project] 프로젝트 삽질기62 (feat sentry 잘 활용하기) (0) | 2024.05.19 |
[Project] 프로젝트 삽질기60 (feat aws-vault) (0) | 2024.05.15 |
[Project] 프로젝트 삽질기59 (feat transactional outbox) (0) | 2024.05.06 |
[Project] 프로젝트 삽질기58 (feat Transactional) (0) | 2024.04.21 |