실패한 단계부터 확인한 다음 로그 수준을 살펴보세요

Clash 로그는 ‘연결이 커널에 들어왔는지 → 어떤 규칙에 매칭됐는지 → 어떤 정책을 사용했는지 → 어느 단계에서 실패했는지’ 순서로 확인해야 합니다. warning은 이벤트의 로그 수준을 뜻할 뿐, 클라이언트 전체를 사용할 수 없다는 의미는 아닙니다. i/o timeout 로그 하나만으로 노드가 작동하지 않는다고 단정할 수도 없습니다. 같은 요청의 시간, 대상 주소, 정책, 오류를 함께 확인해야 로컬 포트, DNS, 프록시 서버 중 어디를 점검할지 판단할 수 있습니다.

# 현재 적용 중인 설정의 최상위에 병합하세요. 같은 이름의 필드를 중복으로 추가하지 마세요.
log-level: info

이 글에서는 일반적인 Clash 설정과 Clash Meta(mihomo) 커널을 다룹니다. 커널과 클라이언트에 따라 로그 형식, 필드명, 한국어 안내 문구가 다를 수 있습니다. 아래 예시는 필드 간 관계를 설명하기 위한 것으로, 모든 버전에서 그대로 출력되는 고정 문구는 아닙니다. 문제를 확인하기 전에 클라이언트 버전, 커널 이름, 커널 버전을 기록하세요. 데스크톱 앱 버전만 적어서는 충분하지 않습니다.

log-level 단계별 선택 방법

log-level은 YAML 최상위 필드이며 dns나 proxy-groups 안에 넣으면 안 됩니다. 일반적으로 사용하는 값은 silent, error, warning, info, debug입니다. 값은 warn이 아니라 warning입니다. 로그에 표시되는 WARN은 출력 레이블일 뿐, 설정에서도 같은 표기를 사용할 수 있다는 뜻은 아닙니다.

설정값출력 범위사용 상황
silent일반적인 커널 로그 출력을 중지합니다.연결 문제를 진단하기에는 적합하지 않습니다. 클라이언트 자체 메시지는 계속 출력될 수 있습니다.
error오류 이벤트출력량이 적어 유용한 연결 경고를 놓칠 수 있습니다.
warning경고 및 오류 이벤트연결 이상을 확인하기에는 적합하지만, 정상적인 트래픽 분기를 추적하기에는 부족합니다.
info일반적인 실행 정보와 그보다 심각한 이벤트규칙 매칭, 정책 선택, 기본 연결 상태 확인
debug디버그 정보 추가DNS 조회, 연결, 내부 처리 과정을 짧게 추적할 때 사용합니다.

설정을 바꿨는데 로그가 늘어나지 않는 이유

  • 아직 전환하지 않은 다른 설정이 아니라 현재 활성화된 Profile을 수정했는지 확인하세요.
  • 실행 설정이나 덮어쓰기 기능이 log-level을 다른 값으로 되돌리는지 확인하세요. 구독 원문보다 최종 적용된 설정이 판단에 더 중요합니다.
  • 클라이언트에서 제공하는 방법으로 설정을 다시 불러오세요. 실행 중 설정 변경을 지원하는 클라이언트라면 설정에서 조정할 수 있으므로 시스템을 반복해서 재시작할 필요는 없습니다.
  • 로그 뷰어의 키워드 및 로그 수준 필터를 해제한 뒤 새 요청을 보내세요. 이전 로그는 debug로 바꿔도 세부 정보가 추가되지 않습니다.

설정을 불러오지 못했다면 시작 로그나 클라이언트의 커널 출력을 확인하세요. 로그 목록이 비어 있는 이유가 커널이 아직 시작되지 않았기 때문일 수 있습니다. 이때 프록시 규칙부터 살펴볼 필요는 없습니다.

연결 로그에서 확인할 필드

연결 경로를 먼저 확인하고 로그 끝부분의 오류를 살펴보세요. 아래는 구조를 설명하기 위한 예시입니다. 출발지 주소는 로컬 임시 포트, 대상은 웹사이트의 HTTPS 포트이며 Proxy는 예시 정책 그룹 이름입니다.

[TCP] 127.0.0.1:53124 --> www.example.com:443
match DomainSuffix(example.com) using Proxy[노드 A]

[TCP] dial Proxy (match DomainSuffix/example.com)
127.0.0.1:53124 --> www.example.com:443
error: dial tcp 192.0.2.10:443: i/o timeout

여기서 192.0.2.10은 문서용 예시 주소로, 실제 사용할 수 있는 노드 주소가 아닙니다. 실제 로그의 연결 대상은 프록시 서버일 수도 있고 직접 연결하려는 대상이나 DNS 서버일 수도 있습니다. 마지막 IP만 보고 웹사이트가 다운됐다고 단정하지 마세요. 현재 아웃바운드 정책과 오류 전후의 전체 로그를 함께 확인해 커널이 어디에 연결 중인지 판단해야 합니다.

  1. 시간: 직접 테스트한 시각과 일치하는지 확인하세요. 백그라운드 앱이 앞서 만든 연결일 수도 있습니다.
  2. 네트워크 유형: TCP와 UDP는 구분해야 합니다. 웹페이지가 열린다고 게임이나 다른 UDP 앱도 정상이라는 뜻은 아닙니다.
  3. 대상: 도메인인지 IP인지, 포트가 예상과 일치하는지 확인하세요. HTTPS의 기본 포트는 보통 443입니다.
  4. 규칙과 아웃바운드: 어떤 규칙에 매칭됐는지, 어느 그룹에 들어갔는지, 그룹에서 노드, DIRECT, REJECT 중 무엇을 최종 선택했는지 확인하세요.
  5. 오류 단계: DNS 조회, TCP 연결, 프록시 핸드셰이크, 이후 데이터 읽기·쓰기 중 어느 단계에서 발생했는지 확인하세요.

dial tcp와 i/o timeout은 각각 무엇을 의미하나요?

dial tcp는 TCP 연결을 시도 중이라는 뜻이며 그 자체로 오류 원인을 나타내지는 않습니다. 뒤에 이어지는 i/o timeout, connection refused, network is unreachable 등이 실패 원인을 파악하는 단서입니다. 프록시 프로토콜 핸드셰이크, TLS 협상, 애플리케이션 요청은 서로 다른 단계에서 진행됩니다. TCP 연결에 성공했다고 전체 경로가 정상이라고 판단할 수는 없습니다.

오류 메시지확인할 수 있는 내용다음 점검 항목
dial tcp … i/o timeout지정된 주소로 TCP 연결을 설정하는 데 제한 시간이 초과됐습니다.주소와 포트를 확인하고 네트워크 경로, 서비스 접속 가능 여부, 방화벽을 점검하세요.
i/o timeout네트워크 읽기 또는 쓰기 작업이 시간 초과됐습니다. 이것만으로는 발생 단계를 알 수 없습니다.앞뒤 로그를 확인해 연결이 이미 설정됐는지, 핸드셰이크가 시작됐는지 확인하세요.
connection refused연결 거부 응답을 받았거나 네트워크 장비가 연결을 거부했습니다.수신 대기 포트와 서비스 상태를 확인하세요. DNS 모드부터 바꾸지는 마세요.
network is unreachable현재 네트워크 스택에서 사용할 수 있는 경로를 찾지 못했습니다.라우팅, 네트워크 인터페이스, IPv4 및 IPv6 연결 상태를 확인하세요.
connection reset by peer상대편이나 네트워크 경로상의 장비가 연결을 재설정했습니다.프로토콜, 서버 로그, 발생 시각을 확인하세요. 이 오류만으로 책임 소재를 단정할 수는 없습니다.
EOF데이터를 읽는 도중 연결이 종료됐습니다.핸드셰이크 단계였는지 확인해 프로토콜 설정을 점검하세요. 정상적인 연결 종료일 수도 있습니다.

모든 노드의 시간 초과와 특정 대상만의 시간 초과는 구분해야 합니다.

서로 다른 여러 서버에서 동시에 연결 시간 초과가 발생하면 로컬 네트워크, 라우팅, 방화벽, 구독 주소의 유효성을 먼저 확인하세요. 한 노드에서만 실패한다면 해당 노드의 서버 주소, 포트, 서비스 상태부터 점검해야 합니다. 같은 노드로 다른 웹사이트에는 접속되지만 특정 도메인만 실패한다면 대상 웹사이트, DNS 조회 결과, 트래픽 분기 규칙을 확인하세요. 지연 시간 테스트는 보통 특정 테스트 주소에만 연결하므로 테스트에 성공해도 모든 웹사이트에 접속할 수 있다는 보장은 없습니다.

DNS, TLS, 포트 오류 구분하기

DNS 조회 실패: 노드 도메인과 대상 도메인부터 구분하세요

lookup … no such host는 도메인 조회 실패를 나타냅니다. DNS … timeout은 DNS 요청이 제때 완료되지 않았다는 뜻입니다. 실패한 도메인이 노드 서버, 구독 서버, 방문하려는 웹사이트 중 무엇인지 먼저 확인하세요. 노드 도메인을 조회하지 못하면 프록시 연결 자체가 시작되지 않았을 수 있으므로 웹사이트 규칙을 바꾸는 것은 도움이 되지 않습니다.

시스템에서 실행한 nslookup 결과가 mihomo 내부 DNS 결과와 항상 같지는 않습니다. 특히 Fake-IP, DNS 하이재킹, 분기 DNS를 사용하는 경우 차이가 날 수 있습니다. 시스템 DNS 조회 결과를 비교 자료로 활용하되 현재 적용된 dns 설정도 함께 확인하세요. mihomo의 proxy-server-nameserver는 프록시 노드 도메인 조회에 사용됩니다. 문제를 확인할 때는 사용 중인 버전에서 지원되는지와 실제 설정 여부를 점검하고, 이 필드를 지원하지 않는 구형 커널에 그대로 적용하지 마세요.

TLS 오류: 인증서, 시스템 시간, 프로토콜 설정 확인

x509 오류는 인증서 신뢰 여부, 유효 기간, 이름 불일치와 관련된 경우가 많습니다. 먼저 시스템 날짜를 확인한 다음 노드의 TLS 활성화 여부, 서버 이름, 서버 측 요구 사항을 점검하세요. tls handshake timeout은 TLS 핸드셰이크가 제때 완료되지 않았다는 뜻이지, 반드시 인증서 오류가 있다는 의미는 아닙니다. 요청이 아직 핸드셰이크 중이라면 웹사이트가 HTTP 오류를 반환한 것으로 볼 수 없습니다.

수신 대기 실패: 먼저 로컬 접속 지점을 복구하세요

bind: address already in use는 보통 로컬 수신 주소와 포트가 이미 사용 중이라는 뜻입니다. 예를 들어 HTTP와 SOCKS를 7890에서 함께 수신하도록 설정했는데 다른 클라이언트도 같은 포트를 사용하면 커널의 로컬 접속 지점이 제대로 열리지 않을 수 있습니다. 충돌하는 프로세스를 종료하거나 포트를 바꾼 뒤 시스템 프록시, 브라우저, 터미널 설정도 함께 업데이트하세요.

# 로컬 접속 지점 예시입니다. 7890은 예시 포트이며 모든 클라이언트의 기본값은 아닙니다.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

이 코드는 필드 일부만 보여 주며 노드나 완전한 규칙은 포함하지 않습니다. 수정 전에 기존 설정에 mixed-port가 있는지 확인해 중복 키를 만들지 마세요. 로컬에서만 사용할 경우 allow-lan: false를 유지하세요. 로컬 포트 충돌을 해결하려고 LAN 수신을 허용할 필요는 없습니다.

규칙 미일치: 순서, 패턴, 최종 정책 확인

‘규칙 미일치’는 보통 문제를 설명하는 표현이며 모든 버전에서 공통으로 사용하는 오류 메시지는 아닙니다. 연결이 기본 규칙에 매칭됐거나 예상과 다른 정책 그룹에 들어갔거나 커널에 전달되지 않은 경우를 모두 이렇게 부를 수 있습니다. 규칙은 rules에 적힌 순서대로 위에서부터 확인합니다. 앞쪽에 있는 포괄적인 규칙이 연결을 먼저 처리할 수 있습니다.

# 예시: 도메인 규칙은 앞에, 기본 규칙은 뒤에 배치
# Proxy는 전체 설정에 이미 정의된 정책 그룹 또는 프록시 이름이어야 합니다.
mode: rule
rules:
  - DOMAIN-SUFFIX,example.com,Proxy
  - MATCH,DIRECT
  • 먼저 모드를 확인하세요: global은 전역 정책을, direct는 직접 연결을 사용합니다. 이 모드로는 rule 모드의 규칙 순서를 검증할 수 없습니다.
  • 그다음 대상 정보를 확인하세요: 앱이 IP에 직접 연결할 수도 있습니다. 도메인 복원 여부는 DNS 매핑, 스니핑, 실제 트래픽에 따라 달라집니다. 모든 IP 연결이 도메인 규칙에 매칭된다고 가정하지 마세요.
  • 기본 규칙을 확인하세요: MATCH,DIRECT에 매칭되는 것은 규칙이 정상적으로 실행된 결과입니다. 다만 예상과 다를 수 있으므로 앞쪽의 구체적인 규칙을 수정해야 합니다.
  • 그룹에서 선택된 항목을 확인하세요: 로그에 Proxy 그룹이 표시돼도 프록시 연결이라고 단정할 수 없습니다. 그룹에서 현재 DIRECT를 선택했다면 최종적으로는 직접 연결됩니다.
  • 업데이트로 덮어쓰이는지 확인하세요: 구독을 업데이트하면 직접 수정한 내용이 교체될 수 있습니다. 계속 유지해야 하는 규칙은 클라이언트가 지원하는 병합 또는 덮어쓰기 기능으로 추가하고, 생성된 결과도 확인하세요.

현재 트래픽에 해당하는 로그가 전혀 없다면 먼저 로컬 접속 지점을 확인하세요. 시스템 프록시 설정은 해당 설정을 따르는 앱에만 적용됩니다. 터미널, 게임, 자체 프록시를 설정한 브라우저는 다른 경로를 사용할 수 있습니다. TUN은 더 많은 IP 트래픽을 처리할 수 있지만 권한, 라우팅, 제외 설정, DNS 설정의 영향을 받습니다. TUN을 켰다는 사실만으로 모든 트래픽이 커널에 들어왔다고 볼 수는 없습니다. 필드 설명은 설정 필드 안내에서 확인할 수 있습니다.

재현 가능한 로그 분석 절차

한 번 수정할 때마다 새로운 근거를 확인할 수 있어야 문제를 효과적으로 진단할 수 있습니다. 아래 절차에서는 로컬 HTTP 프록시 주소 127.0.0.1:7890을 예로 듭니다. 설정에서 다른 포트를 사용한다면 명령의 포트도 함께 바꾸세요.

  1. 현재 Profile, 커널 버전, 프록시 모드, 선택된 노드, 로컬 수신 포트를 기록하고 로그 수준을 info로 설정하세요.
  2. 관련 없는 다운로드나 속도 측정 작업을 중지하고 현재 시각을 기록하세요. 테스트 결과를 백그라운드 연결과 혼동하지 않도록 대상 하나에만 요청을 보내세요.
  3. 아래처럼 프록시를 명시하는 명령으로 테스트하면 시스템 프록시 설정에 의존하지 않습니다. Windows PowerShell에서는 구버전 환경의 별칭 차이를 피하기 위해 curl.exe를 사용하세요.
  4. 같은 시간대의 연결 로그를 찾아 규칙과 아웃바운드를 확인한 뒤 오류 끝부분을 읽으세요. 로그가 없다면 먼저 수신 지점과 뷰어 필터를 점검하세요.
  5. 정보가 부족하면 debug로 바꾸고 같은 요청을 반복하세요. 한 번에 조건 하나만 변경해야 합니다. 예를 들어 노드만 바꾸고 DNS, 규칙, TUN을 동시에 수정하지 마세요.
  6. 문제가 해결된 것을 확인한 뒤 info로 되돌리고, 디버그 로그를 계속 쌓아 두기보다 원인과 최종 적용된 필드를 기록하세요.
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 15 --verbose https://example.com/ --output /dev/null

Windows에서 curl.exe를 사용할 때 출력 대상 /dev/null은 NUL로 바꾸면 됩니다. 여기서 10초는 curl의 연결 단계 제한 시간이고 15초는 전체 요청 제한 시간이며, 커널 내부 시간 초과 설정을 직접 변경하지는 않습니다. 명령의 --verbose 옵션은 프록시 연결과 TLS 과정을 보여 줍니다. HTTPS 요청이 HTTP 프록시를 거칠 때 CONNECT 성공은 터널이 만들어졌다는 뜻일 뿐이므로 이후 핸드셰이크와 응답도 확인해야 합니다.

로그를 공유할 때 남길 정보와 숨길 정보

도움을 요청할 때는 오류 발생 시각, 클라이언트 및 커널 버전, 관련 모드, 대상 포트, 규칙 처리 결과, 요청 전후의 연속된 로그를 제공하세요. 마지막 timeout 한 줄만 캡처하는 것보다 한 번 재현하기 전후의 로그 약 10~30줄을 남기는 편이 원인을 찾기 쉽습니다. 설정 일부를 공유할 때는 계층 구조와 필드명을 유지하되 서비스 접속에 사용할 수 있는 인증 정보는 삭제하세요.

  • 구독 전체 URL과 쿼리 매개변수, 노드 비밀번호, UUID, 액세스 토큰, 제어 인터페이스의 secret은 숨기세요.
  • 필요하다면 실제 도메인, LAN 주소, 노드 주소를 숨기세요. 단, 같은 대상을 일관된 대체 이름으로 표시해 서로의 관계를 파악할 수 있게 하세요.
  • 오류 유형, 대상 포트, TCP/UDP 유형, 규칙 순서는 결론에 직접 영향을 주므로 그대로 남기세요.
  • 문제 해결 자료로 구독 파일 전체를 기본적으로 업로드하지 마세요. 노드 수가 많아도 재현 절차가 없으면 도움이 되지 않습니다.

최종 진단은 구체적인 단계로 좁혀야 합니다. 요청이 로컬 접속 지점에 들어오지 않았는지, 규칙 선택이 잘못됐는지, 노드 연결에 실패했는지, 프로토콜 핸드셰이크가 실패했는지, 대상이 오류를 반환했는지 분류하세요. 먼저 원인을 구분한 뒤 수정하면 클라이언트를 반복해서 재설치하거나 모든 설정을 한꺼번에 초기화하는 것보다 유용한 단서를 더 잘 보존할 수 있습니다.