← Home

아이즈원 프라이빗 메일 백업의 계보 - 1편

#오픈소스 #생태계 #아이즈원 #크롤링 #저작권 #파이썬
By 탐정토끼(Taehee Kim)
↑ 맨 위로

한 오픈소스 생태계의 발전과 계보를 기록하다.

이 수상한 제목을 누르고 들어오신 손님 여러분, 환영합니다. 먼저 이 시리즈를 읽으시면 무엇을 얻어가실 수 있을지 이야기해보려 합니다.

아이즈원 프라이빗 메일은 팬 전용 유료 SNS 입니다.

아이즈원 프라이빗 메일 광고. 일본 느낌이 물씬 풍기는 디자인이다.

아이즈원 프라이빗 메일(이하 "프메")은 팬 전용 유료 구독 SNS 서비스입니다. 아이즈원이 데뷔한 직후인 2019년 초부터 해체한 2021년 4월 27일까지 아이즈원 멤버들이 팬들에게 메일을 보내주는 형식으로 운영됐습니다. 광고에서 일본 스타일을 느끼셨다면 정확합니다! 원래 AKB48에서 운영하던 서비스를 그대로 아이즈원에서 사용했거든요.

다양한 배경을 가진 개발자들, 복잡한 기술적 도전

아이즈원 프메 백업 뷰어는 팬들이 자발적으로 시작한 프로젝트들입니다. 파이썬, JQuery부터 스벨트, 안드로이드, 플러터, Go까지 다양한 기술 스택을 가진 개발자들이 서로 다른 방향으로 백업 툴과 뷰어를 만들었습니다. 저희 개발자들은 현생과 서비스 종료라는 시간의 압박 속에서 다양한 이슈들을 해결해야 했습니다. 한국에서 해외까지 수 많은 실 사용자들에게 피드백이 들어왔고... 대부분은 프로그램은 커녕 컴퓨터도 잘 모르는 사람들이었죠.

발전 : 사용성을 개선하고, 성능을 최적화하기

처음에는 사용자가 직접 fiddler같은 프록시 서버를 띄우고 설정해야하는 불편한 구조였습니다. 하지만 일반인 사용자들은 파이썬 설치도 어려워했죠. 그래서 개발자들은 여러 자동화 스크립트를 발전시켰고, 결국 아이디와 비밀번호만 입력하면 될 수준으로 간단해졌습니다.

백업 시간도 처음에는 파이썬 순차 요청으로 1~3시간이 걸렸지만, 최종적으로는 Go + 비동기 병렬성을 이용해 3분까지 단축했습니다.

하지만 이러한 저희의 도전은 아이즈원 팬덤인 위즈원 커뮤니티 만의 이야기였고요. 개발자들조차 다른 프로젝트들이 어떻게 진행되어왔는지는 잘 몰랐습니다.

누구도 모르는 한 오픈소스 생태계의 역사

최근에 Hyun-woo Park(@lqez) 님과 오픈소스 생태계에 대해 대화를 나눴습니다. 어쩌다가 아이즈원 프메 백업 뷰어에 대해 약간 이야기를 들려드렸는데요. 흥미로워하시면서 "이게 오픈소스 아닌가요?"라며 글로 써보는 게 어떻겠냐고 제안을 주셨습니다. 매주 월요일마다 글을 쓰기로 약속까지 받아내셨죠.

생각해보면 이 글을 쓰기에 저만큼 괜찮은 사람도 없었습니다. 우연히 이 프로젝트의 초창기부터 참여해왔고요. 두 번째로 사용자가 많은 프메 백업 뷰어를 만들었습니다. 최근에 서로 다른 뷰어들의 데이터를 호환시키는 프로젝트를 하고, 개발자님들과 대화하면서 이런저런 내막을 들을 수도 있었죠. 무엇보다 현업으로 바쁜 다른 분들에 비하면, 저는 코칭을 하면서 나름 여유롭게 살고 있습니다.

전에도 프메 백업 뷰어 이야기를 쓴 적은 있지만, 그건 제 개인적인 감정이나 소감 정도였습니다. 이 시리즈에서는 이 생태계가 어떻게 발전해왔는지, 오픈소스의 관점에서 이야기해보려 합니다. 다양한 기술적 난관과 해결책은 어떻게 보면 엉성해보이실 수도 있고, 어떤 면은 놀라우실 수도 있으리라 생각합니다. 부디 도움이 되길 바랍니다.

여튼 그러한 이유로 앞으로 매주 월요일마다 글을 올리려 합니다. 5부작 정도로 계획하고 있습니다.

이야기는 한 카이스트 대학생으로부터 시작합니다.

태초에 Payload와 Python이 있었다.

아이즈원이 해체를 공식 발표하다.

Mnet은 10일 오후 보도자료를 통해 아이즈원의 프로젝트 종료를 공식 발표했다.

때는 2021년 3월 10일. 아이돌 그룹 아이즈원과 팬덤 위즈원은 3월 13일, 14일에 진행될 온라인 콘서트 [One, The Story]를 기다리고 있었고, 언론을 통해 아이즈원 해체 결정이 공식 발표되었습니다.

위즈원 팬덤이 어떻게 반응했으며, 무슨 분투가 있었는지는 저희의 관심사가 아닙니다. 아이즈원은 결국 4월 27일 최종적으로 해체했습니다.

"자기 책임 하에 백업합니다."

자연스럽게 프메 서비스도 종료하게 되었습니다. 운영팀은 자체 백업 기능을 제공하지 않았습니다.

(22) 당사는 고객 정보 및 콘텐츠 저장 의무를 부담하지 아니하며, 그 완전성, 가용성에 대해 보증하지 아니합니다. 고객은 고객 정보 및 콘텐츠를 보전하고자 할 경우, 자기 책임 하에 백업합니다.

그러면 저희에게 어떤 방법이 있었을까요?

"수작업으로 스크린샷 찍어야 하나요..."

제목 : 프메 어떻게 백업하나요. 정말

일일히 수작업으로 스크린샷 찍어야 하나요...

익명의 누군가

사람들은 프메 데이터를 보존하기 위해서 '수동 백업'을 선택했습니다. 8천 장이 넘는 메일과 사진을 하나하나 스크린샷으로 찍어 보존하려 했죠. 이 단순 반복 노동에 수 많은 사람이 포기한 것은 둘째치고, 스크린샷은 용량이 어마어마했습니다. 열람이나 검색이 불편한 것도 있었고요.

백업 데이터 저장소 : 방주 IZ*ARK

위즈원 팬덤은 이런 사태를 전부터 예상하고 있었습니다. 프로젝트 그룹인 IOI나 Wanna One도 계약기간이 끝나자마자, 해체했으며. 재결합 시도가 있었으나 무산되었으니까요. 아이즈원은 괜찮은 성적을 냈지만, 안준영 PD의 투표 조작 사건을 겪으면서 몇 번이나 해체위기를 겪었었습니다.

위즈원 팬덤은 아이즈원이 데뷔할 때 이미 IZ*ARK 이른바 '방주'라는 공유 구글 드라이브를 만들어, 모든 아이즈원의 활동을 기록하고 보존해왔습니다. 이 방주는 여전히 SPACE*IZ (허브홈)에서 운영 중 입니다. 공식 SNS와 활동한 모든 글과 이미지, 영상을 보존하고 있습니다.

방주의 폴더들 트위터, 틱톡, 인스타, 페이스북, 유튜브 등등 모든 SNS와 활동 자료들이 모여 있다.

그 방주 사이트의 구글 드라이브 연동, 인증 시스템을 개발한 사람이 바로 첫 번째 이야기의 주인공인 Payload(aka 페이좌) 입니다.

보안을 공부하던 카이스트 대학생은 방주 사이트 개발팀이 되는데...

공개된 정보만 이야기하자면 페이님은 부산 과학고를 졸업한 카이스트 대학생으로, 원래는 보안 쪽에서 활동하시는 해커이신 모양입니다.

원래는 DC인사이드의 아이즈원 멤버들 갤러리에서 활동하셨다고 합니다. 19년에는 팬 서포트를 위한 작은 플랫폼을 만들었는데요. 이게 방주 관리자인 똘배님의 눈에 띄어서 2019년 방주 개발팀에 합류하셨다고 합니다. 앞서 말씀드렸듯 구글 드라이브 연동을 통해 각종 백업 데이터를 관리하는 일을 해오신 거죠. 출처

보안 쪽 지식 + 백업 사이트 개발을 합치면 어떻게 프메 백업의 아이디어를 떠올리셨을지 예상이 갑니다.

프록시 서버를 이용한 아이즈원 프메 백업 스크립트

정신 차리니 거대해져버린 이 프로젝트의 시작은, 너무나도 작은 프로젝트였습니다 사용자가 HTTPS 프록시를 이용해서 모든 정보를 추출해내고, 사용법도 안 적혀 있던 참 단순하고, 불친절한 스크립트였습니다.

IZPM 프로젝트 후기 중에서 - 페이

저(탐정토끼)는 당시에 이곳저곳 뒤지던 중에 이 초창기 파이썬 스크립트를 발견했습니다. 저도 처음에는 이게 도대체 뭐하는 건가 싶었는데요. 여러분이 웹에 대한 지식이 없다고 가정하고, 그 원리를 설명해보고자 합니다.

앱은 서버에게 HTTP 요청을 보냅니다.

프메는 안드로이드와 IOS에서 돌아가는 모바일 앱입니다. 하지만 내부적으로는 WebView를 이용한 웹 앱으로 되어 있죠.

HTTP 서버의 개념도

출처 : MDN : 웹 서버란 무엇일까?

위 그림은 웹 브라우저와 HTTP 서버가 통신하는 모습을 그림으로 그려본 겁니다. 브라우저(저희는 모바일 앱)가 HTTP 규약에 맞춰서 요청(Request)을 보내면, 서버는 응답(Response)하면서 JSON 데이터나 파일을 돌려줍니다.

프메 앱도 똑같습니다. 프메 API 서버에 JSON으로 된 메일 목록을 요청해서 보여줍니다. 각 메일을 클릭하면 CDN 서버에서 HTML 파일과 이미지를 불러옵니다. 예를 들어 JSON 파일은 이렇게 생겼습니다.

{'mail_count': 20,
 'page': 1,
 'has_next_page': True,
 'unread_count': 1129,
 'star_count': 30,
 'mails': [{'member': {'id': 12,
    'name': '깃털채연',
    'realname_ko': '이채연',
    'realname_th': 'LEE CHAE YEON',
    'realname_in': 'LEE CHAE YEON',
    'image_url': 'https://img.izone-mail.com/artist/profile/starship/202010211113/d43bd42aa098239c7653b35c79e66d8c.jpg'},
   'group': {'id': 3, 'name': 'IZ*ONE'},
   'id': 'm00000',
   'subject': '21/3/27_제목',
   'subject_ko': '21/3/27_제목',
   'subject_in': '21/3/27_제목',
   'subject_th': '21/3/27_제목',
   'content': '메일의 첫 문장이 들어있었는데 마스킹했어요.',
   'content_ko': '메일의 첫 문장이 들어있었는데 마스킹했어요.',
   'content_in': '메일의 첫 문장이 들어있었는데 마스킹했어요. 인도네시아어 지원 같은 거 없고 한국어에요.',
   'content_th': '메일의 첫 문장이 들어있었는데 마스킹했어요. 태국어 지원 같은 거 없고 한국어에요.',
   'receive_time': '20:50',
   'receive_datetime': '2021-03-27 20:50:09',
   'detail_url': 'https://app-web.izone-mail.com/mail/m00000',
   'detail_url_ko': 'https://app-web.izone-mail.com/mail/m00000',
   'detail_url_in': 'https://app-web.izone-mail.com/mail/m00000',
   'detail_url_th': 'https://app-web.izone-mail.com/mail/m00000',
   'is_unread': True,
   'is_star': False,
   'is_image': True},

   ... (계속)

문제는 간단해졌습니다. 서버에 메일 목록 JSON과 HTML, 이미지를 HTTP 요청해서 파일로 저장하는 프로그램을 만들기만 하면되는 거죠. 페이님은 파이썬의 Requests 라는 라이브러리를 사용했습니다.

하지만 여기서 보안이 우리를 가로 막습니다.

access-token을 이용한 사용자 인증

만약에 이렇게 허술한 방식으로 앱을 만든다면... 결제하지 않은 사람도 누구나 서버에서 데이터를 빼갈 수 있을 겁니다. 그래서 대부분의 앱은 로그인과 인증을 요구하는데요. 프메 앱은 access-token을 이용한 방식을 활용하고 있었습니다.

사용자가 로그인을 하면 토큰을 발급합니다. 그 후로 서버에 요청을 할 때마다 HTTP 헤더에 access-token을 달아주면, 서버에서는 토큰을 확인하고 데이터를 내어줍니다. 토큰이 없거나 잘못됐다면 접근을 금지시키죠.

나중에 이야기할 프록시 서버로 HTTP 요청을 뜯어보면 이렇게 토큰이 있습니다.

PATCH /v1/application_settings HTTP/1.1129
Host: app-api.izone-mail.com
(중략)
Accesss-Token: 1235ozrlga156156aneiqfqm <- 이게 토큰입니다.
(이하 생략)

그러면 이 토큰만 있으면 되겠네요? 여전히 문제가 있습니다. 일반 웹 페이지는 F12만 눌러도 편하게 이런 HTTP 요청을 뜯어볼 수 있는데요. 반면에 안드로이드나 아이폰 앱은 (당연하게도) 이런 HTTPS 요청을 뜯어볼 방법이 원래 없습니다. 웹 브라우저가 아니라 앱이니까요.

이 토큰 하나를 얻기 위해 앞으로 수 많은 개발자들이 삽질을 하게 됩니다. 먼저 첫 번째 해법부터 만나보시죠.

토큰을 낚아채는 프록시 서버

피들러를 실행한 화면. 메뉴들과 요청한 url 목록이 보인다.

페이님은 보안 쪽 배경이 있으시다고 했죠. 웹 보안 쪽에서는 Fiddler나 Burp같은 HTTP/HTTPS 프록시 서버를 많이 이용합니다. 이 프록시는 실제 서버 사이에서 요청을 가로채는 가짜 서버인데요. 이걸 나쁜 해커가 시도하면 우리의 소중한 보안 토큰과 개인정보를 가로챌 수도 있습니다. (이걸 중간자 공격이라 합니다.) 하지만 착한 해커들에게는 이런 요청을 뜯어보고 공부하기 위한 소중한 도구입니다. 사실 그 외에도 인터넷 연결이 잘 안 되는 지역이라던가, 많은 곳에서 유용한 목적으로 프록시 서버를 이용하고 있어요.

컴퓨터에서 피들러나 버프 프록시 서버를 다운 받아서 실행하면, 특정 포트에서 서버가 대기하고 있게 됩니다. 이제 핸드폰의 와이파이 설정에서 내 컴퓨터의 서버와 포트에 수동으로 프록시를 연결해주면... 이제 앱이 인터넷으로 보내는 모든 요청을 가로채서 볼 수 있게 됩니다. 자세한 방법은 이런 설명글을 읽어보시거나, 인터넷에 검색해보세요.

아직 HTTPS 인증서가 남았다.

하지만 앞에서 말씀드린 것처럼 수상한 프록시 서버는 중간자 공격에 이용될 수 있어요. 프록시 서버는 HTTP 요청은 뜯어볼 수 있지만, 암호화된 HTTPS 요청을 낚아채려면 프록시 서버의 인증서를 다운 받아서 신뢰한다고 설정해줘야 합니다.

여기서 다시 한 번 보안정책이 발목을 잡는데요. 최신 안드로이드 앱은 기본적으로 사용자가 등록한 인증서를 신뢰하지 않습니다. 그러니 사용자 인증서를 등록하려면 여러 꼼수를 써야했어요. 저는 이리저리 고민하다가 인터넷을 뒤져보고, 안드로이드 에뮬레이터에 시스템 인증서로 삽입하는 방식을 사용했습니다.

준비 끝! 백업 시작!

토큰을 확보했다면 준비는 끝났습니다. 처음에 말했듯이 서버에 요청을 보내서 파일을 다운로드 받으면 되는 것이죠. 초창기 버전의 스크립트인 pm.py를 이용해서 저도 백업을 했습니다.

초기 프로토타입인 만큼 이 친구는 단순했습니다. for문을 돌리면서 메일 목록을 불러오고요. 이렇게 다운 받은 목록은 불필요한 부분은 날려버리고, 필요한 부분만 json 형식으로 저장합니다. 메일 목록을 다 불러오면 다시 for문을 돌리면서 각 메일의 HTML과 이미지를 다운 받았습니다.

백업된 output 폴더 사진

백업된 폴더 사진

백업된 메일 html 파일들

메일 html 파일들

JQuery 내장 뷰어

페이님은 JQuery와 iframe을 이용해서 단순한 HTML 뷰어도 같이 만들어 제공했습니다. 나름 예쁜 디자인으로 메일 파일을 열람해서 볼 수 있었습니다. 내장 뷰어 사진

멋진 성과였습니다. 이제 손으로 하나하나 스크린샷을 찍을 필요가 없었습니다. 보안과 웹에 대한 지식을 활용해서 백업 과정을 자동화했으니까요. 메일은 모두 json과 HTML 파일이었기 때문에 용량도 8mb 정도 밖에 되지 않았습니다. (물론 이미지는 1기가를 넘었지만. 스크린샷은 8기가가 넘었습니다!)

과연 일반인이 프록시 서버를 쓸 수 있을까?

하지만 여러 한계가 있었고, 이는 다른 개발자들과 페이님 스스로도 새로운 백업툴과 백업 뷰어를 만들기 시작하는 계기가 됩니다.

당장 문제는 이게 너무 어렵다는 거였어요! 일반인이 프록시 서버를 설치하고, 와이파이 프록시를 설정하고, 인증서까지 설정... 할 수 있을까요? 설명서에는 다음 한 줄만 적혀 있었거든요.

  1. Burpsuite, Fiddler와 같은 HTTPS 프록시를 사용하여, 프라이빗 메일 패킷을 캡쳐합니다.

이게 일반인은 물론이고 프로그래머도 구글링과 삽질을 해야 겨우 가능한 일이었죠. 저도 첫째날에 실패해서 2차 시도 만에 성공했습니다. 프메 백업 스크립트를 만들었지만, 몇 명 밖에 성공한 사람이 없는 상황이었습니다.

다음 글에서는 개발자들이 어떻게 프메 백업을 쉽게 만들었는지 이야기해보겠습니다. 다음 주 월요일에 만나요~

자체 광고

많은 관심 부탁드려요~