1. 라이브러리
  2. 포트
  3. 포트 설정

업데이트됨 1개월 전

초기 웹에서는 각 웹사이트마다 고유한 IP 주소가 필요했습니다. IPv4 주소가 부족해지면서 이는 불가능한 일이 되었습니다. 가상 호스팅이 이 문제를 해결했습니다: 하나의 IP 주소, 하나의 포트, 수백 개의 웹사이트.

방법은 간단합니다. TCP 연결은 서버에게 목적지를 알려줍니다—IP 주소와 포트 번호입니다. 가상 호스팅은 여기에 '누구를 찾고 있는가'를 추가합니다—도메인 이름입니다. 서버는 이 이름을 사용해 올바른 웹사이트로 요청을 전달합니다.

이름 기반 가상 호스팅

브라우저가 http://example.com/page.html을 요청할 때, 단순히 IP 주소에만 연결하는 것이 아닙니다. Host 헤더도 함께 보냅니다: Host: example.com. 웹 서버는 이 헤더를 읽고 올바른 사이트로 요청을 전달합니다.

바로 이 때문에 blog.example.com, shop.example.com, api.example.com의 DNS 레코드가 모두 같은 IP 주소를 가리킬 수 있습니다. 서버는 Host 헤더로 이들을 구분하여, 각각 다른 디렉토리에서 서비스하거나 다른 백엔드로 프록시합니다.

Host 헤더는 바로 이 목적을 위해 HTTP/1.1에서 도입되었습니다. HTTP/1.0에는 원하는 도메인을 지정하는 방법이 없었습니다—여러 사이트가 IP 주소를 공유하는 경우, 서버가 추측해야 했습니다.

Nginx와 Apache 같은 웹 서버는 가상 호스트 블록으로 이를 설정합니다. 각 블록은 서버 이름을 지정하고, 해당 이름으로 요청이 들어왔을 때 어떻게 처리할지 정의합니다. 와일드카드도 사용할 수 있습니다: *.example.com은 하나의 규칙으로 모든 서브도메인을 처리합니다.

HTTPS 문제

HTTPS는 이 모델을 깨뜨립니다. TLS 핸드셰이크는 HTTP 헤더가 교환되기 전에 일어납니다. 서버는 SSL 인증서를 제시해야 하는데, 어떤 것을 선택해야 할까요? 아직 Host 헤더를 읽을 수 없습니다—연결이 암호화되지 않은 상태라 읽을 수 있는 HTTP가 없습니다.

이것은 전형적인 닭이 먼저냐 달걀이 먼저냐의 문제입니다. 서버는 올바른 인증서를 선택하기 위해 도메인을 알아야 합니다. 하지만 암호화된 연결이 성립되기 전까지는 도메인을 알 수 없습니다. 그리고 인증서를 선택하지 않고는 암호화된 연결을 수립할 수 없습니다.

SNI(Server Name Indication)는 이 딜레마를 영리하게 우회합니다. TLS 핸드셰이크 중, 암호화가 시작되기 전에, 클라이언트가 도메인 이름을 평문으로 전송합니다. 서버는 이를 읽어 올바른 인증서를 선택한 후 암호화를 진행합니다. 보안 터널이 만들어지면 HTTP는 Host 헤더 라우팅으로 정상적으로 계속됩니다.

SNI는 이제 모든 브라우저와 서버에서 보편적으로 사용됩니다. SNI를 지원하지 않는 구형 클라이언트가 있다면, 관리자는 와일드카드 인증서나 여러 도메인을 나열한 인증서(Subject Alternative Names)를 사용해야 합니다. 그렇지 않으면 인증서가 기대한 것과 일치하지 않을 때 해당 클라이언트에 보안 경고가 표시됩니다.

IP 기반 가상 호스팅

다른 방법은 각 웹사이트에 자체 IP 주소를 부여하는 것입니다. 서버는 하나의 네트워크 인터페이스에 여러 IP를 바인딩하고, 모두 같은 포트에서 수신 대기합니다. 라우팅은 목적지 IP를 기반으로 이루어지므로 헤더가 필요 없습니다.

이는 HTTP뿐만 아니라 모든 프로토콜에서 작동합니다. Host 헤더나 SNI를 전송하지 않는 구형 클라이언트도 지원합니다. 일부 규정 준수 요구 사항은 격리를 위해 전용 IP를 요구하기도 합니다.

비용은 명백합니다: IPv4 주소가 고갈되었습니다. 많은 지역에서 여러 주소를 취득하는 것은 비싸거나 불가능합니다. IPv6는 이 상황을 바꿉니다—주소가 사실상 무제한입니다—하지만 대부분의 네트워크에서는 여전히 IPv4가 지배적입니다.

리버스 프록시와 로드 밸런서

현대 인프라는 한 겹을 더합니다. Nginx, HAProxy, Traefik 같은 리버스 프록시는 애플리케이션 서버 앞에 위치하여 모든 트래픽을 수신하고, 단순한 Host 헤더 매칭보다 훨씬 정교한 규칙에 따라 라우팅합니다.

이 시스템들은 URL 경로(/api/*는 API 서버로, /static/*는 CDN으로), HTTP 메서드, 커스텀 헤더, 심지어 요청 본문 내용에 따라서도 라우팅합니다. 포트 443의 단일 로드 밸런서가 수십 개의 서로 다른 백엔드 서비스로 트래픽을 전달할 수 있습니다.

SSL 종료도 처리합니다—진입점에서 HTTPS를 복호화하여 사설 네트워크의 백엔드에 일반 HTTP로 전달합니다. 이는 인증서 관리를 중앙화하고 애플리케이션 서버의 부하를 줄입니다. 프록시는 SNI를 읽어 올바른 인증서를 선택한 후, 복호화된 요청(Host 헤더 그대로)을 처리해야 할 백엔드로 전달합니다.

컨테이너화된 환경에서는 이 라우팅이 자동으로 업데이트됩니다. 서비스가 확장되거나 축소될 때, Kubernetes와 같은 서비스 디스커버리 시스템이 로드 밸런서 설정을 업데이트합니다. 수동 변경이 필요 없습니다.

가상 호스팅에 대해 자주 묻는 질문

가상 호스트를 사용하여 같은 포트에서 서로 다른 애플리케이션을 호스팅할 수 있나요?

네. 가상 호스팅은 각 도메인 뒤에 무엇이 있는지 상관하지 않습니다. 한 도메인은 정적 파일을 제공하고, 다른 도메인은 Node.js 앱으로 프록시하며, 또 다른 도메인은 Python 서비스로 연결할 수 있습니다. 웹 서버나 로드 밸런서가 도메인 이름을 기반으로 라우팅한 후, 설정한 백엔드로 넘깁니다.

누군가 도메인 이름 대신 IP 주소로 접속하면 어떻게 되나요?

Host 헤더가 없거나 Host 값으로 IP 주소가 포함된 요청이 들어옵니다. 대부분의 서버에는 이러한 요청을 처리하는 기본 가상 호스트가 있습니다—일반적으로 일반 페이지를 표시하거나, 오류를 보여주거나, 다른 곳으로 리다이렉트합니다. 이 동작은 서버 설정에서 제어할 수 있습니다.

SNI는 내가 방문하는 웹사이트를 노출하나요?

네. SNI의 도메인 이름은 암호화가 시작되기 전에 평문으로 전송됩니다. 연결을 모니터링하는 누구든 통신 내용은 볼 수 없더라도 어떤 도메인에 접속하는지는 알 수 있습니다. ECH(Encrypted Client Hello)가 이 문제를 해결합니다—7년간의 개발 끝에 2024년 발행 승인을 받았으며, 현재 Firefox와 Chrome을 포함한 주요 브라우저에 배포되었습니다1.

하나의 서버에서 몇 개의 가상 호스트를 운영할 수 있나요?

엄격한 제한은 없습니다. 서버는 보통 수백에서 수천 개의 가상 호스트를 운영합니다. 실질적인 한계는 메모리(각 설정이 일부를 소비함), HTTPS를 위한 인증서 관리의 복잡성, 그리고 설정 유지에 드는 관리 부담입니다. 공유 호스팅 업체들은 종종 단일 서버에서 수만 개의 사이트를 운영합니다.

출처

이 페이지가 도움이 되었나요?

😔
🤨
😃
같은 포트에서 여러 서비스 실행하기 (가상 호스트) • 라이브러리 • Connected