카테고리 보관물: 개발

모르는 WIFI에 함부로 접속하는건 위험한 행위

아내는 스마트폰 요금제를 데이터 적은걸로 사용하면서 요즘은 카페든 어디든 가면 와이파이가 다 공짜로 제공되서 데이터 요금 비싼거 사용할 필요 없다고 저에게 이야기 하고는 합니다.

하지만 저는 비밀번호가 없는 와이파이 혹은 관리가 잘 안될것 같은 와이파이는 사용하지 않으려고 합니다. 그래서 스마트폰 데이터 요금제도 무제한으로 사용하고 될수 있으면 노트북도 테터링으로 사용합니다. 이렇게 말은 해도 중요한일을 하지 않거나 HTTPS로 된 서비스만 사용한다는 자기최면후 카페 와이파이 사용하는 경우가 많습니다.(돈이 많았다면 요금제 더 비싼걸로 하고 외부 와이파이 절대 접속 안했겠지만…)

제가 이런 생각을 하게된 계기는 대학생때로 거슬러 올라가게됩니다.

대학생 시절 학교 전산팀에서 학생들로 구성된 보안팀을 만들었고 학교에서 일어나는 보안 사고나 홈페이지 관리등을 맡게 되었는데 어느날 특정 전살실에서 웹 브라우저가 잘 동작하지 않는다는 신고를 받고 컴퓨터들을 조사하다가 이상한 현상을 목격하게 됩니다. 컴퓨터에는 바이러스도 없고 다른것들은 다 잘되는데 웹페이지만 접속하면 안되는 현상이었는데요. HTML 소스보기를 해보니 <html> 태그보다 한단계 위에 <script>로 시작하는 이상한 중국사이트의 자바스크립트를 다운로드 받는 코드가 있었습니다. 웹 서버는 보낸적이 없는 이 코드가 언제부터 주입되고 있었는지 모르겠지만 꽤 오랫동안 전산실 컴퓨터들을 좀비컴퓨터로 잘 사용하다가 해당 도메인이 차단 당했는지 더이상 동작하지 않으면서 오류가 발생 했었던거였죠

이 코드는 어떻게 주입되고 있었을까요? 한두대의 컴퓨터도 아니고 전산실 전체에 주입되고 있었는데 그 컴퓨터들은 아무 이상이 없었는데 말이죠. 원인은 컴퓨터가 인터넷에 접속하려면 공유기에 해당하는 기기에 웹페이지를 요청하고 응답을 받는데 그 응답 받은 페이지 최상단에 몰래 코드를 추가 하고 있었습니다. 공유기에 해당하는 기기가 이미 점령 당한 상태에서 그 기기를 이용해 인터넷을 이용하는 모든 컴퓨터가 위험에 노출된 상황이었죠. 이후로 저는 인터넷 사용을 위해 함부로 이상한 공유기에 접속하면 안되겠다는 생각을 하게 되었습니다.

최근에도 이런 일은 빈번한데요. 그 예로 특정 카페에 가서 검색을 하는데 이상하게 검색결과 상단이 뭔가 이상하게 보이거나 커뮤니티 사이트를 이용하는데 본적 없는 이상한 배너가 보이는등의 문제가 있습니다. 실제로 회사 동료중 한분도 특정 사이트가 이상하다고 이야기 했었던적이 있어서 제가 와이파이 끄고 해보라고 했더니 잘되는 경우가 있었습니다.

얼마전 미국의 특정 스타벅스 매장에서 와이파이에 접속했더니 느려져서 HTML 소스코드를 보니 와이파이에 처음 접속하면 10초 동안 가상화폐를 채굴하는 코드가 있다는 트윗이 화제였습니다. 공유기 관리가 제대로 되지 않았던거죠. 요즘에는 해킹도 예전처럼 사이트에 이상한글 올리고 돈주라고 하기보다 몰래 가상화폐 채굴하는것들이 종종 보입니다.

이러한 행위를 방지하기 위해서 믿을수 없는 공유기(혹은 와이파이)에 접속하지 않는것이 중요합니다. 이 문제는 사용자들이 주의해야 하는 문제일까요? 웹 서비스 제공자는 사용자들이 이상한 네트워크에 접속하지 않기를 기도하고 있으면 되나요? 그렇지 않습니다. 서비스 제공자들은 이러한 문제를 막을수 있는 최소한의 장치들이 있습니다.(일부 은행권 모바일 앱의 경우 이런 경우에 대비해 와이파이 상태에서는 사용하지 못하게 막는 경우도 있습니다.)

그중에 하나는 모든 페이지와 리소스(이미지, js, css등)에 HTTPS를 적용하는 것입니다. 간단하지만 효과적인 조치입니다. HTTPS로 전송되는 데이터는 중간에 가로채서 수정하기 어렵습니다. 최근 몇년동안 한국에서는 HTTPS를 기본으로 하는 서비스들이 늘어나고 있는 추세이지만 굳이 보안에 필요하지 않은 모든 페이지에 HTTPS를 적용해야되나? 자원도 많이 먹는데? 라고 생각 할 수 있습니다. 하지만 중요하지 않은 페이지더라도 사용자들이 잘못된 공유기로 접속해서 피싱당하거나 변조된 페이지를 보는것을 막을수 있다면 좋은겁니다. 중요하지 않은 파일이라고 취급받는 이미지 파일의 경우도 이미지 파일을 이용해 나쁜 의도를 가진 해킹을 할 수 있는것을 고려하면 사용자들의 컴퓨터를 지키고 서비스 신뢰성을 위해서라도 모든 리소스에 HTTPS 적용은 중요합니다. (HTTPS라고 해도 사용자 컴퓨터의 프록시를 변경하는등의 방법으로 변조가 가능하지만 사용자의 컴퓨터의 제어권을 사전에 얻어야 되는 과정이 필요하죠)

HTTPS를 사용해서 얻을수 있는 다른 장점중 하나는 ARP 스푸핑이라고 부르는 기법으로 현재 공유기에 물려있는 모든 컴퓨터들의 패킷이 도청당할때도 어떤 데이터가 포함되었는지 모르게 할 수 있다는 장점이 있습니다. ARP 스푸핑을 막기위한 보안조치로 OS나 공유기 회사들이 보안을 조치를 해두기는 하지만 모두가 그런 OS와 공유기를 사용하고 있다고 가정하는 것은 위험합니다.

ARP 스푸핑은 간단한 기법이지만 위험합니다. 같은 네트워크 상의 모든 패킷을 그대로 볼 수 있고 변조도 할 수 있습니다. HTTPS가 적용되지 않는 사이트에 로그인 한다면 그 아이디와 비밀번호는 평문으로 해커가 그대로 볼 수 있습니다.

예를 들어보겠습니다. 카페의 공공 와이파이를 사용하는데 그 공유기는 ARP 스푸핑에 대한 보안조치가 안되어있다고 생각해보죠.(일반인들은 공유기 싼거 사거나 그냥 패치 안하는 경우도 많으니까..) 공개된 와이파이라서 해커와 일반 사용자들은 다 같이 와이파이를 사용하고 있습니다. 이때 해커가 ARP 스푸핑 기능을 동작시키면 카페 와이파이 사용자들이 인터넷 서핑하고 있는 모든 데이터는 해커에게 전달됩니다. 이때 HTTPS로 암호화되었다면 아이디나 비밀번호 혹은 내가 입력한 검색어등을 확인하기 어렵지만 HTTP라면 그냥 평문 그대로 노출됩니다. HTTPS라고 해서 만병통치약은 아니지만 적어도 HTTP로 할때보다는 해커가 노력을 기울여야 하고 어렵습니다.

여기 까지 읽고 어떤 생각이 드시나요? 카페 와이파이나 무료로 열린 와이파이 앞으로도 접속하실건가요? 무섭긴 하지만 그래도 나는 데이터 용량이 적어서 와이파이 사용하셔야 된다면 HTTP로 된 사이트와 HTTPS로 된 사이트중 어떤곳을 사용하고 싶으신가요?

참고자료

대표 사진 : Photo by Kym Ellis on Unsplash

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

개발과 관련된 글만 올리는 블로그를 새로 만들었어요

이 블로그에 개발관련글과 일반 리뷰들을 섞으려고 했었는데 방문자들의 성향이 다를것 같아서 개발 관련된 글을 별도의 블로그를 만들어서 사용하기로 했습니다 ^^

https://code.iamseapy.com

관심 있는 분들은 RSS 구독 해주세요 ~

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

개발자를 위한 아이패드 프로 12.9인치 앱 리뷰

아이패드 프로 12.9인치는 스마트 키보드가 있어 개발자들이 활용하기에 유용한데요. 개발자들이 사용하기 좋은 앱을 소개해드리려고 합니다.

동영상으로 실제 실행하는 영상을 촬영했으니 참고하세요

코딩용 에디터 Coda

Coda는 저도 구매만 하고 사용하지 않는 앱이지만 유용하게 사용하실분들도 있을까 싶어서 소개합니다. Coda는 간단한 에디터, 터미널 접속, 브라우저를 하나의 앱에서 실행할 수 있습니다.

아이패드에서 간단한 HTML, CSS 파일을 만들고 내장 브라우저에서 확인후 바로 업로드할 수 있고 이미 서버에 있는 파일을 수정할 수도 있습니다.

SSH 클라이언트 Prompt 2

Prompt 2는 SSH 클라이언트로 서버에 접속할 수 있습니다. 데스크탑에서 사용하던 SSH 프로그램 못지 않은 기능으로 왠만한 작업은 다 가능합니다.

  • 단축키 지원(esc 키도 단축키로 사용할 수 있어요)
  • 한글 지원
  • 다양한 테마, 글자 크기, 글꼴 변경 지원
  • 터치를 이용한 복사 및 붙여넣기
  • Key를 이용한 서버 접속
  • 터치 ID를 이용한 앱 잠금
  • 클립을 이용해 자주 사용하는 문자열 저장 및 원터치 붙여넣기
  • 화면분할
  • 접속유지(접속이 끊길것 같으면 푸쉬로 알려줘서 접속 연장)

Prompt 2는 개발자라면 꼭 살만한 앱이라고 생각합니다. 언제 어디서든지 서버에 접속할 수 있다는건 노트북을 항상 들고 다니지 않아도 된다는 이야기겠죠?

S3, FTP 접속 프로그램 Transmit

Transmit은 FTP, AWS S3에 접속하는 프로그램입니다. 원격에 있는 데이터를 확인하거나 다운로드, 업로드, 편집이 가능합니다. 터미널을 이용해서 할 수도 있겠지만 이 프로그램을 이용하면 좀더 편하게 탐색하고 확인할 수 있습니다.

윈도우 원격접속 프로그램 Microsoft Remote Desktop

Microsoft Remote Desktop은 IE나 공인인증서가 필요한 경우 원격에 있는 윈도우에 접속하는 프로그램입니다. 윈도우를 원격에 두고 필요할때 접속하기에 좋습니다.

터치도 지원하고 한글 변환도 잘되서 사용하는데 거의 불편함이 없을정도입니다.

마치며

4개의 앱을 소개했지만 제가 자주 사용하는 프로그램은 Prompt 2Transmit 입니다. Coda는 개념을 이해못했고 제 사용목적에 맞지 않는것 같더라구요.

이외에도 개발자에게 유용한 앱이 있다면 알려주세요 ~

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

일본어 RSS 번역해서 보기 – AWS Lambda 이용

저는 요즘 일본어 글을 보는 일이 많아졌습니다. 일본어라고는 히라가나 철자를 발음하는 수준이 전부지만 일본어로 된 좋은 글들이 많기 때문입니다. 다행히 일본어-한국어 번역기는 품질이 괜찮은 편이라 구글 번역기를 이용해서 내용을 이해하는 데 큰 무리가 없고 크롬을 이용하면 일본어 사이트인 경우 자동으로 한국어로 번역하도록 설정해서 볼 수 있지만 문제는 모바일입니다.

모바일 기기에서도 크롬을 사용할 수 있지만 사용하는 RSS 리더인 Feedly(, iOS, 안드로이드)는 모바일웹용 RSS는 제공하지 않고, 번역을 제공하는 다른 RSS 서비스나 앱을 찾을 수 없었습니다. 이러한 불편함을 해결하고자 일본어 RSS를 읽어서 제목만이라도 한국어로 번역해주면 RSS 목록에서 제목을 보고 관심 있는 글은 크롬으로 열어서 번역으로 보면 괜찮겠다고 생각했습니다. 제목만 한국어로 바꾼 새로운 RSS 파일을 생성하면 RSS 리더 서비스나 앱이 지원하지 않아도 번역된 내용을 볼 수 있는 장점이 있습니다.

RSS 번역 구조도

RSS 번역 구조도

일본어 RSS를 번역 후 새로운 RSS 파일을 만드는 건 어렵지 않은 일입니다. 번역 API를 사용해서 얻은 값을 파일에 다시 쓰기만 하면 되는 거니 까요. 문제는 서버를 어떻게 관리할 것 인지였습니다. 이런 간단한 프로그램을 위해 서버를 운영하는 건 비용이나 운영에 들어가는 시간이 아까웠습니다. 제가 원하는 조건은 다음과 같았습니다.

  • 서버 비용이 저렴 할 것
  • 따로 신경쓰지 않아도 잘 동작 할 것

서버 비용은 집에 남는 서버를 사용하거나 기존에 운영 중인 개인 서버를 사용하면 됩니다. 하지만 따로 신경 쓰지 않아도 잘 동작하는 서버라는 건 없었죠. 아무리 신경 쓰지 않는다고 해도 새로운 서버로 업그레이드하거나 정전, OS 업그레이드 등 다양한 상황이 발생할 수 있습니다.

그러던 와중에 생각난 것이 AWS Lambda입니다. Lambda는 소스코드만 올려두면 서버 설정 없이 AWS가 코드를 실행해주는 서비스입니다. 소스코드에 이상만 없으면 서버 관리할 필요 없이 알아서 동작하고, 비용도 실제 실행시간만큼만(100ms 단위) 지불되므로 제가 원했던 것처럼 몇 초 안에 실행이 끝나는 경우 별도의 서버를 운영하는 것보다 저렴합니다.

Lambda는 다양한 방법으로 코드를 실행할 수 있습니다. S3, API Gateway 요청, AWS IoT 이벤트 그리고 정해진 시간에 실행하는 방법 등이 있습니다. 정해진 시간에 코드가 실행되는 건 CloudWatch – Schedule을 선택 후 cron 문법에 맞는 문자열만 적으면 정해진 시간에 실행됩니다. CloudWatch가 뭔지 몰라도 상관없는 거죠.

Lambda 이벤트 소스 종류

Lambda 이벤트 소스 종류

Lambda CloudWatch - Schedule

Lambda CloudWatch – Schedule

Lambda Cron 표현식

Lambda Cron 표현식

제가 만든 RSS 번역하는 소스코드는 다음과 같습니다. 참고로 Lambda가 지원하는 개발 환경은 Node.js(v0.10.36), Java(Java 8), Python(Python 2.7) 인데 Java(자바)는 그냥 하기 싫었고 Python(파이썬)은 3이 아니라서 한 번도 해본 적 없는 Node.js로 만들었습니다. Node.js는 처음이라 제가 잘못 작성한 부분도 많겠지만 참고 봐주세요 ^^;

```index.js
var http = require('http');
var xml = require('xml2js');
var DOMParser = require('xmldom').DOMParser;
var async = require('async');
var request = require('request');
var AWS = require('aws-sdk');
var s3 = new AWS.S3();

exports.handler = function(event, context) {
    var options = {
      hostname: 'b.hatena.ne.jp',
      path: '/hotentry/it.rss',
      headers: {
        'User-Agent': 'Mozilla/5.0'
      }
    }
    http.get(options, function(res) {
        res.setEncoding('utf8');
        var body = '';
        res.on("data", function(chunk) {
            body += chunk;
        });
        res.on('end', function() {
            var parser = new DOMParser({
                            locator:{},
                            errorHandler:function(level,msg){ }
                        })
            var doc = parser.parseFromString(body);
            var items = doc.getElementsByTagName('item');
            async.eachSeries(items, function iterator(item, callback) {
                var title = item.getElementsByTagName('title')[0]
                var form = {
                    q: title.textContent,
                    langpair: 'ja|ko',
                    de: 'myemailaddress'
                }
                request.post({ url:'http://api.mymemory.translated.net/get', form: form },
                    function (err, httpResponse, body) {
                        if (!err) {
                            var result = JSON.parse(body);
                            title.textContent = result.responseData.translatedText;
                        }
                        callback();
                    }
                )
            }, function done() {
                var xml = doc.toString();
                s3.putObject({
                    Bucket: 'seapy-static',
                    Key: 'rss/lambda_hatena_hotentry_it.xml',
                    Body: xml,
                    ACL: 'public-read',
                    ContentType: 'text/xml'
                }, function(err, data) {
                    if (err) console.log(err, err.stack);
                    else     console.log(data);
                    context.done(null, 'success');
                });
            });
        });
    }).on('error', function(e) {
        context.done('error', e);
    });
};
```

이 코드를 로컬 환경에서 실행하려면 좀 귀찮은데 이걸 해결하려면 lambda-local을 이용합니다.

번역 API는 구글 것을 사용하고 싶었지만, 유료라서 무료 범위에서 많은 단어를 제공하는 Mymemory를 사용했습니다. 필요한 모듈들은 npm을 이용해서 설치했고 해당 모듈들은 node_modules 폴더에 위치합니다.(aws-sdk는 로컬에서만 사용하고 실제 업로드 할 파일에서는 제외합니다. lambda 에서 이미 가지고 있거든요) 그리고 위의 코드와 node_modules 폴더를 하나의 압축파일로 만들어서 Lambda 서비스에 업로드 후 이벤트 소스를 CloudWatch – Schedule로 하고 20분에 한 번씩 실행하도록 하면 끝입니다. 진짜 끝이에요. 이제 20분 마다 일본어로 된 RSS를 한국어로 번역하고 S3에 저장합니다.

저는 서버가 어떻게 실행되는지 다운되지는 않았는지 업그레이드는 언제 할지 전혀 고민하지 않아도 되고 비용도 거의 무료로 사용합니다. AWS Lambda의 무료 범위가 꽤 넓거든요 ~

Lambda가 실행된 횟수와 실행시간은 Monitoring 탭에서 확인할 수 있고, 메모리 사용량이나 출력 등 자세한 로그는 CloudWatch에서 확인할 수 있습니다.

Lambda 모니터링

Lambda 모니터링

Lambda 로그

Lambda 로그

일본어 RSS의 제목을 번역한 새로운 RSS를 구독한 결과는 다음과 같습니다.

RSS 번역 결과 - Feedly 웹

RSS 번역 결과 – Feedly 웹

RSS 번역 결과 - Feedly 모바일

RSS 번역 결과 – Feedly 모바일

일부 번역이 안된 것들도 보이지만 주제를 아는 데 방해가 될 정도는 아닙니다. 문제는 “Mymemory Warning: You Used All Available Free Translations For Today.” 이라고 나오는 것들인데요. 제가 보는 하테나 IT 섹션 RSS의 업데이트 빈도가 너무 높아서 Mymemory 번역 API의 무료범위를 넘어가서 발생하는 문제입니다. 돈을 내면 쉽게 해결될 문제인데 저와 같은 목적으로 위의 RSS를 보고 싶은 사람들이 있다면 여러 명이 나눠서 내면 크게 비싸지 않을 것도 같습니다.

이번 개발을 하면서 느낀 건 2가지였습니다. 첫째는 Node.js 도 재미있다는 거였습니다. 이번 개발을 하기 전까지는 필요성을 못 느꼈는데 서버 운영하기 싫은 간단한 것들 만들 때 Lambda에 올릴 것들은 Node.js 배워서 해보면 재미있겠다는 생각이 들었습니다. 두 번째는 Serverless 트렌드가 일회성으로 끝나지 않고 앞으로 많은 비중을 차지하게 될 것이라고 느꼈습니다. 직접 해보니 특정 영역에서 확실한 장점이 보였습니다.

Lambda에 아쉬운 건 제가 좋아하는 Ruby(루비)를 아직 지원하지 않는다는 것입니다. 작년 AWS re:invent에서 Python 지원을 발표했으니 올해는 Ruby 지원을 발표하면 좋겠지만, Ruby는 아마 안될 거예요…

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

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) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

ZSH에서 ~/.ssh/config에 있는 Host만 자동완성되게 하기

저는 맥에서 zsh을 사용하고 있는데요. 설정은 oh-my-zsh에서 설정된 기본값을 사용합니다.

최근 회사나 커뮤니티의 서버에 접속할 일이 많아지면서 서버 접속에 불편함이 생겼는데요. 그건 바로 ssh 명령어 입력후 탭으로 자동완성되는 호스트에대한것이었습니다. 기본 설정으로 자동완성되는 호스트는 내가 한번이라도 접속한적이 있는것들이 다 나오더라구요. 아마도 ~/.ssh/known_hosts 와 ~/.ssh/config에 설정된 호스트를 모두 뒤져서 자동완성에 사용하는것 같습니다.

한두번만 접속해본 서버들 때문에 자주가는 사이트들이 자동완성되지 않는게 너무 싫어서 ~/.ssh/config에 설정된 호스트 alias만 자동완성에 사용하도록 .zshrc에 아래 코드를 추가합니다.

h=()
if [[ -r ~/.ssh/config ]]; then
   h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ $#h -gt 0 ]]; then
   zstyle ':completion:*:ssh:*' hosts $h
fi

이제는 ssh 입력후 탭을 입력했을때 ~/.ssh/config에 입력된 host alias 목록만 나와서 한결 접속하기 편해졌습니다 ^^

참고정보

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

AWS 서울 vs 도쿄 리전 속도 및 가격 비교

드디어 한국에도 AWS 리전(region)이 생겼습니다 ^^

그동안 한국에서 AWS 사용하시는 분들은 대부분 일본 도쿄에 있는 리전을 사용했었는데요. 다운로드 속도 같은건 괜찮았지만 지연속도나 가끔 특정 인터넷 업체에서 접속이 안되는등의 문제가 있었습니다. 하지만 이제 서울에 리전이 생긴만큼 이런 문제들은 없어질것이라고 생각합니다.

그런 의미에서 기존에 한국 서비스에서 많이 사용하던 도쿄 대비 서울이 과연 얼마나 속도가 빨라졌을까 궁금해서 비교해보기로 했습니다.

가장 많이 사용되는 S3와 EC2의 지연시간, 다운로드 속도에 대해 비교를 진행했습니다.(참고로 저는 KT의 기가 인터넷을 사용하고 있고 공유기는 기가를 지원하지만 ASUS 공유기 문제로 테스트에 사용한 노트북과 공유기는 2.5 Ghz 로 연결하고 있습니다)

S3

S3 속도 비교는 저용량부터 고용량 파일 4개를 업로드/다운로드 하는 방법으로 진행했습니다.

테스트에 사용한 파일의 크기는 374KB, 1.5MB, 100MB, 1.5GB 였고, 스토리지 옵션은 Standard Storage, 서버 암호화 안함, Public Access 설정이었습니다.

  • 도쿄
    • 4분 16초, 4 MB/s ~ 10MB/s 사이. 평균 6 MB/s
  • 서울
    • 2분, 10 MB/s ~ 16MB/s 사이. 평균 13 MB/s

파일 업로드 속도에서 2배 차이로 서울이 빨랐습니다. 도쿄의 경우 특정 시간대에는 1 MB/s도 안나오는 경우가 있었는데 그것까지 감안하면 서울의 속도는 정말 빠릅니다.

Multipart Upload 기능을 이용한 업로드 테스트

+ 2016년 1월 11일 내용추가된 단락입니다.

S3에서는 대용량 파일을 업로드할때 여러개의 파일로 나눠서 올리는 Multipart Upload 기능이 있습니다. 이를 이용해서 올리는 경우에도 차이가 많이 나는지 테스트 해봤습니다. 테스트에는 aws cli 프로그램을 이용했고 명령어는 다음과 같았습니다.

time aws s3 cp --region ap-northeast-1 100mb2.MOV s3://tokyo-bucket/100mb2.MOV
time aws s3 cp --region ap-northeast-2 100mb2.MOV s3://seoul-bucket/100mb2.MOV

결과는 다음과 같습니다.

  • 100 MB
    • 도쿄 : 16초
    • 서울 : 11초
  • 1.5 GB
    • 도쿄 : 2분 48초
    • 서울 : 2분 30초

1.5 GB에서 반반의 확률로 일본이 속도가 5초정도 빠른경우가 있었습니다. 지금 도쿄가 속도가 빠른시간인지 모르겠으나 속도 차이가 많이 나지 않네요. 주의할점은 이전 섹션의 대용량 테스트와 테스트 시점이 다르기 때문에 서로 뭐가 빠르다고 이야기 할 수 없습니다.(참고로 이 테스트는 다른 테스트와 다르게 기가 인터넷이 아닌 KT 일반 인터넷에서 진행됬습니다.)

같은 환경에서 이전 섹션의 테스트처럼 브라우저에서 업로드한경우 서울 리전 기준 3분이 걸렸습니다. multipart upload가 조금더 빠르네요

저용량 다운로드 테스트

크롬 개발자 도구의 네크워크 탭에서 정보를 확인했으며 3번씩 테스트 하고 지연시간(Latency), 전체 시간을 기록했습니다. 다운로드에 사용한 URL은 HTTPS라서 HTTP보다 조금 느리다는것 감안하시기 바랍니다.

  • 도쿄
    • 374 KB
      • 233ms, 462ms
      • 217ms, 554ms
      • 198ms, 569ms
    • 1.5 MB
      • 245ms, 693ms
      • 239ms, 747ms
      • 215ms, 811ms
  • 서울
    • 374 KB
      • 95ms, 142ms
      • 55ms, 109ms
      • 49ms, 113ms
    • 1.5 MB
      • 79ms, 201ms
      • 69ms, 234ms
      • 51ms, 251ms

지연시간의 개선은 물론 다운로드 속도도 빨라져서 374 KB의 경우 4배정도 빠르고, 1.5 MB의 경우도 3배정도는 빨라졌습니다.

대용량 다운로드 테스트

대용량 파일은 크롬에서 진행하기 힘들어서 curl 명령어를 이용해 전체 다운로드 소요시간, 평균 다운로드 속도를 100 MB 파일은 3번, 1.5 GB는 1번 시도해서 얻은 결과값입니다. URL에는 저용량과 마찬가지로 HTTPS입니다.

  • 도쿄
    • 100 MB
      • 12s (8078 KB/s)
      • 18s (5162 KB/s)
      • 13s (7115 KB/s)
    • 1.5 GB
      • 4m 9s (6631 KB/s)
  • 서울
    • 100 MB
      • 6s (14.6 MB/s)
      • 7s (12.8 MB/s)
      • 7s (12.4 MB/s)
    • 1.5 GB
      • 1m 45s (15.3 MB/s)

대용량 파일에서는 속도 및 시간이 2배 빨리진것을 확인할 수 있습니다.

가격 비교

전체적으로 2배이상 빨라진 S3의 스토리지 및 네트워크 가격 비교입니다.

  • 스토리지
    • 도쿄 : 1 GB당 $0.033 ~ $0.0302
    • 서울 : 1 GB당 $0.0314 ~ $0.0287
  • 요청 요금(GET 요청만 비교)
    • 도쿄 : GET 요청 1만건당 $0.0037
    • 서울 : GET 요청 1만건당 $0.0035
  • 데이터 전송 요금
    • 도쿄 : 1 GB당 $0.140 ~ $0.120
    • 서울 : 1 GB당 $0.126 ~ $0.108

S3는 스토리지보다 전송요금 때문에 많이 나오기 마련인데 도쿄보다는 저렴합니다. 그래도 미국이나 유럽보다 2배정도 비싸네요 ㅜㅜ

S3 뿐만 아니라 서울은 도쿄보다 가격이 조금 저렴하게 측정되었습니다.

EC2

EC2 비교는 Ruby로 만들어진 간단한 sinatra 웹 어플리케이션 대해 wrk로 요청을 테스트 했습니다. 인스턴스 타입은 서비스에 많이 사용되는 m4.large, OS는 Ubuntu 14.04 를 사용했습니다.

단순히 ping 테스트만 해봤을때 지연시간은 도쿄가 40ms, 서울이 6ms 정도 였습니다.

응답시간 및 요청수 비교

`wrk http://xxx.xxx.xxx.xxxx:8080` 명령어를 사용한 스레드 한개에 대한 결과 입니다. (참고로 wrk에 옵션없이 실행했을때 2개의 스레드로 10개의 커넥션을 가지고 10초동안 테스트가 진행되었습니다.)

  • 도쿄
    • 평균 응답 시간 89.81ms
    • 초당 요청수 55.65
  • 서울
    • 평균 응답 시간 36.88ms
    • 초당 요청수 135.90

응답 시간에서 2배의 개선이 확인됩니다. 이 수치는 어플리케이션 상황에 많이 달라질수 있습니다.

가격비교

테스트에 사용한 m4.large Linux 기준입니다.

  • 온 디맨드
    • 도쿄 : 시간당 $0.174, 30일 기준 $125.28
    • 서울 : 시간당 $0.165 , 30일 기준 $118.8
  • 1년계약 전체 선결제
    • 도쿄 : $799
    • 서울 : $758

서울에는 현재 스팟 인스턴스가 없습니다

데이터 전송 비용

EC2에서 인터넷으로 데이터 송신하는데 들어가는 비용입니다.

  • 도쿄 : 1 GB당 $0 ~ $0.120
  • 서울 : 1 GB당 $0 ~ $0.108

그외 비용

  • Elastic IP : 동일
  • ELB 시간당
    • 도쿄 : $0.027
    • 서울 : $0.025
  • ELB가 처리한 GB 단위 데이터당 요금 : 동일

정리

서울 리전이 생기면서 네트워크 속도가 2배 이상 빨라진걸 확인할 수 있었습니다. 마음 같아서는 지금이라도 당장 이전하고 싶지만 대부분 저처럼 1년 혹은 3년단위로 계약해서 사용하기 때문에 계약 기간이 끝나기전까지는 옮기지 못할것으로 보입니다.

미국은행 계좌가 있는경우는 AWS 마켓플레이스를 통해 EC2 선결제한것을 사용자 끼리 사고 팔수 있지만 저는 미국은행 계좌가 없거든요 ㅜㅜ

어차피 리전을 이동하는게 쉬운일은 아니라서 지금부터라도 새로 생성되는 서버는 서울에 두고 천천히 옮겨가는게 좋겠지요 ^^ 리전 이동에 대해서는 “AWS CLOUD Advanced 2. AWS를 활용한 글로벌 아키덱처 운용 전략” 영상이 도움이 될것입니다.

참고정보

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

루비 mysql2 젬 MySQL 5.7에서 사용하기

최근 rorlab.org  홈페이지 이전중 DB를 MySQL 5.7로 업그레이드 하면서 겪었던 문제입니다

MySQL 5.7로 업그레이드 하고 레일스 콘솔이나 asset precompile 등을 하다보면 다음과 같은 에러가 발생합니다.

NameError: uninitialized constant Mysql2::Client::SECURE_CONNECTION

이 에러는 MySQL 5.7 에서 무언가 기능이 빠지면서 발생하는 문제였습니다. 해결방법은 간단하게도 최신버전의 mysql2 gem을 사용하는것입니다.

bundle update mysql2 
혹은 
gem update mysql2

위의 두 명령어중 본인의 상황에 맞게 실행하면 됩니다. 아마 대부분 bundler를 사용할테니 첫번째 명령어를 사용하게 될겁니다.

rorlab.org에서 사용하던 mysql2 젬의 버전은 0.3.16 이었고 업데이트 후에는 0.4.2 였습니다.

그런데 여기서 다시 서버를 시작하거나 콘솔을 시작하면 생뚱 맞은 에러가 발생합니다.

Gem::LoadError Specified 'mysql2' for database adapter, but the gem is not loaded. 
Add `gem 'mysql2'` to your Gemfile

Gemfile에 mysql2 젬이 없다네요. 어 분명히 넣었으니까 아까 에러도 났는데? 이상하죠. 이는 ActiveRecord를 사용하는 경우 mysql2 최신 젬버전과 호환이 되지 않기 때문에 발생하는 에러입니다. Gemfile을 열고 다음과 같이 변경합니다.

gem 'mysql2', '~> 0.3.18'

mysql2 최신 버전인 0.4 를 사용하지 않도록 하는게 핵심입니다. 수정후 bundle update 하거나 bundle install 합니다.

이제는 문제가 없을겁니다 ^^

MySQL 5.7은 마이너 버전번호가 바뀐것 치고는 어플리케이션들에 영향이 좀 있는것 같습니다.

추가로 꿀팁 : MySQL 5.7을 직접 설치 하신다면 MySQL 5.7 부터는 최초 설치시 root 패스워드가 랜덤생성되고 /var/log/mysqld.log에 적혀 있으니 참고하시기 바랍니다. 예전에는 루트 비밀번호가 없어서 바로 접속해서 설정했는데 이거 안되서 고생했습니다. 공식 문서에서도 언급이 안되어 있었거든요. 관련해서 제가 올린 트윗 . 그런데 생각해보면 요즘 누가 직접 MySQL 설치 하겠어요? 다들 RDS 같은거 쓰고 PostgreSQL 쓰는거 아닌가요? ㅎㅎㅎ 농담반 진담반이에요

참고링크

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

루비(Ruby) 콘솔(IRB, PRY)에서 한글 입력하기

이 글은 한국 루비 커뮤니티의 Advent Calendar 2015의 일환으로 작성했습니다. 이런 이벤트를 빌미로 글도 적게 되고 좋네요 ^^

평소에는 IRB, PRY 에서 한글 입력할 일이 없어서 신경쓰지 않고 있었는데 최근 한글 입력이 필요한 상황이 있어서 다시금 찾아보면서 정리 해봤습니다.

루비(Ruby) 2.0 부터는 기본 인코딩이 UTF-8로 변경 되었는데 왜인지 저는 이걸로 콘솔에서도 기본으로 한글 입력할 수 있다고 생각하고 있었습니다. 완전히 잘못된 생각이었죠.

IRB, PRY에서 한글을(일본어, 중국어등 UTF-8 입력에 모두 적용) 입력하려면 readline이라는 패키지가 필요하고 루비 설치시에 이 패키지를 사용하도록 해야합니다. 이미 루비가 설치 되어 있었다면 다시 컴파일 해야합니다.

readline 패키지 설치 방법은 시스템 별로 다음과 같습니다
Ubuntu:

$ apt-get install libreadline-dev

Fedora:

$yum install readline-devel

Max OS X :

$ brew install readline
$ RUBY_CONFIGURE_OPTS=--with-readline-dir="$(brew --prefix readline)" rbenv install 2.2.0

Ubuntu, Fedora는 루비를 다시 컴파일 하는것까지는 적지 않았는데 상황에 따라 컴파일 하면됩니다. Mac OS X에서는 rbenv를 사용하는 경우 위와 같이 옵션에 readline 경로를 명시해야합니다.

Max OS X에서 새로운 루비 버전을 설치할때마다 옵션을 주는것도 번거롭고 까먹으면 다시 설치해야 하는 상황이 마음에 들지 않았는지 Tim Pope가 이를 자동화 해주는 rbenv plugin을 공개했습니다.  홈 디렉토리의 rbenv 폴더 밑에 플러그인을 체크아웃하는 것으로 설치는 완료됩니다.

git clone git://github.com/tpope/rbenv-readline.git ~/.rbenv/plugins/rbenv-readline

이제부터는  rbenv install 2.2.0 과 같이 입력만 해도 readline 경로가 지정된 상태로 설치됩니다 ^^

이미 설치된 루비 버전을 다시 컴파일 한 경우 기존에 설치된 젬중 일부는 정상작동하지 않는 경우가 발생합니다. 저 같은 경우 아래와 같은 메시지가 출력되었습니다.

Ignoring bcrypt-3.1.10 because its extensions are not built. Try: gem pristine bcrypt --version 3.1.10
Ignoring binding_of_caller-0.7.2 because its extensions are not built. Try: gem pristine binding_of_caller --version 0.7.2
Ignoring byebug-8.2.0 because its extensions are not built. Try: gem pristine byebug --version 8.2.0
Ignoring byebug-8.0.0 because its extensions are not built. Try: gem pristine byebug --version 8.0.0
Ignoring byebug-4.0.5 because its extensions are not built. Try: gem pristine byebug --version 4.0.5
Ignoring curb-0.8.8 because its extensions are not built. Try: gem pristine curb --version 0.8.8
Ignoring mysql-2.9.1 because its extensions are not built. Try: gem pristine mysql --version 2.9.1
Ignoring mysql2-0.4.1 because its extensions are not built. Try: gem pristine mysql2 --version 0.4.1
Ignoring nokogiri-1.6.6.2 because its extensions are not built. Try: gem pristine nokogiri --version 1.6.6.2
Ignoring oj-2.12.12 because its extensions are not built. Try: gem pristine oj --version 2.12.12
Ignoring pg-0.18.3 because its extensions are not built. Try: gem pristine pg --version 0.18.3
Ignoring puma-2.11.2 because its extensions are not built. Try: gem pristine puma --version 2.11.2
Ignoring redcarpet-3.2.3 because its extensions are not built. Try: gem pristine redcarpet --version 3.2.3
Ignoring therubyracer-0.12.1 because its extensions are not built. Try: gem pristine therubyracer --version 0.12.1
Ignoring unicorn-4.8.3 because its extensions are not built. Try: gem pristine unicorn --version 4.8.3

gem pristine 명령어를 이용해 젬을 정리하는것 같은데 하나하나 입력하기 귀찮아서 옵션을 찾던중 gem pristine --all 을 이용하면 위에 언급된 젬 이외에 설치된 모든 젬에 대해서 실행한다는것을 알게 되어 해당 명령어를 이용했습니다. puma 젬 같은경우는 이 명령어를 이용해도 잘 되지 않아 젬을 지웠다가 다시 설치했던거 같은데 시간이 지나서 기억이 정확하지는 않네요;;

참고자료

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