태그 보관물: https

mitmproxy를 이용한 HTTP/HTTPS 트래픽 확인

개발을 하다보면 실제 네트워크 요청이 어떻게 이루어지고 있는지 확인해야할 필요가 있습니다. 내가 원하는 헤더와 파라미터로 전송되었는지, 응답에 포함된 헤더는 무엇인지등 상황은 많습니다. 직접 만들고 있는 어플리케이션에서는 디버깅 툴을 이용하거나 print 등을 이용해서 출력해서 확인하기도 하지만 이런것이 불가능한 상황도 있고 매번 지웠다 추가했다 하는것도 귀찮은 일입니다.

이렇게 다른 앱이나 혹은 디버깅을 직접 할 수 없는 상황에서 프록시 서버를 이용해 네트워크 트래픽을 분석하는 경우가 많이 있습니다. Wireshark, Charles Proxy 등이 많이 알려져 있는데요. 오늘 제가 소개할 툴은 mitmproxy 입니다. Wireshark, Charles 같은 경우 미려한 GUI를 제공하지만 설치하기도 번거롭고 네트워크 트래픽만 보려는데 메뉴도 많아서 복잡한데 mitmproxy는 터미널에서 간단하게 실행되고 사용하기도 쉽습니다.

설치

python이 설치되어 있다면 아래 명령어를 이용해 설치합니다.

$ pip install mitmproxy

Mac 사용자라면 홈페이지에서 맥용 바이너리를 직접 받는편이 쉽습니다. 바이너리 압축을 풀면 실행파일이 2개 나오는데 이중 mitmpxoy를 다음과 같이 실행만 하면 끝입니다. 쉽죠?

$ ./mitmproxy

설정

mitmproxy를 실행하면 전체가 까만색에 하단에는 파란색 상태바만 보이는 화면을 보게 됩니다. 이게 실행된겁니다 ^^ 하단 파란색 상태바의 우측에 [*:8080] 는 현재 컴퓨터의 8080 포트로 프록시 서버를 실행했다는 의미입니다.

mitmproxy_launsh

mitmproxy 실행화면

mitmproxy를 실행한 상태에서 네트워크 트래픽을 확인하기 위한 디바이스의 네트워크 설정에 프록시 서버 설정을 합니다. ip 주소는 mitmproxy가 실행중인 컴퓨터의 ip, 포트는 위에서 확인한 8080 포트를 입력합니다.

SSL 인증서가 적용된 네트워크 트래픽을 확인하기 위해서는 추가 작업이 필요합니다. 네트워크 트래픽을 확인하기 원하는 디바이스의 브라우저에서 http://mitm.it 을 입력후 OS에 맞는 이미지를 선택해 SSL 인증서를 설치합니다.(프록시 설정이 되있지 않은 상태에서는 mitm.it 에 접속할 수 없습니다.

iOS 기기에 인증서 설치하기

iOS 기기에 인증서 설치하기

SSL 인증서가 디바이스에 설치되어 있지 않은경우 HTTPS 를 사용하는 앱에서 다음과 같은 오류가 발생하고 트래픽 확인도 불가능합니다.

SSL 인증서 미설치시 오류

SSL 인증서 미설치시 오류

iOS 용 크롬의 경우는 SSL 인증서 미설치시 주소창 옆에 잠금 아이콘이 빨간색으로 나오면서 잘못된 인증서임을 알립니다.

인증서 미 설치시 사파리 알림창

인증서 미 설치시 사파리 알림창

인증서 설치 전후 URL 주소창

인증서 설치 전후 URL 주소창

사용 방법

mitmproxy의 기본 사용방법은 간단합니다. HTTP/HTTPS 트래픽이 화면에 표시되고  j/k 키를 이용해 커서를 상하로 이동해서 트래픽을 선택하고 상세히 확인하고 싶은 트래픽에서 엔터키를 입력하면 요청/응답/상세 탭으로 구분된 페이지로 이동하고 다시 목록으로 가려면 q키를 입력합니다.

mitmproxy 트래픽 목록

mitmproxy 트래픽 목록

상세화면에서 요청/응답/상세 탭의 이동은 h/l 키를 이용합니다.

mitmproxy 상세 화면

mitmproxy 상세 화면

이외에도 mitmproxy는 같은 요청을 다시 보내거나 트래픽을 변조하는등 다양한 기능을 가지고 있습니다. 저 같은경우는 위에 나온 가장 기본적인 방법만 주로 사용하고 있습니다.

mitmproxy를 사용한다고 모든 네트워크 트래픽을 볼 수 있는것은 아닙니다. HTTP/HTTPS 트래픽만 확인 가능하고 페이스북/애플 등 몇몇 앱들의 경우에는 트래픽 확인이 되지 않는데 이유는 정확히 모르겠습니다. 아마도 보안조치를 취해서 그런것이 아닐까 생각하고 있습니다.

또한 iOS와 달리 Mac에서는 인증서를 설치하더라도 mitmproxy를 프록시 서버로 설정하는 경우 HTST를 적용한 일부 웹사이트는 사용이 불가능합니다. HTST는 HTTPS에 보안을 좀더 강화한것으로 정확한 동작방식은 저도 아직 이해를 못해서 위키링크로 대체합니다. HTST가 적용된 대표적인 서비스로 Google, GitHub 등이 있습니다. 그런 이유로 mitmproxy를 사용하면서는 구글 검색과 깃헙 사용을 못해요 ㅜㅜ iOS에서는 잘되는데 맥에서는 왜 안되는지 이유를 잘 모르겠습니다.

HTST가 적용되지 않은 사이트는 위험하지만 페이지 접근 가능

HTST가 적용되지 않은 사이트는 위험하지만 페이지 접근 가능

HTST가 적용된 사이트는 접근 불가능

HTST가 적용된 사이트는 접근 불가능

게시글의 아마존, 쿠팡, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

CDN을 이용해 워드프레스 블로그에 쉽게 HTTPS 적용하기

워드프레스로 운영중인 현재 블로그에 HTTPS를 적용했는데 다른 분들에게도 유용할 것 같아서 정리했습니다.

왜 HTTPS인가?

최근 모든 웹 페이지 및 API 트래픽에 HTTPS를 사용하는것이 당연시 되고 있습니다. 구글은 HTTPS를 사용하면 검색결과에서 상위에 노출되게 하도록 하겠다고 했고(공식 블로그 글), 애플은 iOS 9 부터 기본설정으로 앱이 외부와 통신할때 HTTPS가 아니면 안되도록 강제했습니다(관련 글). 이렇게 하는 이유는 HTTP 통신의 경우 아주 간단한 방법으로 사용자가 어떤 페이지에 언제 접속 했고 어떤 컨텐츠를 확인했는지 알수 있기 때문입니다. 한국의 경우 로그인 페이지만 HTTPS를 적용하는 경우가 많은데 이런경우 로그인 정보는 암호화 된다고 해도 웹페이지에서 어떤 게시물을 봤는지 어떤 이미지를 봤는지 다른 사람이 손쉽게 확인할 수 있고 심지어 중간에 데이터를 변조 해서 다른 행동을 하도록 할 수도 있습니다. 해킹된 공유기에 접속한 사용자가 HTTP로만 되어있는 페이지로 접속시 정상적인 URL 주소를 입력했더라도 전혀 다른 페이지를 보여주거나 사이트 내부에 몰래 광고나 데이터를 가로채는 코드를 추가할 수 있는거죠. HTTPS로 인해 속도가 조금 느려질수는 있지만 속도야 말로 정말 작은 문제인거죠.(트래픽이 페이스북 만큼 많으면 이해하겠습니다. 그런데 페이스북도 이미지를 포함한 모든것들이 HTTPS로 제공된답니다.)

이러한 이유로 개인적으로는 모든 페이지에 HTTPS를 적용하는 흐름에 동조하는 편이었지만 개인 블로그에서는 적용하지 못하고 있었습니다. 인증서를 발급 받는 비용도 문제였지만 1년마다 갱신하는것이 번거롭고 개인 블로그를 운영하다보면 갱신하는것을 기억하지 못하거나 바빠서 제때 갱신하지 못할수도 있기 때문입니다.

SSL 인증서

HTTPS를 적용하기 위해서는 SSL 인증서라는것이 필요합니다. 이 인증서는 돈을 주고 구매해야 하는데요. StartSSL,  Let’s Encrypt 에서 무료로 제공하기도 하지만 1년이나 3개월에 한번씩 갱신해야 되는것이 번거로운 저는 다른 방법을 선택했습니다.

CDN에서 제공하는 HTTPS

CDN은 데이터 전송을 좀더 빠르게 해주는 역할도 하지만 SSL 접속을 대신 해주는 기능도 합니다. HTTPS를 지원하는 CDN으로는 무료인 CloudFlare와 유료인 AWS의 CloudFront가 있습니다. 좀더 다양한 설정을 원한다면 CloudFront가 좋고 무료로 간단한 기능만 사용한다면 CloudFlare가 좋습니다. 두 서비스 모두 SSL 인증서를 자동으로 갱신하므로 인증서 갱신을 신경쓰지 않아도 됩니다.

사용자와 CDN 통신은 HTTPS로 암호화하고 CDN과 블로그 서버의 통신은 기존대로 HTTP로 하는것입니다. CDN이외에는 블로그 서버로 직접 접속하지 않기 때문에 그나마 괜찮은 방법이고 기존에 운영중인 워드프레스 블로그에 직접 인증서를 설치하지 않아도 되는 장점이 있습니다. 또한 HTTP로 접속하는 경우는 HTTPS로 리다이렉트 시켜 사용자가 실수로라도 HTTP로 접속하는 일이 발생하지 않도록 할것입니다.

CDN을 이용한 블로그 SSL 구조

CDN을 이용한 블로그 SSL 구조

CDN 설정하기

CloudFlare를 사용하려면 도메인의 네임서버를 CloudFlare로 변경해야 합니다. CloudFront를 사용한다면 AWS Certificate Manager를 이용해서 도메인에 대한 인증서를 만들고 도메인 설정에서 CNAME으로CloudFront 주소를 입력하면 됩니다.(현재는 버지니아 리전에서만 무료로 발급 가능하지만 CloudFront는 지역이 상관 없으므로 버지니아에 생성해도 됩니다) 이후 부터는 CloudFlare 기준으로 설명하겠습니다. CloudFront 사용해보신 분들이라면 다 쉽게 할수 있는 것들입니다.

네임서버 설정

네임서버 설정

CloudFlare의 경우 Crypto > SSL 타입을 FlexibleSSL로 설정하고, Page Rules에서 http로 접속하는 패턴을 추가후 only https를 체크해서 http로 들어오는 트래픽은 https로 리다이렉트 시킵니다.

CloudFlare SSL 설정

CloudFlare SSL 설정

http 트래픽을 https로 리다이렉트

http 트래픽을 https로 리다이렉트

워드 프레스 설정

워드프레스에서 HTTPS를 사용하기 위해서는 몇가지 설정이 필요합니다.

  1. “일반 > 설정”에 입력된 본인의 블로그 주소를 http에서 https로 변경합니다.
  2. CloudFlare 플러그인을 설치 : 코멘트를 작성하는 사용자의 ip 주소를 정상적으로 표시하는데 필요합니다. 설정하지 않으면 모든 사용자의 ip가 CDN 서버의 ip로 남겨집니다. Cloudfront를 사용하는 경우 비슷한 역할을 하는 플러그인을 설치해야합니다.
  3. wp-config.php에서 `$_SERVER[‘SERVER_PORT’] = 443;` 설정
    • jetpack 플러그인을 사용할때만 해당하는 사항

CDN 설정이 완료되면 도메인 네임서버가 변경되는 시간을 고려해서 몇시간이나 몇일후 부터는 사용자가 HTTPS로 접속가능합니다.

워드프레스 사이트주소 변경

워드프레스 사이트주소 변경

CloudFlare Plugin

CloudFlare Plugin

제가 사용한 구성에서 CDN과 워드프레스사이의 통신은 HTTP로 이루어지기 때문에 워드프레스는 이를 HTTP로 인식하게 됩니다. 이로 인해 여러가지 문제가 발생하는데요. 이미 이와 관련한 패치가 wp-config.php 파일에 되어 있습니다. 하지만 JetPack을 정상적으로 사용하기 위한 설정이 빠져 있습니다.

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

위의 코드가 wp-config.php에 반영해야할 내용인데요. “$_SERVER[‘SERVER_PORT’] = 443;” 를 제외한 나머지는 이미 포함되어 있으니 “$_SERVER[‘SERVER_PORT’] = 443;”만 추가하면 됩니다.

  • `$_SERVER[‘HTTPS’] = ‘on’;`
    • 이 설정이 없으면 블로그는 HTTPS로 제공하지만 CSS/JS 등이 HTTP로 제공되어 브라우저가 차단합니다.
  • `$_SERVER[‘SERVER_PORT’] = 443;`
    • 이 설정이 없으면 JetPack과 워드프레스 닷컴간의 연결이 되지 않습니다. 워드프레스 앱에서 본인의 블로그에 접속 할수도 없습니다.

참고 : CloudFront를 사용하는 경우에는 HTTP_X_FORWARDED_PROTOHTTP_CLOUDFRONT_FORWARDED_PROTO로 변경해야 합니다. 이유는 모르겠지만 X-Forwarded-Proto 헤더를 CloudFront에서 직접 설정해도 적용되지 않았습니다.

여기 까지만 하면 블로그의 일반적인 사용에 문제가 없습니다. 하지만 블로그 운영자들이 필수적으로 사용하는 외부 서비스들의 설정 변경에 대해서 더 알아보겠습니다.

Google Search Console

Search Console은 블로그가 구글에 검색되도록 설정하고 관리하는 서비스인데요. Search Console 에서는 HTTPS에 대한 고려가 되어 있지 않아서 HTTPS 사이트를 별도의 사이트로 인식합니다. 따라서 기존에 생성된 사이트와 별개로 https://를 포함한 새로운 사이트를 생성해서 관리해야 합니다. 소유자 확인은 기존에 추가했던 코드들을 지우지 않았다면 별다른 설정을 할 필요 없습니다.

Search Console에 https 사이트를 별도로 등록해야한다

Search Console에 https 사이트를 별도로 등록해야한다

Search Console는 원래 블로그의 URL 구조가 변경되는 경우 구글 검색결과에서 쉽게 바꿀수 있는 기능을 제공하는데 HTTP에서 HTTPS로의 전환시에는 사용할 수 없습니다. 그저 301 리다이렉트 코드를 적용해두면 구글이 언젠가 반영해주기를 기다려야죠.

Google Analytics

서비스 접속후 속성에서 블로그 주소 앞의 프로토콜을 http에서 https로 변경합니다.

Google Analytics HTTPS

Google Analytics HTTPS

Google 애드센스(AdSense)

광고 추가코드 부분에서 “http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js” 이런식으로 되어 있는것에서 http:를 제거합니다. 최종 결과물은 “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js” 이렇게 됩니다. 이 설정을 하게되면 블로그가 HTTPS로 제공될때는 애드센스 광고도 HTTPS로 호출합니다.

HTTPS로 광고를 요청하는 경우 HTTPS를 지원하는 광고만 노출되기 때문에 HTTP를 사용할때보다 광고의 수가 적어서 수익이 줄어 들수 있다는것을 주의해야합니다. 구글에서 검색해보면 2014년도의 외국 블로그 글에서 실제 블로그 수익이 50% 가까이 감소 했다는 글을 볼수 있습니다. 이것이 2016년인 현재도 마찬가지 상황인지는 모르겠지만 사람마다 다르니 HTTPS를 적용할때 주의하시기 바랍니다.

결론

워드프레스 블로그를 HTTPS로 전환하다 보니 개인 블로그를 HTTPS로 변경하는것은 아직 시기 상조인가?라는 생각이 많이 들었습니다. 워드프레스에서도 지원하지 않아서 플러그인 설치나 직접 수정으로 해결해야 하는 경우도 있고, 구글의 애드센스나 Search Console등을 봐도 이에 대해 고려가 되어 있지 않다는 인상을 받았기 때문입니다. 그럼에도 불구하고 새로 시작하는 블로그라면 HTTPS로만 제공하기를 추천합니다. 앞으로는 점점 HTTPS만 제공하는 추세가 될것이기 때문이죠. 기존에 HTTP로 제공중인 블로그라면 좀더 기다리다가 변경하기 편해졌을때 하는것도 좋고 조금 고생하더라도 지금부터 미리 HTTPS로 전환해서 나중에 검색결과등에서 미리 유리한 고지를 점령하는것도 좋겠습니다.

삽질들

설 연휴동안에 HTTPS 설정을 빨리하고 다른일을 하려 했는데 어마어마한 삽질을 하느라 시간이 다 가버렸습니다. 설 연휴 첫날 내려가기 전에 HTTPS 설정을 다했고 블로그도 정상적으로 실행되는것을 확인했는데 남은 설 연휴를 다 써버렸으니 제 삽질의 여파는 엄청 났습니다.(대부분 JetPack 때문이었죠… 워드프레스 닷컴과 워드프레스 앱을 사용하는건 너무 중요했습니다 ㅜㅜ)

제가 했던 삽질들 입니다.

  • CloudFlare -> CloudFront -> CloudFlare
    • CDN 서비스를 선택할때 부터 고민하다가 무료인 CloudFlare로 선택 했었는데요. 다 잘되는데 JetPack으로 워드프레스 닷컴 연동과 워드프레스 앱 연동이 안되서 CloudFront로 바꾸는 삽질을 했습니다. 그랬는데 CloudFront 에서는 X-Forwarded-Proto 헤더가 전송이 안되는걸 모르고 몇시간을 헤매다가 관련 코드를 넣어서 HTTP 컨텐츠가 섞여서 나오는 문제는 해결했지만 JetPack 문제는 해결되지 않았죠. SERVER_PORT를 443으로 수정해서 JetPack 연동하는걸 알게된후 다시 무료인 CloudFlare로 변경했습니다.
  • 잦은 CDN 변경으로 DNS 캐쉬 문제 발생
    • 단시간에 잦은 CDN 변경으로 DNS 네임서버도 변경하다 보니 하루가 지나도 이전 CDN으로 접속되는 문제가 발생했습니다. 그래서 맞는 설정을 했는데도 됬다 안됬다하는 현상이 반복되다보니 삽질을 하는 횟수가 몇배로 늘어났습니다.
  • 플러그인 막무가내 설치
    • 잘 모르는 상황에서 이것저것 SSL 관련 플러그인을 몇개 설치후 체크박스 한두개 설정했더니 어드민에 접속하지 못하는 현상이 발생했습니다. 결국 SSH로 서버에 접속해서 해당 플러그인 폴더를 삭제하는것으로 해결했습니다.

제가 했던 삽질을 하지 않으려면 우선 CDN 서비스는 본인에게 맞는건 하나만 선택해서 끝까지 해보시기를 추천드립니다. 저처럼 뭔가 안된다고 짧은 시간에 CDN 서비스를 바꾸면 삽질이 몇배로 늘어납니다.

  • 2017년 11월 19일 추가
    CDN을 CloudFlare에서 AWS CloudFront로 변경했습니다. CloudFlare가 간혹 너무 느려서 사이트 접근이 불가능한경우가 있었기 때문입니다. 무료 버전의 CloudFlare에 문제가 있다는 이야기는 몇번 들었었는데 불규칙적이고 한번 발생하면 해결도 불가능해서 안정적으로 컨텐츠를 제공하는데 별로인것 같아서 비용이 나가더라도 CloudFront를 사용하는게 좋겠다고 생각했습니다. CloudFront를 사용하는 경우 CloudFront 에서 CNAME 설정 및 Route 53에서 A 레코드로 Alias로 CloudFront 설정이 필요하며 Cache Behavior 설정에서 ‘Cache Based on Selected Request Headers’를 All로 설정하고 Forward Cookies를 All로 설정해야 합니다. 이렇게 설정하면 캐시가 되지 않는데 우선 이렇게 동작하게 하고 캐시 설정은 더 공부해보고 설정해보세요.

참고정보

게시글의 아마존, 쿠팡, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^