본문 바로가기

Trip

AWS 요금 폭탄 경험기 - 5일간 2000만원

AWS라고 Amazon에서 제공해 주는 클라우드 서비스이다.

일반적인 BE(Backend) 개발자는 AWS를 이용해서 데이터를 저장하거나, 가상 서버를 임대하여 서버를 운용한다. 2000년 초반, 물리 서버가 있어야 했던 세상과는 다르다. 원하는 성능의 서버를 10분 이내에 만들어 사용할 수 있고, 딱 필요한 시간만 사용하고 종료할 수 있어 효율적으로 비용을 관리할 수 있다. 뿐만 아니라 내가 한국에 있지만, 미국 또는 유럽에서 서버를 개설하고 운용해야 하는 상황이라고 하더라도, 그 과정은 차이가 없다.

 

이렇게 손쉽게 자원을 관리할 수 있다는 것이 강력한 장점이지만, 충분한 이해가 없다면 비용관리 측면에서 치명적이다. 그 예를 이 글에서 적어보려고 한다.

 

2018년 6월 어느 금요일, 회사에서 약간 짬을 내어 진행하던 toy project에 작은 기능 개선 작업을 하고 퇴근을 했다. 여느 때와 다르지 않은 주말을 보내고, 월요일 오전. AWS 에게서 이메일 한 통을 확인했다.

 

Your AWS account ***** is compromised

문제 발견

모두 영어로 적혀있어 평소처럼 신경을 쓰고 싶지 않았다. 하지만 그러기에는 평소와 달리 이메일 내용이 무척이나 길었다. 그리고 느낌이 이상했다. 팔을 턱에 괴고 천천히 읽기 시작했다. 네이버 영어 사전에서 검색하기 전까지 compromised 가 칭찬하다는 뜻인 줄 알았다. (후에 알았지만 내가 헷갈렸던 단어는 compliment이다.)

 

 

내 계정이 안전하지 않다는 내용이었다. 이상하다 하며 AWS billing 페이지(https://console.aws.amazon.com/) 방문했다.

 

평소와 달리 Elastic Compute Cloud 항목에 Seoul region 뿐만 아니라 AWS가 접근 가능한 모든 Region에서 서비스가 열심히 돌고 있었다. 그냥 화면을 보고 있을 뿐인데 등에서 땀줄기가 흐르는 것을 느낄 수 있었고, 손가락이 떨려서 키보드 타이핑을 할 수 없었고, 마우스 클릭이 어려웠다. (다운된 회사 서비스 복구해야 했던 패닉의 순간이다.)

 

대응

스스로 이성적이라는 사람이라고 체면을 걸고, 생각하기 시작했다. 원인을 찾아야 하나, 문제부터 해결해야 하나. 사실 그 순간 계획하고 실행할 수 있는 마음의 여유는 없었다. 긴박한 순간 머릿속에 떠 오른 것은 지금이라도 줄줄 세고 있는 비용을 줄여야 한다는 것이다. 당장 EC2 console로 페이지를 클릭했다. 손이 떨려서 마우스 포인트가 해당 링크를 클릭하지 못하고, 두어 번 빈 여백을 클릭했다. 무사히 Seoul Region의 EC2 목록에서 20개의 Running 상태의 인스턴스가 눈에 보였다. 인정하고 싶지 않았지만, 각 인스턴스의 스펙이 너무 좋다. 일괄 선택 후 한 번에 종료(terminate) 하려고 했지만, 이런 termination protection 가 걸려 있어서 일괄 종료가 안된다. 인스턴스를 한 번에 하나씩 선택 후, termination protection을 disable 하고, 하나씩 terminate 시도해야 한다.  Seoul 지역에만 20개, 다른 지역 각각도 이 정도 숫자가 있으니 모두 200개가 넘어가는데 일일이 하려니 속이 탄다. 그 와중에 손가락 긴장이 풀리지 않아 허공에 클릭질은 줄어들지 않는다.

대략 한 시간이 걸렸다. 점심시간이었는데, 밥을 먹지 않았지만 배도 고프지 않고 온몸에 힘이 쭉 빠졌다. 긴박한 순간이었지만, 더 이상 부과되는 비용을 막을 수 있어 다행이었다.

 

2차 실수

다음 날 아침, 확인하는 마음으로 AWS billing 페이지에 접속해 보았다. 이제는 각 Region 별로 running instances 가 없어야 당연했다. 근데 웬일인가. 어제 데자뷔 같은 상황이 재현되었다. 꿈은 아니었다. 입에서 쌍욕이 나온다. 어제 그 짓을 반복해야 했다. 여전히 termination protection이 걸려있어, 일괄처리 진행을 할 수 없다.

나중에 알게 된 사실이지만, 어제 나는 문제를 제거했지만 원인을 그대로 두었던 것이다.

 

내가 저지른 실수 원인

지난 금요일 토이 프로젝트 진행 후, 코드 버전 관리를 위해 github에 최종 결과물을 push 했다. 민감한 개인 정보가 없을 꺼라 생각했다.

 

Django에서 AWS에서 자원에 접근할 때 필요한 정보가 있는데, 이 값을 보기 좋게 public github 저장소에 두었던 것이다.

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY

나 같은 실수를 하는 사람을 노리는 어둠의 자식들이 있는지, 누군가는 github에 코드를 실시간으로 감시하다 위와 같은 Key 값을 crawling 하여, 자원을 훔쳐 사용한다.  그들의 나쁜 의도롤 욕할 수 있겠지만 빌미를 만들어준 나도 책임이 없지 않다.

 

최종 비용

그래서약 5일간 $ 18K의 비용이 측정되었다.

AWS와 이메일 주고받으며 거의 구걸하다시피 살려달라고 했던 거 같다. 또 남들이 하는 얘기로 이와 같은 실수를 하는 사람들이 많은데, 처음 한 번 정도는 실수를 봐준다고 한다.

 

 

후기

공유차 서비스를 사용하는 개인 계정이 도용당하는 경우, 물리적으로 2대 이상은 대여가 불가능하다. 그린카 같은 곳에서 동시간에 3대의 차를 빌릴 수는 없으니까.

그렇지만 cloud 환경은 다르다. 논리적으로 허용 가능한 모든 자원이 임대 가능하다. 그러므로 더더욱 자원관리를 잘해야 하겠다. 반드시 MFA 적용하고, IAM 정책을 이용해 특정인에게 모든 권한이 집중되는 것을 막아야겠다.

 

 

반응형