참고로 본인은 개발자가 아니다. 따라서 이 방법에 문제가 있을 수도 있다. 하지만 당장 네이버 검색으로 내 블로그에 들어왔을 때 www가 없는 경우 크롬에서 경고 화면이 뜨기 때문에, 어쩔 수 없이 이렇게 처리해 두었다.




사건의 발단


일단 사건의 발단을 간략히(?) 소개하겠다.


대략 2년 전 티스토리 공지 블로그에 아래와 같은 글이 올라왔다.


(중요) 2차 도메인 블로그의 DNS 설정 변경 요청 안내(~10/9까지)


내용은 2차 도메인을 사용하는 유저의 경우 A 레코드 대신 CNAME으로 바꾸라는 것이다. 그 이유를 추정해보면 다음과 같다.


티스토리는 Daum의 서비스인데 Daum은 카카오와 합병하였다. 그러다보니 서버 IDC 이전 작업이 꽤 있었을 것이고, 공인 IP가 변경되어야 하는 상황이 왔을 것이다. 그런데 공인 IP가 변경되면 일일이 2차 도메인을 사용하는 유저들이 A 레코드를 변경해줘야 한다. 실제로 본인은 블로그 활동을 열심히 하지 않아서 공지사항을 제때 확인하지 못하였고, 한동안 내 블로그가 접속되지 않는다는 사실을 모른채 지낸 적도 있었다. 나중에 A 레코드가 변경되었다는 사실을 알게 되어 DNS 레코드를 수정하였는데, 그 당시 유저 입장에서 화가 많이 나기도 했다.


이러한 문제 때문에 티스토리 측에서는 잦은 IP 변경으로 인한 영향도를 없애고자 2차 도메인 유저들에게 CNAME 처리를 요구하였는데, 문제는 나도 그랬지만 그동안 www 없이 사용했던 유저들이 많았다는 것이다. 그런데 CNAME은 domain root에 적용될 수 없다. 정확히 말하면 CNAME은 다른 type의 레코드와 동시에 사용될 수 없다. 그런데 domain root에는 필수적으로 SOA, NS 레코드 등이 들어간다. 따라서 CNAME은 들어갈 수 없다. 이러한 제약 때문에 어쩔 수 없이 www 레코드를 CNAME으로 host.tistory.io로 처리하게 되었고, 나중에 티스토리 측에서 공인 IP를 변경할 때도 host.tistory.io의 A 레코드만 변경하면 되기 때문에, 우리같은 유저들 입장에서는 www를 CNAME 걸어 사용한다면 IP 변경 작업에도 아무런 영향을 받지 않게 되었다.


SSL(TLS)의 등장


그런데 이번에 SSL(TLS)을 적용하면서 다시 문제가 불거지게 되었다. Let's Encrypt에서 무료로 인증서를 발급해주니까 2차 도메인 사용자들도 SSL을 사용할 수 있도록 해주겠다고 했는데... 문제는 내 블로그의 경우 www용 인증서는 발급이 되었는데 www 없이 접속하면 서버에서 targetmusic.co.kr 도메인 인증서를 제출하고 있다. 그래서 내가 서버사이드에서 www 없이 들어오면 www를 붙여서 301 URL Redirect 걸어달라고 코멘트를 남겼는데...


문제는 반대의 케이스도 있다는 것이다. www 없이 그대로 쓰고 싶은데, www 붙은 상태로 접속을 하면 보안 경고 창이 뜬다는 것이다. 따라서 사용자마다 의도하는 바가 전부 다르기 때문에 서버사이드에서 일괄적으로 www <-> non-www를 처리하는 것은 좋은 방법이 아니라는 결론을 내렸다.


Client에서 처리


따라서 나는 이 방법이 최선일지는 모르겠지만, 블로그 스킨에 javascript 코드를 삽입해서 www 없이 들어오면 www 붙여서 relocate 하도록 처리하였다. 반대의 요구도 있는 것 같아서 이렇게 포스팅을 하는 바이다.


domain => https://www.domain/


<script>
var loc = window.location;
if (loc.hostname.indexOf('.tistory.com') === -1 &&
loc.hostname.indexOf('www.') !== 0) {
var newUrl = 'https://www.' + loc.hostname + loc.pathname;
loc.replace(newUrl);
}
</script>


www.domain => https://domain/


<script>
var loc = window.location;
if (loc.hostname.indexOf('.tistory.com') === -1 &&
loc.hostname.indexOf('www.') === 0) {
var hostname = loc.hostname.replace('www.', '');
var newUrl = 'https://' + hostname + loc.pathname;
loc.replace(newUrl);
}
</script>


한계점


이 방법은 임시 조치일 뿐 근본적인 해결책이 되지는 못한다. 왜냐하면 javascript가 로딩되기 전에 먼저 TLS Handshake가 일어나기 때문이다. 이미 서버에서 유효하지 않은 인증서를 제출했기 때문에 경고 한번 먹고 시작을 한다. 그 이후에 www로 redirect 시켜주는 것은 소 잃고 외양간 고치는 격이다. 물론 그 외양간 조차 고치지 않는 것 보다는 고치는게 나아서 이렇게 처리를 해봤다.