증상 정리: «테스트는 되는데 왜 실사용만 안 되나»

Clash·미호모 계열에서 노드 품질을 볼 때 흔히 쓰는 TCP 지연·간단한 속도 측정은, 실제 HTTPS 사이트가 여는 전체 경로와 완전히 같지 않을 수 있습니다. 측정용 흐름은 짧은 TCP·TLS만 보고 끝나는 반면, 브라우저는 긴 세션·HTTP/2·HTTP/3(QUIC)·다중 인증서 체인까지 포함합니다. 그래서 «대시보드에서는 초록불인데 YouTube·GitHub만 handshake에서 죽는다» 같은 패턴이 자주 나옵니다.

로그에 TLS handshake failed, ssl 관련 문구, i/o timeout, context deadline exceeded 류가 섞여 나오면, 먼저 같은 노드·같은 규칙으로 단순한 대상(예: 소형 정적 페이지)과 문제 사이트를 번갈아 시험해 보세요. 한쪽만 실패하면 목적지 CDN·SNI 정책 쪽을 의심하고, 전부 실패하면 출구 인증서·시스템 시간·공유기 SSL 검사를 우선합니다. DNS 모드에 따라 이름 해석 경로가 달라 TLS까지 영향을 줄 수 있으므로, fake-ip와 redir-host 정리 글과 짝을 맞춰 읽으면 맥락이 이어집니다.

먼저 코어 버전 TLS 암호 스위트·ALPN 협상은 시간이 지날수록 바뀝니다. 증상이 특정 사이트에만 집중된다면 규칙 문제일 수도 있지만, 여러 출구에서 반복된다면 mihomo 코어 업그레이드로 협상 실패를 줄일 여지가 있습니다.

1단계: OS 시계·신뢰 저장소·인증서 체인

TLS는 인증서의 notBefore·notAfter를 OS 시계와 비교합니다. 메인보드 배터리 방전·듀얼 부트·가상 머신 스냅샷 복원 뒤에는 시각이 크게 어긋나 아직 유효한 서버 인증서도 «만료됐다»고 판단해 handshake가 깨질 수 있습니다. Windows·macOS·Linux·Android 모두 네트워크 시간 동기화를 켜고 타임존을 맞춘 뒤 다시 시험하세요.

다음으로 기업망·공항·기숙사 Wi‑Fi처럼 캡티브 포털이나 HTTPS 검사(SSL inspection)를 하는 환경인지 봅니다. 중간 장비가 자체 CA로 재서명한 인증서를 끼워 넣는데, 그 루트가 사용자 장치의 신뢰 저장소에 없으면 클라이언트는 정상적인 서버라도 «신뢰할 수 없음»으로 끊습니다. 반대로 Clash 쪽에서 «비표준 인증서를 허용»하는 옵션을 켠 상태라면, 실제로는 피싱·잘못된 출구일 수 있으니 목적지와 지문을 함께 확인해야 합니다.

구독·패널 URL 자체가 TLS에서 막히는 경우는 구독 자동 갱신·HTTPS 글에서 다룬 것처럼 User-Agent·리다이렉트·403과 섞여 나타나기도 합니다. 노드가 아니라 구독 서버의 인증서 체인 불완전(중간 인증서 누락)도 간헐적 handshake 실패를 만듭니다. 이때는 브라우저로 같은 URL을 열어 개발자 도구의 보안 탭과 비교해 보는 것이 빠릅니다.

2단계: SNI·호스트 이름·종단 불일치

클라이언트가 보내는 SNI(Server Name Indication)는 서버가 어떤 인증서를 내보낼지 고르는 기준입니다. 중계 프록시(VLESS·Trojan·VMess 등) 설정에서 servername·sni 필드가 실제 접속하려는 사이트와 다르면, 종단은 «다른 가상 호스트»로 인식해 엉뚱한 인증서를 줄 수 있습니다. 특히 CDN 앞단 호스트원본 도메인이 갈리는 서비스에서 흔합니다.

로그에 찍힌 목적 호스트와 노드 프로필에 적힌 SNI를 나란히 놓고 보세요. 한동안 잘 되다가 특정 지역 출구만 실패한다면, 그 POP가 요구하는 SNI·ALPN 조합이 바뀌었을 수도 있습니다. 가능하면 같은 노드로 curl -v 등을 써 ClientHello 직전까지 도달하는지 확인하면, «TCP는 되는데 TLS만 실패»인지 «애초에 연결이 안 된다»인지 갈립니다.

일부 상용 필터는 잘못된 SNI를 보낸 세션을 즉시 끊기 때문에, 앱이 보여 주는 메시지는 단순 timeout처럼 보일 수 있습니다. 이때는 반드시 원문 로그 한 줄을 남기고 타임스탬프를 맞추는 것이 중요합니다.

3단계: 스니펫(sniffer)·도메인 덮어쓰기 충돌

mihomo 계열이 제공하는 스니펫은 TLS ClientHello 등에서 도메인을 추출해 규칙 매칭을 돕지만, 잘못 켜 두면 실제 연결과 다른 이름으로 정책이 잡히거나, 일부 앱의 비표준 동작과 충돌합니다. «스니펫으로 고친 듯했는데 특정 은행 앱만 깨진다» 같은 제보는 대개 이 축에서 발생합니다.

점검 순서는 (1) 스니펫을 잠시 끄거나 최소 설정으로 줄여 동일 증상이 사라지는지 본 뒤, (2) override-destination·스니펫 대상 포트 범위를 필요한 만큼만 남기고, (3) DNS fake-ip·fake-ip-filter와 함께 로컬 도메인이 오탐되지 않는지 확인합니다. 스니펫은 편의 기능이지 만능 스위치가 아니라서, 문제가 재현될 때마다 로그의 도메인 라인을 기준으로 범위를 조여 가는 편이 안전합니다.

4단계: 분 앱 프록시·UWP·특정 앱 우회

안드로이드 Clash for Android의 분 앱·우회 목록은 트래픽이 Clash TUN/VPN을 탈지 말지를 가릅니다. 우회에 넣은 앱은 DIRECT로 나가므로, 그 경로에서만 캡티브 포털·차단이 걸리면 «Clash 켜면 되고 끄면 안 되는」 패턴이 뒤집혀 보이기도 합니다. 전체 증상 정리는 Android 구독·노드 타임아웃 글과 연결해 읽으면 한 번에 잡힙니다.

Windows에서는 Microsoft Store 앱(UWP)이 루프백 격리 때문에 시스템 프록시와 엇갈릴 수 있습니다. 브라우저만 정상이고 일부 스토어 앱만 TLS에서 허덕인다면 UWP 루프백·CheckNetIsolation·Clash TUN 조합을 의심하세요. macOS에서도 «Wi‑Fi에는 프록시, 이더넷에는 없음»처럼 서비스 순위가 갈리면 앱마다 다른 NIC을 탈 수 있습니다.

정리하면, 모든 앱이 동일하게 실패하는지 먼저 나누고, 특정 앱만이면 분 앱·시스템 VPN·다른 VPN 확장과의 이중 터널 여부를 보면 됩니다.

5단계: UDP·QUIC·경로와 timeout의 차이

HTTP/3는 QUIC(UDP 기반)를 씁니다. 노드나 로컬 방화벽이 UDP를 막거나, 출구 NAT가 QUIC에 불리하면 브라우저는 TCP로 폴백하기도 하지만, 그 사이에 긴 stall이나 timeout이 보이기도 합니다. 반면 순수 TCP TLS handshake 실패는 로그에 보통 명확한 오류 클래스가 남습니다. 증상을 섞어서 한 가지 레이블로 부르지 말고, 같은 시각의 로그를 나란히 놓으세요.

라우팅 측면에서는 GEOIP·정책 그룹이 의도와 다르게 잡혀 «느린 DIRECT 경로»로 나가다 timeout 나는 경우와, 프록시 체인이 너무 길어 tail latency만 튀는 경우를 구분해야 합니다. TUN 모드와 시스템 프록시 모드를 바꿔도 TLS 메시지가 동일하면 출구·인증서 쪽이고, 모드에 따라 달라지면 TUN·시스템 프록시 점검 글에서 다룬 캡처 범위 문제일 가능성이 큽니다.

Discord 음성처럼 UDP 세션이 중요한 앱은 TLS 문자열과 별개로 RTC 포트를 점검해야 합니다. 채팅은 되고 음성만 끊길 때는 Discord UDP 글의 순서가 더 맞습니다.

한 장 체크리스트

  • 시간·타임존 자동 동기화 여부
  • 기업 SSL 검사·캡티브 유무와 신뢰 CA
  • 노드 프로필의 SNI·호스트와 실제 접속 이름 일치
  • 스니펫 on/off A/B와 override 범위
  • 분 앱·UWP·이중 VPN 여부
  • UDP·QUIC 차단과 로그의 timeout vs handshake 오류 구분

자주 묻는 질문

지연 테스트는 되는데 TLS handshake만 실패하면 무엇부터 보나요?

먼저 OS 시계·타임존이 맞는지 확인한 뒤, 기업용 안티바이러스·SSL 검사·캡티브 포털이 중간에서 인증서를 바꾸지 않는지 봅니다. 그다음 노드가 기대하는 SNI·프로토콜과 클라이언트 로그의 서버 이름이 일치하는지, 스니펫으로 덮어쓴 도메인이 충돌하지 않는지 순서대로 좁힙니다.

SNI가 TLS 핸드셰이크 실패와 어떤 관련이 있나요?

클라이언트가 ClientHello에 실어 보내는 SNI는 가상 호스트 기반으로 올바른 인증서를 고르는 힌트입니다. 중계 노드가 다른 호스트 이름으로 종료하거나, 스니펫이 잘못된 이름을 붙이면 서버는 엉뚱한 인증서를 내보내 handshake가 깨질 수 있습니다. 로그에 표시되는 대상 호스트와 실제 연결 종단을 대조하세요.

분 앱 프록시 때문에 일부 앱만 연결이 끊길 수 있나요?

가능합니다. 안드로이드의 분 앱·우회 목록, Windows UWP 루프백 제한 등으로 특정 앱만 DIRECT로 나가면 TLS 경로가 달라져 증상이 갈립니다. 문제 앱이 Clash를 타는지, 시스템 VPN과 충돌하지 않는지 각 플랫폼 가이드와 함께 확인하세요.

timeout과 handshake failed를 어떻게 구분하나요?

timeout은 패킷이 도달하지 않거나 응답이 늦을 때 흔하고, handshake failed는 보통 인증서·SNI·프로토콜 불일치·중간 장비 차단처럼 TLS 레이어에서 협상이 끊긴 뒤에 남습니다. 타임스탬프를 맞춰 같은 세션에서 어떤 단계까지 진행됐는지 로그 한 줄씩 대조하면 구분이 쉬워집니다.

마무리

TLS 핸드셰이크 문제는 표면적으로는 «노드 불량»처럼 보이지만, 실제로는 시스템 신뢰·이름·앱별 경로가 얽힌 경우가 많습니다. 다섯 단계를 순서대로 밟으면 불필요한 규칙 대량 수정 없이도 원인 축을 빠르게 줄일 수 있습니다. 코어·클라이언트는 다운로드 페이지에서 플랫폼에 맞게 받고, 구독 링크는 안전하게 보관한 뒤 갱신 주기만 맞춰도 재현·비교 실험이 수월해집니다.

규칙 설계를 이어가려면 YAML 규칙 가이드와 함께 보시고, 다른 주제는 기술 칼럼 목록에서 고르시면 됩니다.

Clash 무료 다운로드 — 최신 빌드로 TLS 스택을 맞춘 뒤, 본문의 다섯 단계로 handshake·timeout을 체계적으로 점검해 보세요.

추가 설정이 필요하면 도움말을 참고해 주세요.