Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

기술 뉴스 #163 : 20-12-02

웹개발 관련

  • Better JS scheduling with isInputPending() : Chromium 87에 정식 추가된 isInputPending()을 설명한다. 브라우저에서는 자바스크립트 실행이 걸어지면 인풋의 응답은 지연될 수밖에 없어서 보통 스크립트 실행을 나누어서 브라우저가 인풋 관련 이벤트가 있는지 확인하고 다시 스크립트를 실행할 수 있도록 하는데 반응성이 느리면 자연히 스크립트 실행도 (나누어지므로) 길어진다. 이 문제를 해결하기 위해 Facebook이 isInputPending()를 제안했고 자바스크립트가 브라우저에 위임하지 않고 직접 처리할 인풋 이벤트가 있는지 확인할 수 있다.(영어)
  • Back/forward cache : 뒤로/앞으로 가기를 눌렀을 때의 캐시(bfcache) 적용이 파이어폭스/사파리는 오랫동안 지원했지만, 크롬은 87부터 안드로이드 사용자에게 점진적으로 적용하기 시작했다. bfcache는 HTTP 캐시와는 다르게 전체 페이지를 메모리에 캐시한다. 브라우저가 알아서 최적화를 해주지만 pageshow, pagehide로 캐시 상태를 알 수 있고 unload는 사용하지 말라고 하고 있다.(영어)
  • 이제 React.js 를 버릴 때가 왔다 : React가 인기를 얻게 된 것은 SSR(Server Side Rendering) 때문이었는데 SSR을 하기가 쉽지 않고 hooks가 간결하게 만든 점은 있지만, 상태를 동기화하게 되면서 오히려 다루기 어려워졌다고 얘기하고 있다. 지금은 다른 좋은 대안이나 시도도 많이 나오기 시작하고 있음으로 React를 고집할 필요가 있냐고 주장하는 글이다.(한국어)
  • FE 개발자의 성장 스토리 02 : Babel 7과 corejs3 설정으로 전역 오염 없는 폴리필 사용하기 : IE11을 지원하기 위해서 Babel로 컴파일하는 과정에서 polyfill이 전역으로 포함되어 전역 스코프를 오염시키는 문제는 해결한 과정을 설명한 글이다. 전역 스코프를 오염시키지 않도록 core-js를 설정하고 node_modules 모듈에도 Babel 설정이 적용되도록 Babel 7에 추가된 Project Wide Configuration을 사용하고 ES Moules/CommonJS Modules를 같이 사용할 수 있는 _interopRequireDefault의 적용 과정을 설명한다.(한국어)

그 밖의 개발 관련

  • 주니어 개발자들의 (얕은) 코드리뷰 도입기 : 회사의 두 주니어 개발자가(백엔드와 프론트엔드) 코드 리뷰를 해보고 싶어서 스택이 다름에도 서로 리뷰를 하기로 한 뒤 템플릿을 만들고 오타 수정이나 코드에 대한 질문, 개선 요청을 한 경험을 공유하는 글이다. 공부하고 직접 고민하면서 개선해 나가는 과정이라서 실제로도 도움이 많이 되는 부분이라는 생각이 든다.(한국어)
  • Growl in Retirement : 2004년부터 OS X의 노티피케이션 시스템으로 사용되었던 Growl의 개발이 종료되었다. 오랫동안 인기를 끌었지만 2012년 WWDC에서 Apple이 노티피케이션 센터를 발표하고 사용 빈도가 줄어들었기 때문에 당연한 수순이다. 개발자는 그동안 도움을 준 회사들에 감사를 표했고 소스 코드는 GitHub에서 볼 수 있다.(영어)
  • Standing up for developers: youtube-dl is back : 미국 음반 산업 협회(RIAA)의 디지털 밀레니엄 저작권법(Digital Millennium Copyright Act, DMCA) 이슈로 youtube-dl 저장소가 내려갔었는데 이 부분이 부당하다고 주장하여 다시 복구되었다.(영어)
  • No more free work from Marak - Pay Me or Fork This : 테스트용 가짜 데이터를 생성하는 JavaScript 라이브러리인 faker.js를 만든 Marak이 (무슨 일이 있었는지 모르지만...) 포춘 500 기업이나 그보다 작은 기업에는 더는 지원하지 않겠다고 선언했다. 연 1억 이상의 계약을 하거나 포크해가서 직접 수정해가며 쓰라는 것인데 긴 스레드 끝에 GoDaddy와 계약을 맺어서 hook.io의 소유권은 GoDaddy에 넘기고 오픈소스 활동을 할 수 있게 되었다고 한다.(영어)

인프라 관련

볼만한 링크

  • 스타트업을 맛보다 (1) - 달달한 맛, (2) - 이국적인 맛, (3) - 매운 맛, (4) - 짠 맛, (5) - 씁쓸한 맛 : 2011년 대학생 때 스타트업에 합류해서 LUKnFEED라는 서비스를 만들면서 열정에 넘쳐서 iOS 앱 만들고 마케팅에도 힘쓰다가 서비스가 제대로 성장하지 못하자 사람들이 떠나가고 퇴사하게 되는 과정이 적혀있다. 처음에는 최근 상황까지 적으시려다가 첫 스타트업 얘기로만 시리즈가 끝났지만, 글을 잘 쓰셔서 재미있게 읽을 수 있다.(한국어)
  • 누구나 원하는 개발자되기 : 오랫동안 면접관으로 면접을 보면서 회사는 어떤 부분을 기대하고 지원자는 어떻게 준비해야 하는지를 정리할 글이다. 이력서에서 어필할 수 있도록 기술 나열이 아니라 성과라는 스토리를 담아야 하고 과제나 테스트에서는 코드 품질을 주로 보기 때문에 정상 동작 이상의 부분을 보여줄 수 있어야 한다. 면접에서도 자신이 아는 내용을 설명할 준비를 해두는 것이 중요하고 이런 준비를 평소에 할 수 있도록 환경에 상관없이 배운 것을 메모하고 정리하라고 추천하고 있다. 다양한 과정이 있지만 "이런 과정을 통해 무엇을 경험하고 배웠는지가 더 중요하다"는 부분에 동의한다.(한국어)

IT 업계 뉴스

  • 아마존이 최고가에 인수한 '자포스' 창업자 토니 셰이 사망 : "딜리버링 해피니스"라는 책으로도 유명한 자포스의 토니 셰이(Tony Hsieh)가 46세의 나이로 유명을 달리했다. 삼가 고인의 명복을 빕니다.(영어)
  • 버즈피드와 허핑턴포스트의 운명은 어디로? : 버즈피드가 허핑턴포스트를 인수한 과정과 배경이 설명이 나와 있다. 각 회사의 정확한 목적은 상황으로 추측할 뿐이지만 허핑턴포스트는 모회사의 여러 번 인수되면서 현재의 모회사 버라이즌 미디어와 애매한 관계가 되었고 인기는 끌었지만, 돈을 벌지 못한 버즈피드는 버라이즌 미디어에 돈을 받고 허핑턴포스트를 인수한 묘한 상황이 되어 버렸다. 나는 허핑턴포스트는 등장할 때 꽤 관심을 가졌지만, 국내만 그런지 좀 이상한 뉴스매체가 된듯해서 안보기 시작했고 버즈피드는 한참 동안 감탄하며 보던 곳이지만 어느샌가 잊힌 회사가 되어서 앞으로 어찌 될지 궁금하다.(한국어)
  • Servo’s new home : 모질라에서 만들던 브라우저 엔진인 Servo 프로젝트가 Linux 재단 밑으로 들어갔다.(영어)
  • 세일즈포스, 30조 원 들여 슬랙 인수…SW기업 M&A 최고액 : 세일즈포스가 Slack을 277억 달러(약 30조 원)에 인수했다.(한국어)
  • Airbnb S-1 : Airbnb가 상장을 위해 증권거래소에 S-1 문서를 제출했다.(영어)
  • Roblox S-1 : 온라인 게임플랫폼을 만드는 Roblox가 상장을 위해 증권거래소에 S-1 문서를 제출했다.(영어)
  • 카카오뱅크, 'AWS 클라우드' 도입 : 금융보안원이 실시하는 금융 클라우드 안전성 평가가 완료되어 카카오뱅크가 AWS를 도입하게 되었다.(한국어)

프로젝트

  • Is Apple silicon ready? : 새로 나온 M1 Apple Silicon 맥북에 앱의 호환성 여부를 보여주는 사이트.
  • MVP.css : 별도의 클래스 명이나 관례 없이 HTML 요소에만 최소한의 스타일을 적용한 CSS.
  • 스포카 한 산스 네오 : 기존 스포카 한 산스 폰트에 웨이트를 늘리고 가독성과 통일성을 향상한 폰트.
  • k0s : 추가 설정 없이 바로 Kubernetes 클러스터를 구성해서 운영할 수 있게 미리 설정해서 제공하는 프로젝트.
  • Skija : 오픈소스 2D 그래픽 라이브러리인 Skia의 Java 바인딩으로 JetBrains에서 공개했다.
  • k6 : JavaScript로 코드를 작성해서 부하 테스트를 하는 도구로 Go로 작성되었다.

버전 업데이트

2020/12/02 19:06 2020/12/02 19:06

mitmproxy로 iOS 기기의 네트워크 트래픽 살펴보기

개발을 하다 보면 가끔 직접 소스를 수정할 수 없는 프로그램의 네트워크를 보고 싶은 경우가 있다. 네트워크를 볼 수 있는 프로그램도 많이 있고 웹 같은 경우는 브라우저의 개발자 도구를 열면 대부분을 볼 수 있지만, 모바일 쪽으로 가면 상황이 달라진다. 나는 모바일 개발자는 아니라서 그쪽 생태계는 잘 모르지만, 모바일 개발자의 도움 없이 앱의 네트워크 동작을 봐야 할 일이 있었다.(남의 앱은 아니고 우리 회사의 앱)

mitmproxy

mitmproxy 웹사이트

그렇게 방법을 찾아보다가 알게 된 도구가 mitmproxy다. 이름에서 알다시피 MITM(man in the middle)으로 네트워크를 중간에서 가로채서 볼 수 있게 해주는 도구이고 오픈소스이면서 무료로 사용할 수 있다. How mitmproxy works에 나와 있는 대로 폰의 모든 요청을 mitmproxy로 가게 하고 mitmproxy가 다시 이를 원래 요청한 서버로 보내주는 방식이다.

설치

$ brew install mitmproxy

설치는 macOS의 경우 brew로 쉽게 설치할 수 있다. Linux와 Windows는 문서에 잘 나와 있다.

$ mitmproxy --version
Mitmproxy: 5.3.0
Python:    3.9.0
OpenSSL:   OpenSSL 1.1.1h  22 Sep 2020
Platform:  macOS-10.15.7-x86_64-i386-64bit

설치가 완료되면 버전을 확인해 볼 수 있고 현재 버전은 5.3.0이다.

맥북에서 mitmproxy 설정

아이폰과 맥북이 같은 Wi-Fi 네트워크에 붙어있다고 했을 때 맥북에서 mitmproxy를 실행한다.

$ mitmproxy

터미널에서 mitmproxy를 실행하면 아래와 같은 화면이 나타난다. 아직 트래픽을 보내지 않았으므로 아무것도 안 나오는 게 맞다.

터미널에서 mitmproxy를 실행한 빈 화면

mitmweb 명령어를 통해서 웹 인터페이스도 제공하지만 몇 번 사용해보니 느려지기도 하고 사용성 면에서 터미널에서 사용하는 것이 훨씬 나아서 더는 웹 인터페이스는 사용하지 않는다.

그리고 현재 맥북의 로컬 IP를 확인한다. 나는 Alfred 같은 도구로 IP를 보통 확인하는데 터미널에서는 다음과 같은 명령어로 확인할 수 있다.

$ ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'
172.30.1.52

내 로컬 IP는 172.30.1.52다.

iPhone에서 프락시 설정

iOS의 Wi-Fi 설정의 HTTP Proxy 메뉴

아이폰에서 [설정] - [Wi-Fi]에서 현재 사용 중인 Wi-Fi를 눌러서 들어가면 맨 아래 HTTP PROXY라는 부분을 볼 수 있다. 보통은 사용 안 하니 Off로 되어 있는데 "Configure Proxy"를 눌어서 들어간다.

Congifure Proxy 부분에서 IP와 포트를 입력함

여기서 "Manual"을 누르고 서버에서는 위에서 확인한 IP 172.30.1.52를 입력하고 포트는 8080을 입력한다.

iPhone에서 인증서 설정

아이폰에서 브라우저를 열고 http://mitm.it에 접속하면 아래와 같이 플랫폼별 인증서를 설치하는 화면이 나온다. HTTP라면 상관없지만, HTTPS의 경우 인증서 때문에 네트워크를 모니터링 할 수 없어서 인증서를 바꿔치기 해야 한다. 물론, 이건 내 폰에서 내가 직접 설정해야 가능한 것이므로 다른 사람의 폰을 감시하거나 할 수는 없다.(현재 iOS 14.2를 사용 중이다)

mitm.it 사이트에서  플랫폼별 인증서 다운로드 메뉴

만약 mitmproxy로의 프락시 설정이 제대로 되지 않았다면 아래와 같은 화면이 보일 것이다. 이때는 앞의 과정으로 돌아가서 맥북에 mitmproxy가 잘 떠 있는지 아이폰에서 프락시 설정이 잘 되어 있는지 확인해야 한다.

mitmproxy 프록시가 제대로 설정안되었으면 If you can see this, traffic is not passing through mitmproxy라고 나온다

맥북에서 아까 띄워놓은 mitmproxy를 보면 아이폰에서 브라우저로 http://mitm.it에 접속하면서 보낸 트랙픽을 확인할 수 있다.

터미널에 띄워놓은 mitmproxy에 트래픽이 잡혔다

http://mitm.it에서 iOS 부분의 "Get mitmproxy-ca-cert.pem"을 클릭한다.

iOS가 구성 프로필을 다운로드 할 것인지 묻는다

구성 프로필을 다운로드 할 거냐고 경고가 나온다. 보통은 조심해야 할 메시지지만 여기서는 의도한 것이므로 Allow 한다.

프로필 메뉴에 다운로드 받은 프로필이 표시된다

다운로드가 완료된 후 아이폰의 [설정] - [General]에 들어가면 하단에 Profile이라는 메뉴에 들어가면 mitmproxy 프로필을 볼 수 있다.

프로필 상세페이지에 Not Verified라고 표시되고 install 버튼이 있다

아직 다운로드한 것이므로 들어가서 Install을 누른다.

설치가 완료되어 프로필이 verified로 바뀌었다

설치가 완료되면 프로필이 Verified로 바뀐다.

다시 아이폰의 [설정] - [General] - [About]에 들어가면 최하단을 보면 "Certificate Trust Settings"라는 메뉴가 있다.

Certificate Trust Settings에 mitmproxy의 토글 버튼이 생긴다

이곳에 들어가면 좀 전에 설치한 mitmproxy 인증서를 볼 수 있다. 이 인증서를 신뢰하는 인증서로 설정해 주어야 네트워크 트래픽을 볼 수 있음으로 켜준다.

활성화 할때 enabling this certificate for websites will allow third parties to view any private data sent to websites라는 경고 메시지가 나온다

여기서는 의도한 동작이지만 보통 다른 인증서를 신뢰하도록 하는 것은 위험한 행위이므로 경고 메시지가 나온다. 무서워하지 않고 Continue를 누른다. 이제 모든 설정이 완료되었다.

mitmproxy로 네트워크 모니터링하기

아이폰에서 실행한 앱의 트래픽이 터미널에서 띄운 mitmproxy에 표시된다.

이제 아이폰에서 아무 앱이나 실행하면 네트워크 로그가 남는 것을 볼 수 있다. 여기서는 트위터 앱을 실행해 보았다. 한 줄이 하나의 요청이고 화살표로 위아래 움직일 수 있는데 이동하는 커서는 왼쪽에 >>로 표시된다.

터미널 UI라서 사용하기가 어려울 수 있는데 조금 익숙해지면 그리 어렵지는 않다. ?를 누르면 아래처럼 단축키를 알 수 있고 UI의 사용법은 mitmproxy 문서에도 안내되어 있다.

mitmproxy에서 단축키와 설명이 표시된다.

자세히 보고 싶은 요청을 Enter를 눌러서 들어가면 요청과 응답을 볼 수 있다.

각 요청의 상세보기에 들어가면 요청/응답/상세로 탭이 나뉘어져서 정보가 표시된다

위처럼 HTTPS 요청이지만 내용을 모두 볼 수 있는걸 알 수 있다. Details 부분에서는 커넥션에 걸린 시간, 첫 바이트를 받은 시간, 핸드쉐이크에 걸린 시간 등을 볼 수 있다. 터미널 UI라서 진입 장벽이 있고 불편하게 느껴질 수 있지만 트래픽 보는 것이 복잡한 작업은 아니니 트래픽을 뒤적거리다 보면 익숙해지게 된다. 물론 mitmproxy는 그냥 트래픽 모니터링만 하는 것이 아니라 요청을 다시 보내보거나 관심 있는 트래픽을 다운로드 받아보거나 하는 등 다양한 기능을 제공하고 있다.

참고로 mitmproxy를 쓰다가 프로그램을 종료하면 아이폰에서 인터넷이 전혀 되지 않음으로 위에서 설정한 HTTP PROXY 설정을 꺼주어야 한다.

2020/11/30 18:30 2020/11/30 18:30