1. SNI(Server Name Indication)란?
SNI(Server Name Indication)는 클라이언트가 서버에 HTTPS 요청을 보낼 때, TLS 핸드쉐이크 과정에서 어떤 도메인 이름을 요청할 것인지 명시적으로 전달하는 TLS 확장 기능. 이를 통해 하나의 서버에서 여러 도메인을 호스팅할 수 있음.
openssl s_client -connect example.com:443 -servername example.com
2. Web 서버 별 동작 방식
- Apache의 기본 동작 방식
Apache 웹 서버는 SNI 없이도 기본 SSL 인증서를 반환한다.
예를 들어, Apache에 example.com과 example.org 두 개의 도메인을 설정했다고 가정 했을 때
// Apache 설정 예시 (VirtualHost):
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/ssl/example.com.crt
SSLCertificateKeyFile /etc/ssl/example.com.key
</VirtualHost>
<VirtualHost *:443>
ServerName example.org
SSLEngine on
SSLCertificateFile /etc/ssl/example.org.crt
SSLCertificateKeyFile /etc/ssl/example.org.key
</VirtualHost>
SNI가 없는 요청이 오면 Apache는 기본적으로 첫 번째 VirtualHost(example.com)에 설정된 인증서를 반환한다.
이는 클라이언트가 SNI를 지원하지 않더라도 요청을 처리할 수 있게 해준다.
- Nginx Proxy Manager(NPM)의 SNI 기반 동작
Nginx Proxy Manager는 SNI 기반으로 동작하며, SNI 없는 요청을 처리할 기본 호스트가 자동으로 설정되지 않는다.
example.com과 example.org를 각각 npm에 설정했다고 가정했을 때 클라이언트가 SNI 정보를 포함하지 않고 서버에 요청을 하면 연결을 거부한다.
3. NPM의 SNI 없는 요청 처리 방법
1) Default Host 설정
SNI를 지원하지 않는 클라이언트를 고려해야 한다면 수동으로 "Default Host"를 설정한다.
2) 클라이언트에서 SNI 명시
SNI가 없는 요청을 방지하기 위해 클라이언트 측에서 SNI를 명시적으로 설정한다.
NPM은 수동 설정을 최소화하고 GUI 기반으로 쉽게 관리할 수 있도록 설계된 도구이므로, 최신 클라이언트를 사용하는 환경에서는 SNI 명시를 통해 문제를 해결하는 것이 바람직하다고 생각한다.
만약 구형 클라이언트를 지원해야 한다면 1) 의 Default Host 설정을 통해 SNI가 없는 경우의 요청을 처리하면 되겠다.
4. 정리
Apache와 Nginx Proxy Manager는 SNI 처리 방식에 차이가 있으므로, 사용하는 환경과 클라이언트 특성에 맞는 설정이 필요하다. 아래의 기준을 참고하세요:
- 최신 클라이언트 사용: 클라이언트가 SNI를 명시적으로 설정하도록 유도합니다.
- 구형 클라이언트 지원 필요: NPM에서 Default Host를 설정합니다.