먼저 로그 출처와 연결 단계를 확인하세요
Clash 로그는 노드의 상태를 단순히 나열한 목록이 아닙니다. 웹페이지에 한 번 접속해도 도메인 조회, 규칙 매칭, 프록시 서버 연결, 프로토콜 핸드셰이크, 대상 사이트 접속이 차례로 일어날 수 있습니다. 오류가 발생한 단계에 따라 해결 방향도 달라집니다. 빨간 로그 한 줄만 보고 구독을 바꾸면 문제 상황을 파악하는 데 가장 유용한 단서를 놓칠 수 있습니다.
먼저 클라이언트 로그와 코어 로그를 구분하세요. 클라이언트 로그에는 보통 인터페이스, 설정 다운로드, 업데이트, 권한 문제가 기록됩니다. Clash 또는 mihomo 코어 로그에는 주로 설정 로드, 리스닝 포트, DNS, 연결 처리 과정이 기록됩니다. 클라이언트가 mihomo를 사용한다고 해서 모든 오류가 mihomo에서 발생한 것은 아닙니다. 문제를 확인할 때는 클라이언트 버전과 코어 버전을 함께 기록하고, ‘최신 버전’이라고만 적지 마세요.
- 시작하자마자 실패: 설정 파싱, 정책 참조, 포트 충돌, 권한 관련 메시지부터 확인하세요. 대상 웹사이트를 먼저 점검할 필요는 없습니다.
- 정상적으로 시작되지만 웹페이지가 열리지 않음: 해당 도메인의 연결 로그를 찾은 다음 규칙과 아웃바운드 경로를 확인하세요.
- 구독 업데이트만 실패: 설정을 다운로드할 때 사용하는 네트워크, 구독 URL 상태, HTTP 응답을 확인하세요. 프록시 연결 문제와 같은 것으로 단정하지 마세요.
- 브라우저 접속은 실패했지만 관련 로그가 없음: 먼저 트래픽이 클라이언트로 들어오는지 확인한 뒤 노드를 살펴보세요. 시스템 프록시가 모든 앱에 적용되는 것은 아니며, TUN에서도 라우팅 제외가 설정될 수 있습니다.
로그 레벨 조정: 먼저 info를 사용하고 필요할 때만 잠시 debug로
클라이언트의 ‘로그’ 페이지에서 레벨 드롭다운이나 필터 옵션을 찾으세요. 주의할 점은 화면의 필터가 일부 로그를 숨길 뿐, 코어가 생성하는 로그 레벨을 바꾸지는 않을 수 있다는 것입니다. 상세 로그가 필요하다면 실행 설정의 log-level 값이 변경되었는지 확인하세요.
일반적인 Clash 코어와 mihomo는 silent, error, warning, info, debug 등의 레벨을 사용합니다. 평소에는 info부터 시작하고, 문제를 추적할 때 debug로 바꿔 한 번 재현한 뒤 원래대로 되돌리세요. 상세 로그는 출력량을 늘리고 접속한 도메인을 노출할 수도 있습니다.
설정에서 로그 레벨을 바꾸는 방법
- 현재 설정을 백업한 뒤, 클라이언트가 영구 오버라이드, 설정 병합, 로컬 설정 편집 중 어떤 방식을 지원하는지 확인하세요.
- 최상위 항목에
log-level: debug를 설정하세요. 같은 항목이 이미 있으면 기존 값을 수정하고 중복해서 추가하지 마세요. - 클라이언트의 설정 다시 불러오기 기능으로 변경 사항을 적용하세요. 코어를 재시작하라는 안내가 나오면 그대로 진행하세요.
- 로그 패널을 열고 warning이나 error만 표시하도록 설정되어 있지 않은지 확인하세요. 실패하는 동작을 한 번만 실행하고 전후 약 30초의 로그를 보관하세요.
- 수집을 마치면
log-level: info로 되돌려 접속 기록이 장시간 과도하게 출력되지 않도록 하세요.
# 최상위 항목 예시: 기존 설정에 병합하세요
log-level: debug
위 내용은 완전한 설정 파일이 아닙니다. 구독으로 생성된 파일을 직접 편집하면 다음 업데이트 때 덮어써질 수 있습니다. 클라이언트에서 오버라이드 기능을 제공한다면 영구 오버라이드를 우선 사용하세요. 메뉴 위치는 클라이언트 버전에 따라 다르므로 특정 클라이언트의 ‘설정’ 경로를 모든 Clash 클라이언트의 공통 경로로 간주하지 마세요.
연결 로그에서 확인할 항목
먼저 시간을 확인한 다음 대상, 규칙, 오류를 살펴보세요. 연결 로그에는 [TCP] 또는 [UDP] 표시가 자주 나오며, match, using 등의 문구는 적용된 규칙과 사용된 아웃바운드를 설명하는 경우가 많습니다. 출력 내용은 코어에 따라 다르므로 모든 로그에 필드가 빠짐없이 표시되리라고 기대해서는 안 됩니다.
| 필드 또는 내용 | 확인할 사항 |
|---|---|
| 시간 및 프로토콜 | 방금 실패한 동작과 일치하는 로그인가요? TCP와 UDP에서 차이가 있나요? |
| 출발지 주소 | 요청이 현재 기기나 예상한 앱에서 발생했나요? 백그라운드 업데이트나 같은 네트워크의 다른 기기에서 발생한 것은 아닌가요? |
| 대상 도메인 및 포트 | 대상 웹사이트의 443 포트인가요, DNS의 53 포트인가요, 아니면 프록시 서버의 서비스 포트인가요? |
| 규칙 및 정책 | 프록시를 이용해야 하는데 DIRECT가 적용됐나요, 아니면 REJECT로 거부됐나요? 정책 그룹에서 실제로 선택된 항목은 무엇인가요? |
| 오류 메시지 끝부분 | 연결 실패의 직접적인 원인이 DNS 조회, 시간 초과, 연결 거부, 프로토콜 오류, 인증서 오류 중 무엇인가요? |
DIRECT는 직접 연결로 나간다는 뜻이지, 요청이 성공했다는 뜻은 아닙니다. REJECT는 정책에 따라 요청이 거부됐다는 뜻이며 의도된 차단일 수도 있습니다. 로그에 프록시 그룹이 표시되더라도 연결 상세 정보나 정책 화면에서 실제 선택된 노드를 확인하세요. 자동 정책 그룹은 테스트 사이에 구성원이 바뀔 수 있습니다.
dial tcp, timeout, 연결 끊김의 차이
dial tcp: 뒤에 나오는 주소와 원인을 확인하세요
dial tcp 192.0.2.10:443: connect: connection refused
dial tcp 192.0.2.10:443: i/o timeout
dial tcp: lookup proxy.example on 127.0.0.1:53: no such host
dial tcp는 TCP 연결을 시작한다는 뜻일 뿐, 그 자체로 오류 원인을 나타내지는 않습니다. 예시에 나온 192.0.2.10은 문서용 주소입니다. 실제 로그에서는 해당 주소가 프록시 서버인지, 직접 연결하려는 대상인지 확인해야 합니다. 프록시 서버에 연결조차 되지 않았다면 대상 웹사이트의 분류 규칙을 바꿔도 보통 해결되지 않습니다.
- connection refused: 연결이 명시적으로 거부됐습니다. 해당 포트에서 서비스가 실행 중이지 않거나, 포트 번호가 잘못됐거나, 방화벽이 연결을 거부하는 경우가 흔합니다. 계정이나 비밀번호가 틀렸다는 뜻은 아닙니다. 인증은 보통 연결이 설정된 다음에 진행됩니다.
- i/o timeout: 네트워크 읽기 또는 쓰기 작업이 제한 시간 안에 끝나지 않았다는 뜻입니다. 패킷 손실, 대상의 무응답, 아웃바운드 제한, 프로토콜 단계에서의 정체 등이 원인일 수 있습니다. 어느 단계에서 발생했는지 파악하려면 앞뒤 오류 메시지를 함께 확인하세요.
- network is unreachable: 기기 또는 현재 네트워크에서 사용할 수 있는 경로가 없습니다. 인증 정보를 바꾸기보다 네트워크 인터페이스, 기본 경로, IPv6 연결 상태를 먼저 확인하세요.
context deadline exceeded: 작업 전체가 시간 초과됨
제한 시간이 설정된 작업이 제시간에 끝나지 않았다는 뜻입니다. DNS 요청, 상태 확인, 연결 설정 과정에서 발생할 수 있습니다. 이 문구만으로 노드 문제라고 단정할 수는 없습니다. DNS 모듈이나 프록시 연결 모듈 등 오류가 기록된 맥락을 보존하고 같은 시각의 다른 연결 로그와 대조하세요.
EOF, connection reset by peer: 연결 후 끊김
EOF는 데이터를 읽는 중 연결이 종료됐다는 뜻이고, connection reset by peer는 연결 재설정 응답을 받았다는 뜻입니다. 서버의 연결 종료, 프로토콜 불일치, 중간 네트워크 장비의 개입 등이 원인일 수 있습니다. 매번 핸드셰이크 단계에서 발생한다면 노드 유형, 포트, TLS 설정, 전송 매개변수를 확인하세요. 유휴 연결이 종료될 때 가끔 나타나고 실제 접속에는 문제가 없다면 이 로그 하나만으로 장애라고 판단할 필요는 없습니다.
DNS 조회 실패: 노드 도메인, 대상 도메인, DNS 서버를 구분하세요
lookup, no such host, DNS request failed가 보이면 먼저 현재 조회 중인 도메인을 기록하세요. 노드 서버의 도메인을 조회하지 못하면 해당 노드를 사용하는 모든 요청에 영향을 줄 수 있습니다. 특정 대상 도메인만 실패한다면 우선 그 도메인의 DNS 레코드와 조회 경로를 확인하세요.
| 로그 단서 | 의미 및 다음 단계 |
|---|---|
| no such host | 사용할 수 있는 조회 결과를 받지 못했습니다. 도메인이 존재하지 않거나 상위 DNS 서버가 부정 응답을 반환할 때 흔히 발생합니다. 철자, 도메인 상태, 실제로 사용 중인 DNS 서버를 확인하세요. |
| DNS 요청 시간 초과 | 먼저 상위 DNS 서버에 연결할 수 있는지, 프로토콜 설정이 올바른지 확인하세요. DoH를 사용하는 경우 서버 도메인을 처음 조회하는 방식도 살펴봐야 합니다. |
| 127.0.0.1:53 연결 실패 | 기기의 53번 포트에서 DNS 서비스가 실제로 대기 중인지 확인하세요. 루프백 주소는 현재 기기를 가리키며 라우터나 다른 기기를 뜻하지 않습니다. |
| server misbehaving | 대개 DNS 서버가 실패 응답을 반환한 경우입니다. 구체적인 응답 내용과 다른 DNS 서버의 결과를 대조하세요. 도메인이 존재하지 않는다고 바로 단정해서는 안 됩니다. |
시스템 조회 결과가 클라이언트의 DNS 결과와 다를 수 있습니다
예를 들어 nslookup example.com은 보통 시스템에서 선택한 DNS 서버에 질의합니다. 클라이언트가 자체 DNS, fake-ip 또는 별도의 상위 DNS 서버를 사용한다면 이 결과가 앱에서 실제로 사용하는 조회 경로와 다를 수 있습니다. 실행 설정의 리스닝 주소와 포트, 앱 요청이 가로채지고 있는지부터 확인하세요.
fake-ip 모드에서 198.18.0.0/16 대역의 주소가 보이면 설정에서 할당한 매핑 주소일 수 있으므로, 주소만 보고 DNS 오류라고 판단해서는 안 됩니다. 앱이 이전 매핑을 보유한 상태에서 코어를 재시작해 매핑 상태가 바뀌었다면 관련 앱 연결을 닫고 클라이언트가 안내하는 방법으로 캐시를 지운 다음 다시 테스트해야 할 수 있습니다.
mihomo의 proxy-server-nameserver는 프록시 노드 도메인 조회에 사용할 수 있습니다. 이 항목이 필요한지는 코어 버전과 기존 DNS 구성에 따라 판단하세요. mihomo 전용 항목을 지원하지 않는 구형 코어에 추가하거나 DNS 설정 전체를 한꺼번에 바꾸지 마세요. 먼저 어떤 도메인과 상위 DNS 서버에서 문제가 발생하는지 확인하세요.
포트, TLS, 설정 오류를 확인할 위치
address already in use: 로컬 리스닝 포트가 사용 중임
시작 로그에 127.0.0.1:7890에서 대기할 수 없다는 메시지가 나오면 클라이언트 두 개가 동시에 실행 중인지, 이전 코어가 종료되지 않았는지 먼저 확인하세요. 7890은 흔히 쓰이는 예시일 뿐입니다. 실제 설정의 mixed-port, port, socks-port 값을 기준으로 확인하세요.
# Windows PowerShell: 예시 포트를 사용하는 리스닝 프로세스 확인
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
# macOS: 예시 포트의 TCP 리스닝 상태 확인
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux: 예시 포트의 TCP 리스닝 상태 확인
ss -ltnp 'sport = :7890'
프로세스가 무엇인지 확인한 뒤 앱을 정상 종료해 포트를 해제하거나 현재 리스닝 포트를 변경하세요. PID만 보고 정체를 모르는 프로세스를 강제 종료하지 마세요. 포트를 바꿨다면 시스템 프록시나 앱의 프록시 주소도 함께 업데이트해야 합니다. 그렇지 않으면 코어는 정상인데 앱이 이전 포트에 계속 연결하는 문제가 생깁니다.
x509 및 TLS handshake: 시간, 인증서, 서비스 이름 확인
x509: certificate has expired or is not yet valid가 표시되면 먼저 기기의 날짜, 시간대, 자동 시간 설정을 확인한 다음 서버 인증서의 유효 기간을 확인하세요. 인증서 이름이 일치하지 않으면 서버 주소, TLS 서비스 이름, 제공업체가 요구하는 설정을 확인하세요. TLS handshake timeout은 네트워크 차단이나 포트와 프로토콜의 불일치 때문일 수도 있으므로 인증서 만료로만 설명할 수 없습니다.
설정 로드 실패: 우선 정상 실행 상태로 복구하세요
YAML 파싱 오류, 알 수 없는 정책, 프록시 그룹 누락이 나타나면 가장 최근에 변경한 내용을 먼저 되돌리세요. YAML 들여쓰기에는 공백을 사용하고 탭은 섞지 마세요. 규칙이 참조하는 정책 이름은 실제로 정의된 이름과 일치해야 합니다. 코어가 설정을 불러오지 못했다면 이후 웹페이지 접속 실패는 단순한 회선 문제가 아닙니다. 먼저 설정 로드와 포트 리스닝이 정상적으로 완료되도록 한 다음 연결 문제를 확인하세요.
시간순으로 재현하기: 한 번에 변수 하나만 변경하세요
백그라운드 동기화, 자동 상태 확인, 앱의 재시도로 로그가 쉽게 뒤섞일 수 있습니다. 효과적으로 문제를 재현하려면 로그를 많이 모으는 것보다 특정 동작과 짧은 로그 구간을 연결하는 것이 중요합니다. 아래는 반복해서 사용할 수 있는 점검 절차이며 시간은 동작 예시입니다.
- 14:20:00, 기준 정보 기록. 클라이언트 버전, 코어 버전, 운영체제 버전, 네트워크 유형, 현재 모드, TUN 사용 여부, 정책 그룹에서 선택한 노드를 적어 두세요.
- 14:20:10, 짧게 로그 수집 시작. 코어 로그를 debug로 바꾸고 패널의 기존 표시를 지우거나 시작 시간을 기록하세요. 시작과 설정 로드 중 발생한 원본 오류는 그대로 보관하세요.
- 14:20:20, 대상 하나에 접속. 관련 없는 탭을 닫고 이전에 접속에 실패한 URL 하나만 여세요. 브라우저에 표시된 메시지와 로그의 대상 포트, 규칙, 아웃바운드를 기록하세요.
- 14:20:40, 한 번 비교 테스트. 대상, 모드, 네트워크는 그대로 두고 노드 하나만 바꾸세요. 노드 도메인조차 조회할 수 없다면 무작정 바꾸기를 반복하지 말고 먼저 DNS를 확인하세요.
- 14:21:00, 차이 정리. 트래픽이 들어오지 않는 문제인가요, 잘못된 규칙이 적용됐나요, 노드 연결이 실패했나요, 아니면 연결 후 대상의 응답에 문제가 있나요? 실패한 단계를 구체적으로 기록하세요.
로그가 없을 때는 로그 레벨보다 트래픽 가로채기 여부를 확인하세요
로컬 프록시를 통한 요청을 비교 테스트로 사용할 수 있습니다. 아래 명령은 현재 설정에서 실제로 127.0.0.1:7890에 HTTP 또는 mixed 프록시가 제공되는 경우에만 사용할 수 있습니다. Windows PowerShell에서는 다른 명령 별칭과 혼동되지 않도록 curl.exe를 사용하세요.
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/
여기서 10초는 연결 설정 단계의 시간 제한이고, 20초는 요청 전체의 시간 제한이지 속도 지표가 아닙니다. 이 명령은 HEAD 요청을 사용하므로 일부 사이트에서는 일반 웹페이지 요청과 다르게 처리될 수 있습니다. 명시적 프록시 경로를 확인하는 데는 유용하지만 브라우저 접속을 대신하지 않으며, TUN이 모든 트래픽을 가로채는지 확인하는 수단도 아닙니다.
명령 실행 시 연결 로그가 생기지만 브라우저 로그는 없다면 브라우저 프록시 확장 프로그램, 시스템 프록시, 앱 자체 설정을 확인하세요. TUN을 켠 뒤 문제가 생겼다면 먼저 라우팅과 DNS 상태를 기록하고 한 번에 한 설정만 켜고 끄며 비교하세요. TUN, DNS 모드, 노드, 규칙을 동시에 바꾸면 어떤 변경이 영향을 줬는지 알 수 없습니다.
문제 제보 시 주변 맥락은 남기고 민감 정보는 삭제하세요
유지관리자나 서비스 제공업체에 문제를 알릴 때는 마지막 로그 한 줄만 캡처한 이미지보다 실패 전후 약 30초의 필요한 로그를 제공하는 편이 유용합니다. 텍스트 로그는 검색하고 비교하기 쉽지만, 자격 증명이나 개인정보가 포함되어 있지 않은지 먼저 확인해야 합니다.
- 남길 정보: 정확한 시간과 시간대, 클라이언트 및 코어 버전, 오류 전문, 대상 포트, 적용된 규칙, 사용 프로토콜, 이미 수행한 단일 변수 비교 결과.
- 삭제할 정보: 구독 전체 URL, 인증 토큰, 비밀번호, UUID, 컨트롤 인터페이스 키, 공개할 필요가 없는 접속 도메인과 기기 경로.
- 일관되게 비식별 처리: 같은 노드는 로그마다 같은 별칭으로 바꿔 서로 연결할 수 있게 하세요. 모든 도메인과 주소를 같은 단어로 바꾸지는 마세요.
- 원본과 정리본 구분: 실제 로그와 재현 절차를 구분해 표시하세요. 다시 작성한 예시를 클라이언트의 원본 출력인 것처럼 제시하지 마세요.
최종 결론은 ‘프록시 서버와 TCP 연결을 시도하는 단계에서 시간 초과’, ‘규칙에 따라 대상이 DIRECT로 전송됨’, ‘노드 도메인 조회 실패’처럼 구체적으로 작성하세요. ‘Clash가 작동하지 않음’이라고만 적지 마세요. 먼저 실패 단계를 확인한 뒤 네트워크, 규칙, 설정 중 관련 항목을 점검해야 이후 변경의 근거가 분명해집니다.