엔지니어 지망생들이 모이는 커뮤니티에는 ‘공부를 위해 사용하던 AWS 계정에 갑자기 수백만 원의 요금이 청구되었다.’ 라는 무서운 사연이 심심찮게 올라옵니다. 이러한 수준의 요금 폭탄은 대체로 악의적인 사용자에게 권한을 탈취 당했을 때 일어납니다. 이번 포스팅에서는 악의적인 사용자로부터 AWS 계정을 보호하는 방법에 대해 소개합니다.
AWS에 처음 가입하였을 때 접속하게 되는 계정이 바로 루트 계정입니다. ‘큰 힘에는 큰 책임이 따른다.’ 라는 말이 있는데요. 루트 계정에게는 얼마나 큰 힘이 있을까요?
감당하기 어려울 정도로 큰 힘입니다. 작은 힘만 사용하고 작은 책임을 지는 방법에 대해 알아보도록 합시다.
패스워드 관리는 가장 기본적인 보안 대책입니다. 다른 인증 수단에 비해 유출에 취약하기 때문에 다음의 사항을 준수하도록 관리하여야 합니다.
멀티 팩터 인증이란 아이디와 패스워드 외의 확인 수단을 추가로 사용하는 인증 방식을 말합니다. AWS에서 MFA를 활성화 하면 기존의 아이디 패스워드와 함께 OTP(One-time password)를 정확하게 입력해야 계정을 사용할 수 있습니다. OTP는 30초마다 재생성되는 일회용 패스워드인데요. 패스워드만 사용하는 방식에 비해 어떤 장점이 있는지 살펴보도록 하겠습니다.
일반적인 패스워드는 다음의 요인들로 인해 해커에게 탈취될 가능성이 있습니다.
OTP를 함께 사용하면 패스워드의 취약점을 상당 부분 보완할 수 있습니다.
아이디와 패스워드는 AWS 웹 콘솔에 접속할 때 사용하는데요. CLI나 SDK를 사용하고자 할 때는 Access key와 Secret key가 각각 아이디와 패스워드의 역할을 대신합니다. 따라서 이 두 키를 탈취 당하면 아이디 패스워드를 넘겨준 것과 거의 동일한 효과가 있습니다. 다행히 Access key는 사용자가 따로 요청하지 않으면 생성되지 않으므로 아예 만들지 않는 것이 안전합니다.
누군가 루트 계정에 로그인 할 때마다 알림이 발생하도록 설정해두면 신속한 사후 대처를 할 수 있습니다. 알림을 구현하려면, AWS 클라우드 워치에 로그인 기록이 남을 때마다 메일이나 메시지를 송신하는 람다를 작성하면 됩니다. AWS 공식 블로그에 방법을 잘 설명해둔 글이 있어 링크를 남겨드리겠습니다.
Monitor and Notify on AWS Account Root User Activity
앞서 설명드린 기본적인 보호 방법을 적용하였다면, 루트 계정의 접속을 엄격히 제한하여야 합니다. 루트 계정의 대부분의 권한은 뒤에 설명할 IAM을 통해 다른 사용자에게 양도할 수 있습니다. 결제 설정 변경 등 꼭 루트 계정이 필요한 경우가 아니라면 아예 사용을 하지 말도록 합시다.
IAM은 Identity and Access Management의 약자로, 사용자나 리소스에 부여한 신원(Identity)에 맞는 권한만을 사용하도록 통제하는 서비스입니다. 회사의 임직원들은 소속과 직급, 즉 신원에 따라 필요한 권한이 다릅니다. 예를 들어 DB 관리자에게는 DB 수정 권한은 꼭 필요하지만, 쿠버네티스 클러스터에 대한 운영 권한은 없어도 됩니다. 반대로 쿠버네티스 엔지니어에게는 DB에 관련된 권한이 필요 없습니다. IAM을 이용하면 각 사용자에게 필요한 권한만 부여할 수 있습니다. 쉽게 말해 쿠버네티스 엔지니어의 계정이 탈취 당하더라도 DB는 공격 당하지 않게 할 수 있습니다.
어떤 종류의 권한을 부여할지 미리 정해놓은 것을 IAM 정책(Policy)라고 합니다. 예를 들어 ‘개발용 쿠버네티스 클러스터의 상태를 조회할 수 있다.’ 라는 정책이 있다고 합시다. 개발용 클러스터에만 권한이 있고 운영용에는 없습니다. 또 조회만 할 수 있지 수정, 삭제는 안 됩니다. 이런 것을 정해둔 것이 바로 정책입니다.
IAM의 신원은 크게 ‘사용자(User)’와 ‘역할(Role)’로 나눌 수 있는데요. 역할에 대한 설명은 뒤로 미뤄두고 사용자부터 살펴보도록 하겠습니다. 사용자란 AWS에 로그인 가능한 계정입니다. 아이디와 패스워드, 혹은 Access key와 Secret key를 이용해 로그인 해서 운영 작업을 수행합니다. 신원에 정책을 연결하는 것, 즉 ‘개발자 홍길동의 계정’이라는 신원에 ‘개발용 쿠버네티스 클러스터의 조회를 허용한다’ 라는 정책을 연결하는 것이 IAM 운영의 기본입니다.
IAM 사용자 계정도 루트 계정처럼 멀티 팩터 인증을 활성화 할 수 있습니다. 로그인 과정이 다소 귀찮아지지만 훨씬 안전합니다.
앞서 루트 계정의 Access key를 절대 발급하지 말라고 말씀드렸는데요. IAM 사용자의 발급까지 전면 제한하는 것은 무리입니다. 그러나 Access key를 꼭 발급하더라도 작업이 끝난 뒤 바로 삭제하는 것이 좋습니다. 앞서 말씀 드렸듯이, 유효한 Access key와 Secret key의 쌍이 유출됐을 때의 파급 효과는 계정 전체를 탈취 당했을 때와 거의 동일하기 때문입니다. 최대한 짧은 시간만 사용하는 것이 탈취 위험을 줄이는 방법입니다.
특히 Github과 같은 공개된 장소에 Access key와 Secret key를 게시하는 행동은 절대 하면 안 됩니다. 지금도 많은 해커들이 의도치 않게 게시된 Access key를 찾는 크롤러를 실행시키고 있습니다. Github에 키를 공개하는 순간 여러분의 계정은 해커들의 공공재가 될 것입니다.
운영 작업 중 권한 미부여로 인한 오류를 맞닥뜨리다보면, IAM 정책을 와일드카드(*)로 설정해 모든 권한을 부여받고 싶은 강한 유혹을 느낄 수 있습니다. 이런 행동은 루트 계정을 하나 더 만드는 것과 다를 바 없는 행동이므로 절대 금물입니다. 답답하더라도 작업에 필요한 최소한의 권한을 찾아 부여해야 합니다.
IAM 역할은 적합한 권한을 가진 사용자, 또는 리소스에게 일정 시간 동안만 유효한 Access key와 Secret key를 발급해주는 인증 방식입니다. OTP와 마찬가지로 유출이 되더라도 일정 시간이 지나면 만료되므로 더욱 안전합니다.
IAM 역할은 사용자에게도 부여할 수 있지만, 결국 역할을 부여받기 위한 인증 과정에서 Access key를 사용해야 하므로 한계가 있습니다. IAM 역할은 리소스에 부여하였을 때 그 진가가 드러납니다. 예를 들어 ec2 가상머신에 서비스를 배포하기 위해 s3의 파일을 다운로드 해야한다고 가정해봅시다. ec2에 s3의 다운로드 권한을 부여하면 Access key를 입력하거나 저장해두지 않아도 파일을 다운로드 받을 수 있습니다. 키를 입력하는 과정이 생략되므로 스크립트를 통한 자동화에 적합한 방식입니다.
클라우드 보안 사고는 감당하기 어려운 재정적 피해를 끼칠 수 있습니다. 악의적인 사용자의 침해가 명확한 경우 환불을 해주기도 하지만, 절차가 복잡하거니와 100% 구제 받을 수 있다는 보장도 없습니다. 미리 보안 정책을 수립하여 계정을 보호하는 것이 최선의 방법입니다.