도메인 하나를 확보하면 그 아래에 이름을 얼마든지 더 만들 수 있다. 등록한 도메인 앞에 이름을 붙여 만드는 이 하위 이름이 서브도메인이다. 서브도메인은 추가 등록이나 비용 없이 소유자가 자유롭게 만들 수 있는 하위 계층이며, 서비스를 갈래별로 나누는 가장 기본적인 수단이다. 웹, 관리자 화면, 개발 환경, 부속 서비스를 각기 다른 서브도메인에 두는 구성은 거의 모든 서비스에서 발견된다.


이번 편은 서브도메인을 어떻게 설계하는지를 다룬다. 서브도메인이 계층을 어떻게 확장하는지, 하나의 서브도메인이 별도의 호스트로 어떻게 동작하는지, 서브도메인 사이에 출처와 쿠키의 경계가 어떻게 놓이는지, 여러 이름을 한꺼번에 처리하는 와일드카드는 무엇인지, 그리고 서브도메인을 나눌 때 어떤 원칙과 함정이 있는지를 차례로 짚는다. 서브도메인을 잘 설계하면 서비스 구조가 이름만으로도 읽힌다.


계층을 확장하는 하위 이름


서브도메인은 등록한 도메인 앞에 점으로 구분된 이름을 덧붙여 만든다. 등록한 도메인이 하나의 관리 구역이라면, 그 아래의 서브도메인은 같은 구역 안에서 새로 정의하는 이름이다. 소유자는 이 하위 이름을 마음대로 만들고 지울 수 있으며, 각 서브도메인마다 서로 다른 서버를 가리키게 할 수 있다. 하위 이름을 만드는 데 별도의 등록 절차가 필요 없다는 점이 서브도메인의 가장 큰 장점이다.


서브도메인은 다시 그 아래에 또 다른 서브도메인을 둘 수 있다. 이름은 이론적으로 여러 단계까지 깊어질 수 있지만, 실무에서는 대개 한두 단계에서 멈춘다. 단계가 깊어질수록 이름이 길어지고 관리가 복잡해지며, 사용자가 기억하기도 어려워진다. 계층을 깊게 파기보다 필요한 만큼만 나누고 이름을 간결하게 유지하는 편이 낫다.


서브도메인을 만드는 실제 작업은 존에 레코드를 추가하는 것으로 끝난다. 새 서브도메인 이름에 주소 레코드나 별칭 레코드를 붙이면, 그 이름이 곧바로 살아나 지정한 서버를 가리킨다. 등록한 도메인과 같은 존 안에서 관리되므로, 서브도메인의 추가와 삭제는 레코드 편집만으로 즉시 이루어진다. 이 즉시성 덕분에 서브도메인은 서비스를 유연하게 늘리고 줄이는 수단이 된다.


서브도메인을 별도의 네임서버에 위임하는 것도 가능하다. 특정 서브도메인의 관리를 다른 팀이나 다른 서비스에 넘길 때, 그 서브도메인만 별도 네임서버로 위임하면 관리 권한이 분리된다. 이렇게 하면 큰 조직에서 각 부서가 자기 서브도메인을 독립적으로 관리할 수 있다. 위임은 등록한 도메인 계층에서만 일어나는 것이 아니라 서브도메인 계층에서도 똑같이 적용된다. 관리의 경계를 이름의 경계와 맞추어 두면, 각 팀은 자기 이름 아래만 신경 쓰면 되고 서로의 변경이 충돌하지 않는다.


서브도메인은 별도의 호스트


서브도메인은 이름만 나뉜 것이 아니라 기술적으로 별개의 호스트로 취급된다. 브라우저와 서버는 서브도메인이 다르면 서로 다른 목적지로 보고 각각 연결을 맺는다. 그래서 하나의 서브도메인은 완전히 다른 서버, 다른 지역, 다른 서비스 제공자를 가리킬 수 있다. 대표 웹은 자체 서버에, 이미지 전송은 외부 전송망에, 관리 도구는 또 다른 곳에 두는 식의 구성이 자연스럽게 이루어진다.


이 별개성은 서비스를 물리적으로 분리하는 데 유용하다. 트래픽이 몰리는 부분을 별도 서브도메인으로 떼어 전용 서버에 두면, 그 부분의 부하가 다른 부분에 영향을 주지 않는다. 부속 서비스에 문제가 생겨도 대표 웹은 멀쩡하고, 각 서브도메인을 독립적으로 확장하거나 교체할 수 있다. 서브도메인의 분리는 곧 장애의 격리와 확장의 유연성을 뜻한다.


서브도메인마다 다른 인증서가 필요하다는 점도 별개 호스트라는 성격에서 나온다. 보안 연결을 위한 인증서는 특정 이름에 대해 발급되므로, 서브도메인이 다르면 그 이름을 포함하는 인증서가 따로 있어야 한다. 여러 서브도메인을 한 인증서로 묶는 방법도 있지만, 근본적으로 각 서브도메인은 자기 이름에 대한 신원 증명을 갖추어야 보안 연결이 성립한다. 인증서 관리는 서브도메인 설계와 함께 고려해야 할 요소다.


별개 호스트라는 성격은 검색 엔진의 관점에도 영향을 준다. 검색 엔진은 서브도메인을 어느 정도 별개의 사이트로 다루는 경향이 있어, 대표 도메인에서 쌓은 평판이 서브도메인에 그대로 이어지지 않을 수 있다. 그래서 핵심 콘텐츠를 서브도메인에 둘지 하위 경로에 둘지는 검색 노출 전략과 얽히는 결정이 된다. 이 문제는 뒤의 검색 편에서 더 깊이 다룬다.


출처와 쿠키의 경계


브라우저의 보안 모델에서 출처는 이름과 방식과 포트의 조합으로 정의된다. 서브도메인이 다르면 이름이 다르므로 출처도 다르다. 즉 app.example.comapi.example.com은 서로 다른 출처로 취급되어, 한쪽의 스크립트가 다른 쪽의 자원에 접근할 때 교차 출처 규칙의 제약을 받는다. 서브도메인으로 서비스를 나누면 이 출처의 경계를 함께 설계해야 한다.


이 경계는 보안에 이점을 준다. 서로 다른 출처는 기본적으로 격리되므로, 한 서브도메인이 침해되어도 다른 서브도메인의 자원에 곧바로 접근하지 못한다. 민감한 관리 기능을 별도 서브도메인에 두어 출처를 분리하면, 대표 웹에서 발생한 스크립트 공격이 관리 기능으로 번지기 어려워진다. 출처의 분리는 공격의 확산을 막는 벽이 된다.


반대로 서브도메인 사이에 자원을 공유해야 한다면 교차 출처 허용을 명시적으로 설정해야 한다. 한 서브도메인의 스크립트가 다른 서브도메인의 데이터를 부를 수 있게 하려면, 서버가 그 출처를 허용한다는 응답을 함께 보내야 한다. 이 허용을 지나치게 넓게 열면 보안 격리의 이점이 사라지므로, 꼭 필요한 출처만 좁게 허용하는 것이 원칙이다.


쿠키는 출처와는 조금 다른 규칙을 따른다. 쿠키는 도메인 범위를 지정해 상위 도메인에 걸어 두면 여러 서브도메인이 공유할 수 있다. 이 성질은 여러 서브도메인에서 하나의 로그인 상태를 유지할 때 유용하지만, 동시에 한 서브도메인에서 새어 나간 쿠키가 다른 서브도메인에까지 영향을 미칠 위험을 낳는다. 쿠키의 도메인 범위는 편의와 위험을 저울질해 신중하게 정해야 한다.


와일드카드 서브도메인


와일드카드는 정의되지 않은 모든 서브도메인을 한꺼번에 처리하는 특별한 레코드다. 이름 자리에 별표를 두면, 명시적으로 정의된 이름을 제외한 나머지 모든 하위 이름이 이 레코드의 값으로 응답한다. 사용자마다 고유한 서브도메인을 부여하는 서비스처럼, 미리 이름을 다 알 수 없는 경우에 와일드카드가 유용하다. 이름 하나하나를 등록하지 않고도 무한한 하위 이름을 살아 있게 만들 수 있다.


와일드카드는 편리하지만 통제를 느슨하게 만든다. 정의되지 않은 모든 이름이 응답하게 되므로, 존재하지 않아야 할 이름조차 유효한 것처럼 보인다. 오타로 접속한 사용자가 엉뚱한 서브도메인에서 서비스를 받거나, 공격자가 임의의 서브도메인을 만들어 악용할 여지가 생긴다. 와일드카드를 쓸 때는 뒤의 서버가 요청받은 이름을 검사해 허용된 이름만 처리하도록 방어를 함께 두어야 한다.


와일드카드 인증서는 이 구성과 짝을 이룬다. 특정 상위 도메인 아래의 모든 서브도메인을 포괄하는 인증서를 발급받으면, 새 서브도메인이 생길 때마다 인증서를 따로 발급하지 않아도 보안 연결이 성립한다. 다만 와일드카드 인증서 하나가 유출되면 그 아래 모든 서브도메인이 위험해지므로, 이 인증서의 개인 키는 특히 엄격하게 보관해야 한다.


와일드카드는 명시적으로 정의된 레코드보다 우선순위가 낮다. 특정 서브도메인에 별도의 레코드가 정의되어 있으면 그 이름은 와일드카드가 아니라 자기 레코드로 응답한다. 이 우선순위 덕분에 대부분을 와일드카드로 처리하면서도 몇몇 특별한 서브도메인만 따로 지정하는 혼합 구성이 가능하다. 와일드카드는 기본값을 정하고, 개별 레코드는 예외를 정하는 셈이다.


서브도메인 설계의 원칙


서브도메인을 나눌 때 첫 번째 원칙은 이름이 역할을 드러내게 하는 것이다. 무엇을 하는 서비스인지가 이름에서 곧바로 읽히면, 구조를 따로 설명하지 않아도 이름만으로 시스템의 지도가 그려진다. 규칙 없이 즉흥적으로 만든 이름들이 쌓이면 나중에 어느 서브도메인이 무엇을 하는지 아무도 모르게 된다. 일관된 이름 규칙을 먼저 정해 두는 것이 좋다.


두 번째 원칙은 보안 경계를 이름 구조에 반영하는 것이다. 민감도가 다른 기능은 서로 다른 서브도메인에 두어 출처를 분리하고, 신뢰 수준이 낮은 콘텐츠는 대표 도메인과 격리된 별도 서브도메인에 두는 것이 안전하다. 사용자가 올린 콘텐츠를 대표 도메인에서 직접 서비스하면 스크립트 공격의 통로가 되므로, 이런 콘텐츠는 격리된 서브도메인으로 떼어 내는 구성이 널리 쓰인다.


세 번째 원칙은 확장을 미리 염두에 두는 것이다. 지금은 서비스가 단순해도 나중에 갈래가 늘어날 수 있으므로, 처음부터 여유 있는 이름 체계를 잡아 두면 나중에 이름을 바꾸는 고통을 던다. 이름을 바꾸는 일은 링크와 인증서와 사용자의 기억을 모두 흔들기 때문에, 서브도메인 구조는 한번 정하면 오래 유지할 각오로 설계해야 한다.


네 번째 원칙은 개발과 운영 환경을 이름으로 구분하되 노출을 통제하는 것이다. 개발용 서브도메인을 대표 도메인 아래에 두면 관리가 편하지만, 그 이름이 외부에 그대로 노출되면 완성되지 않은 기능이 검색되거나 공격의 표적이 된다. 내부용 이름은 접근을 제한하고 검색에서 가리는 조치를 함께 두어야 한다.


실무에서 겪는 함정


가장 흔한 함정은 뿌리 이름과 앞자리가 붙은 이름을 혼동해 다루는 것이다. 등록한 도메인의 뿌리 이름에는 별칭을 걸기 어렵다는 제약이 있어, 뿌리와 서브도메인을 같은 방식으로 설정하려다 실패하는 경우가 잦다. 뿌리는 직접 주소를 가리키고 서브도메인은 별칭으로 외부 서비스를 가리키는 식으로, 두 이름의 설정 방식이 다를 수 있음을 이해해야 한다.


와일드카드를 쓰면서 개별 예외를 빠뜨리는 것도 함정이다. 대부분을 와일드카드로 처리하다 보면, 특별히 다르게 동작해야 할 몇몇 이름에 별도 레코드 두는 것을 잊는다. 그 결과 특정 서브도메인이 와일드카드에 휩쓸려 엉뚱한 서버로 향한다. 와일드카드를 도입할 때는 어떤 이름이 예외로 빠져야 하는지를 함께 목록으로 정리해 두어야 한다.


쿠키의 도메인 범위를 지나치게 넓게 잡는 것도 자주 겪는 실수다. 편의를 위해 상위 도메인 전체에 쿠키를 걸어 두면, 신뢰 수준이 낮은 서브도메인까지 그 쿠키를 받게 되어 세션이 새어 나갈 통로가 열린다. 쿠키는 꼭 필요한 범위에만 걸고, 민감한 세션 쿠키는 그 세션이 쓰이는 서브도메인에 한정하는 것이 안전하다.


마지막 함정은 서브도메인을 위임한 뒤 방치하는 것이다. 어떤 서브도메인을 외부 서비스에 위임해 두었는데 그 서비스를 더는 쓰지 않게 되면, 남은 위임 레코드가 방향을 잃은 이름으로 남는다. 이렇게 버려진 위임은 다른 사람이 그 자리를 차지해 도메인의 이름으로 악용하는 통로가 될 수 있다. 쓰지 않게 된 서브도메인 위임은 반드시 정리해야 한다. 이렇게 서브도메인의 확장, 별개 호스트로서의 성격, 출처와 쿠키의 경계, 와일드카드, 설계 원칙과 함정까지 이해하면 도메인 하나를 여러 서비스로 정돈되게 펼칠 수 있다. 다음 편은 이 레코드 변경이 실제로 퍼지는 과정을 다루는 전파와 유효 기간이다.