아이폰 6s, 6s+ iOS 9.3.1 비번없이 사진, 연락처 확인하는 버그

iOS 9.3.1 에서 비밀번호를 모르는 상태에서도 사진과 연락처를 확인하는 방법이 알려졌습니다. 시리를 이용해서 가능한데요. 제가 해당 상황을 재현해봤고 쉽게 성공할 수 있었습니다. 아래 영상을 확인해보세요.

영상에서 볼수 있듯이 생각보다 쉬운 방법으로 사진과 연락처에 접근이 가능합니다. 이 버그는 아이폰 6s, 6s+에 추가된 3D 터치로 인해 발생되는거라서 아이폰 6 이하 기종이나 아이패드는 해당사항이 없습니다.

정확한 상황을 말씀드리자면 최초에 시도는 트위터 계정을 연결? 할거냐는 식으로 물어보면서 비번을 입력하라고 해서 실패했습니다. 하지만 거기서 허용하고나서 부터는 위와 같은 현상이 재현되었습니다. 그 이후에는 트위터 검색을 시리에서 막는 옵션을 찾지 못했습니다. 평소에 시리에서 트위터 검색을 해두신 분들은 꼭 확인해보세요.

아직 애플에서 이와 관련된 패치가 발표되지 않았으니 이 버그를 통한 사진 유출을 막기위해서는 개인정보보호에서 사진의 시리 접근 권한을 해제하는것이 좋습니다.

해당 문제는 애플이 시리서버에 패치를 하면서 해결되었습니다. 이제 더이상 문제가 발생하지 않습니다. http://www.macrumors.com/2016/04/05/apple-fixes-siri-vulnerability/

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

몰스킨이 만든 아이폰 캘린더앱 timepage

몰스킨 timepage

몰스킨 timepage

아이폰의 기본 캘린더앱을 대체하고자 하는 사람들은 꽤 많은걸로 알고 있습니다. 저도 그중에 한명이었는데요. 오늘 소개할 timepage는 제가 지금까지 써봤던 캘린더 앱 중에서 제일 만족한 앱입니다.

앱의 인터페이스가 버튼을 누르지 않아도 되도록 잘 만들었기에 그냥 스샷으로 설명하는데는 한계가 있습니다. 제가 유튜브에 올린 아래 리뷰를 보시는걸 추천드립니다.

일정 보기 방식

캘린더앱들은 대체적으로 2가지 부류로 나누어지는데요. 한달의 내역을 한눈에 확인할 수 있게 하는것들과 주간 목록위주로 보여주는것입니다. 한달내역이 한눈에 보이면 이번달에 무슨일이 있는지 확인하기 편하지만 그 안의 내용들의 글자가 너무 작고 일정이 많은 경우 보기 불편합니다. 반대로 주간으로 보면 해당 주에 할일이 한눈에 잘보이고 글자도 크지만 월간단위로 무엇을 해야할지 확인하기 힘듭니다.

저는 이중 월간단위로 보는것을 선호하는 편이었는데요. timepage를 사용하고 보니 주간목록으로 보는것이 훨씬 편하다고 느껴졌습니다. timepage는 메인에는 주간 목록이 보이고 왼쪽으로 화면을 움직이면 해당 월의 일정을 한눈에 볼 수 있습니다.

주간 목록

주간 목록

월간 보기

월간 보기

날씨와 일정의 밀접한 관계

날씨에 따라 약속이 많이 펑크 나기도 하고 무슨옷을 입을지에 영향을 주기도 합니다. timepage 에서는 이러한 일정과 날씨의 밀접한 관계를 고려해서 곳곳에서 날씨를 확인할 수 있는 장치를 마련했습니다.

날씨 확인

날씨 확인

주간 목록에서 터치를 오래동안 하고 있으면 일정이 바로 날씨로 변경됩니다. 이 날씨에는 최고/최저 온도와 함께 비올 확률도 알려줍니다. 이렇게 보여주면 굳이 날씨 앱을 따로 켜지 않아도 되고 특정 약속일에 비올 확률등도 미리 알수 있으므로 일정에 대비하는데 많은 도움이 됩니다.

시간별 날씨

시간별 날씨

또한 각 날짜별 상세 페이지 하단의 날씨 아이콘을 누르면 해당 날짜의 시간대별 날씨도 확인할 수 있고 각 일정의 상세페이지 마다는 약속 시간에 해당하는 날씨를 보여줍니다.

일정 상세

교통 수단

일정에 위치가 빠질수 없겠죠. 일정에 위치를 추가하게 되면 현재위치에서 해당 장소까지 가는데 걸리는 시간을 교통수단별로 알려줍니다. 도보/자전거/자가용으로 알려줍니다. 대중교통이 없다는건 다소 아쉽네요.

교통수단

교통수단

우버 바로 부르기

우버 바로 부르기

지도를 누르면 지도 하단에 우버 바로 부르기 버튼이 생겨서 약속 장소를 일일이 입력하지 않아도 되는 장점이 있습니다. 버튼을 누르면 우버앱으로 이동하고 목적지는 일정에 입력했던 위치로 설정된 상태가 됩니다.

다양한 지원

아이폰용 앱중에서 위젯이나 시계같은것들을 지원하는 앱들이 많지 않고 설사 지원하더라도 별 필요가 없는 경우가 많은데요. timepage는 일정을 관리하는 만큼 아주 유용합니다. 다만 아이패드 앱을 지원하지 않는다는 점은 아쉽습니다.

 

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

리디북스 페이퍼 vs 페이퍼 라이트 비교

리디북스 페이퍼(쿠팡 구매링크)는 나오기전부터 많은 사람들의 관심을 모은 전자책입니다. 저는 페이퍼가 나오자마자 300PPI 제품을 구매했는데 212PPI의 페이퍼 라이트 제품과의 사이에 많은 갈등이 있었습니다. 212PPI 제품이 저렴했고 책을 읽는데 충분하다는 이야기 때문이었죠.

그러다가 궁금증을 이기지 못하고 중고로 페이퍼 라이트를 구매해서 비교해봤습니다 !!!

우선 제가 찍은 영상을 한번 보시죠

비교의 중점은 다음과 같았습니다.

  • 사진
  • 만화
  • 작은 글씨
  • 일반 전자책

사진이나 만화 같은경우에서 PPI 차이가 많이 발생해서 읽기 불편하다는 이야기를 많이 봤었는데요. 제가 비교해본 결과로는 사진이나 만화보다 PDF의 작은 글자에서 차이가 많이 발생했습니다.

PDF 책 이모매거진의 작은 글자 비교

PDF 책 월간이모의 작은 글자 비교

ridipaper_model

페이퍼와 페이퍼 라이트의 외관상 유일한 차이점

ridipaper_weird

이미지 비교. 잘 보면 음영이 변하는 부분이 다르다

그래서 제가 내린 결론은 작은글자를 많이 볼게 아니고 일반 이북처럼 글자 크기를 조정할 수 있는 문서를 많이 본다면 페이퍼 라이트도 충분하다는것입니다.

페이퍼와 페이퍼 라이트의 가격은 6만원차이로 페이퍼 라이트 가격이 89,000원임을 감안하면 결코 작은 가격차이가 아닙니다. 이정도 가격차이라면 페이퍼 라이트의 매력이 높습니다. 물론 금전적인 여유가 된다면 눈 건강을 위해서 페이퍼 300PPI가 좋겠죠? 저는 조만간 페이퍼 라이트는 중고로 팔것 같네요 ^^

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