재현 가능한 요청부터 만들기
Clash 연결 실패를 진단할 때는 먼저 문제가 어느 단계에서 발생하는지 확인하세요. 앱이 요청을 클라이언트에 전달했는지, 커널이 규칙을 매칭했는지, 노드 주소를 조회할 수 있는지, 아웃바운드 연결이 수립됐는지를 살펴봅니다. FlClash는 클라이언트이고 mihomo는 FlClash에서 사용하는 프록시 커널입니다. UI 오류, 구독 다운로드 오류, 커널의 트래픽 전달 로그는 서로 다른 위치에 표시될 수 있습니다.
클라이언트의 ‘로그’ 화면에서 현재 시간, 실행 모드, 선택한 정책 그룹, 실패한 대상을 기록하세요. 메뉴 이름은 클라이언트 버전에 따라 다를 수 있으니 ‘커널 로그’ 또는 ‘실행 로그’를 찾고, 업데이트 확인 기록만 보지 않도록 합니다. 이어서 페이지 하나만 새로고침하거나 테스트 요청을 한 번 보내세요. 백그라운드 앱의 연결이 확인하려는 로그를 뒤덮지 않게 하기 위해서입니다.
- 현재 모드가
rule,global,direct중 무엇인지 확인하세요. 사용자 지정 분기 규칙을 점검하려면 규칙 모드를 사용해야 합니다. - 현재 혼합 포트를 기록하세요. 아래 예시에서는
127.0.0.1:7890을 사용하지만, 모든 클라이언트의 기본값이 이 주소인 것은 아닙니다. - 실패가 발생한 시점 전후 약 10초의 로그를 보관하고 브라우저에 표시된 오류도 기록하세요.
- 한 번에 설정 하나만 바꾼 뒤 같은 대상으로 요청을 다시 보내세요. 노드, DNS, TUN을 동시에 전환하지 마세요.
curl -I -v --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 https://example.com/
이 명령은 로컬 HTTP 프록시 주소를 명시적으로 사용하며, 연결 시간 제한은 10초, 전체 실행 시간 제한은 20초입니다. Windows PowerShell에서는 구형 환경의 동명 별칭과 충돌하지 않도록 명령어를 curl.exe로 지정할 수 있습니다. 대상에서 403 또는 405 응답을 받더라도 먼저 ‘HTTP 응답을 받은 경우’와 ‘연결 자체가 성립하지 않은 경우’를 구분하세요. 이 테스트는 프록시 진입점을 확인할 뿐 TUN이 정상적으로 트래픽을 처리하는지는 검증하지 않습니다.
로그 레벨과 각 항목 읽는 법
mihomo의 log-level은 silent, error, warning, info, debug를 지원합니다. 보통은 먼저 info를 사용하고, 파싱 및 연결 정보를 더 자세히 확인해야 할 때만 debug로 잠시 변경하세요. 클라이언트가 구독 설정의 값을 덮어쓸 수 있으므로 다운로드한 YAML만 수정하지 말고 최종 적용된 설정을 확인해야 합니다.
log-level: info
| 레벨 | 주요 용도 | 확인할 내용 |
|---|---|---|
error | 심각한 오류 | 설정 로드나 구성 요소 시작 실패 등. 구체적인 메시지를 보고 영향 범위를 판단합니다. |
warning | 연결 문제 | 연결 시간 초과, 조회 오류 등. 경고가 한 번 발생했다고 커널 전체가 중단된 것은 아닙니다. |
info | 일반적인 문제 진단 | 시작 정보, 연결 규칙 매칭, 아웃바운드 선택. |
debug | 추가 세부 정보 | 조회 및 내부 처리 정보. 출력량이 많으므로 진단이 끝나면 원래 레벨로 되돌립니다. |
silent | 일반 로그 출력 끄기 | 문제 발생 상황을 수집하는 용도로는 적합하지 않습니다. |
아래는 읽기 편하게 구성한 예시이며, 모든 mihomo 버전의 로그 형식과 정확히 일치하지 않을 수 있습니다. GUI 클라이언트는 시간, 레벨, 메시지를 별도 열로 나눠 표시하기도 합니다.
time="2026-09-15T10:24:08+08:00" level=info msg="[TCP] 127.0.0.1:53124 --> example.com:443 match DomainSuffix(example.com) using 수동 선택[노드 A]"
time: 같은 작업의 로그를 연결해 확인하는 데 사용합니다. 먼저 시스템 시간대를 확인하고 서로 다른 기기의 시간을 그대로 비교하지 마세요.[TCP]또는[UDP]: 전송 프로토콜을 나타냅니다. 웹사이트 접속이 성공해도 UDP 게임이나 QUIC이 정상 작동한다고 볼 수는 없습니다.127.0.0.1:53124: 연결 출발지와 임시 소스 포트입니다. 여기서53124는 프록시가 수신 대기하는 포트가 아닙니다.example.com:443: 대상 도메인과 포트입니다. TUN에서는 대상 IP가 먼저 표시될 수도 있습니다.match: 매칭된 규칙 유형과 내용,using: 사용된 정책과 노드입니다.
‘규칙이 매칭되어 특정 노드를 사용했다’는 로그는 라우팅이 선택됐다는 뜻이지, 대상 사이트가 정상 응답했다는 뜻은 아닙니다. 주변 연결 오류와 실제 요청 결과도 확인하세요.
dial 시간 초과: 어디에 연결 중이었는지 먼저 확인
i/o timeout 및 context deadline exceeded
두 오류는 제한 시간 안에 작업이 완료되지 않았다는 뜻입니다. 이 문구만으로 ‘노드가 작동하지 않는다’고 단정할 수는 없습니다. 앞선 작업의 대상을 먼저 확인하세요. DNS 조회인지, 프록시 서버와의 TCP 연결인지, 프록시를 통한 대상 접속인지 살펴봐야 합니다. 오류 기록에 나타난 IP는 프록시 서버, DNS 서버, 대상 사이트 중 하나일 수 있으며, 각각 점검 방향이 다릅니다.
dial tcp 203.0.113.10:443: i/o timeout
위 주소는 문서 예시용으로 예약된 대역이며 형식 설명에만 사용됩니다. 실제로 진단할 때는 로그의 주소를 현재 노드의 server 및 port와 비교하세요. 프록시 서버 주소라면 먼저 로컬 네트워크에서 해당 서버까지 연결되는지 확인합니다. 직접 접속할 대상이라면 규칙이 왜 DIRECT를 선택했는지, 로컬 네트워크에서 해당 대상에 접속할 수 있는지 살펴보세요.
- 같은 노드로 서로 다른 대상 두 곳을 테스트하세요. 모두 실패하는 경우와 특정 사이트만 실패하는 경우는 따로 진단해야 합니다.
- 규칙과 DNS는 그대로 두고 노드만 바꿔 보세요. 변경 후 정상화된다면 원래 노드 또는 노드까지의 경로에 문제가 있을 가능성이 큽니다.
- 노드를 유지한 채 Wi-Fi와 모바일 네트워크를 전환해 보세요. 특정 네트워크에서만 실패한다면 네트워크 제한, 라우팅, IPv6 연결 가능성을 확인하세요.
- UDP 요청만 실패한다면 노드 프로토콜과 서버의 UDP 전달 지원 여부를 확인하세요. TCP 지연 결과로 UDP가 정상이라고 판단하지 마세요.
connection refused 및 network is unreachable
connection refused는 일반적으로 연결이 명시적으로 거부됐다는 뜻입니다. 해당 포트에서 서비스가 대기 중이지 않거나 방화벽이 연결을 거부했을 수 있습니다. 대상이 127.0.0.1:7890이라면 커널이 실행 중인지, 실제 포트가 바뀌었는지 확인하세요. 원격 노드가 대상이라면 주소와 포트를 다시 확인합니다. 이는 연결을 기다리다 시간 초과되는 현상과는 다릅니다.
network is unreachable은 로컬 라우팅이나 주소 체계 문제일 가능성이 높습니다. 예를 들어 로그에서 IPv6 주소로 연결을 시도했지만 현재 네트워크에 사용할 수 있는 IPv6 경로가 없을 수 있습니다. 먼저 라우팅과 네트워크 환경을 확인한 뒤 IPv6 관련 설정을 조정하세요. 오류가 한 번 발생했다는 이유만으로 IPv6를 전체적으로 끄지 마세요.
DNS 조회 실패: 노드 도메인과 접속 도메인 구분하기
no such host, DNS resolve failed 또는 DNS 조회 중 시간 초과가 나타나면 먼저 어떤 도메인을 조회했는지 확인하세요. 프록시 서버 주소가 도메인인 경우 프록시 연결을 수립하기 전에 해당 도메인을 조회해야 합니다. 접속하려는 사이트의 도메인은 진입점과 설정에 따라 로컬 DNS, mihomo DNS 또는 프록시 경로에서 조회될 수 있습니다.
| 문제가 발생한 대상 | 주요 항목 | 확인할 사항 |
|---|---|---|
| 노드 서버 도메인 | proxy-server-nameserver | 노드 도메인 조회에 사용하는 DNS 서버에 연결할 수 있는지, 프록시가 DNS 조회에 의존하고 DNS 조회가 다시 프록시에 의존하는 순환 구조가 있는지 확인합니다. |
| DoH 서버 도메인 | default-nameserver | DNS 서버 도메인을 조회하는 부트스트랩 DNS가 정상 작동하는지 확인합니다. |
| 일반 접속 도메인 | nameserver、nameserver-policy | 실제로 사용된 DNS 서버, 도메인별 조회 정책, 조회 결과가 예상과 일치하는지 확인합니다. |
| 시스템 DNS와 커널 DNS가 다름 | dns.enable, TUN의 DNS 가로채기 설정 | 시스템 DNS 요청이 실제로 커널에 전달되는지, 앱이 자체 DoH를 사용하는지 확인합니다. |
no such host는 도메인이 존재하지 않는 경우 등에 발생하는 조회 실패 메시지지만, 상위 DNS의 응답까지 확인해야 합니다. 시간 초과는 제때 응답을 받지 못했다는 뜻이지 도메인이 없다는 의미가 아닙니다. nslookup example.com 명령은 보통 시스템에 설정된 DNS를 테스트하며 mihomo의 DNS를 자동으로 테스트하지 않습니다. 실제 DNS 수신 주소와 포트를 지정할 수 있는 도구나 커널 자체 로그를 사용해야 커널의 DNS 조회 경로를 확인할 수 있습니다.
Fake-IP 모드에서는 앱이 198.18.0.0/16 범위의 합성 주소를 받을 수 있습니다. 이 범위는 관련 설정에서 자주 사용되지만 실제 값은 fake-ip-range 설정을 기준으로 확인하세요. 해당 주소가 표시돼도 DNS 변조라고 단정해서는 안 됩니다. 도메인 매핑, 연결 가로채기, fake-ip-filter 설정이 현재 앱의 요구 사항에 맞는지 확인하세요.
로그에 표시되는 합성 주소를 없애려고 모든 도메인을
fake-ip-filter에 추가하지 마세요. 이렇게 하면 DNS 조회 경로만 달라질 뿐, 노드 연결 불가, 상위 DNS 시간 초과, TUN 가로채기 문제를 직접 해결하지는 못합니다.
규칙 미일치: 반드시 오류 로그가 있는 것은 아닙니다
‘규칙 미일치’는 보통 사용자가 트래픽 분기 결과를 설명하는 표현이며, 이에 해당하는 오류 로그가 반드시 있는 것은 아닙니다. mihomo는 규칙을 순서대로 확인하며 앞선 규칙이 먼저 매칭되면 이후 규칙은 실행하지 않습니다. 마지막의 MATCH는 기본 규칙이므로 이 규칙에 매칭되는 것은 정상적인 라우팅 동작이며, 커널의 규칙 파싱 실패를 의미하지 않습니다.
mode: rule
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,PROXY
아래는 규칙 순서의 일부일 뿐, 실행 가능한 전체 설정이 아닙니다. PROXY는 실제로 존재하는 정책 그룹 또는 아웃바운드 이름이어야 합니다. 이 예시에서는 example.com과 모든 하위 도메인을 직접 연결하고 나머지 요청은 PROXY로 전달합니다. 로그에서 요청이 더 앞쪽의 다른 규칙에 매칭됐다면 DNS를 계속 바꾸기보다 규칙 순서를 조정하세요.
- 먼저 모드를 확인하세요:
global및direct모드에서는 일반 규칙 목록에 따른 분기를 기대할 수 없습니다. - 다음으로 메타데이터를 확인하세요: 대상 IP만 있고 도메인이 없으면 도메인 규칙이 예상대로 매칭되지 않을 수 있습니다. 앱이 미리 DNS를 조회했는지, Fake-IP 매핑이 있는지, 적절한 스니핑 설정이 필요한지 확인하세요.
- 규칙 출처를 확인하세요:
RULE-SET을 사용한다면 해당rule-providers가 정상적으로 로드됐는지 확인하고 형식, 경로, 업데이트 오류를 살펴보세요. - 실제 적용된 설정을 확인하세요: 구독 업데이트, 오버라이드, 클라이언트 설정 병합으로 규칙 순서가 달라질 수 있습니다. 실행 중인 설정을 기준으로 판단하세요.
- 마지막으로 정책 그룹을 확인하세요: 프록시 정책 그룹에 매칭돼도 그룹 안에서
DIRECT가 선택될 수 있습니다. 그룹 이름에 ‘프록시’가 들어 있어도 최종적으로 원격 노드를 거친다는 보장은 없습니다.
연결 기록에 요청이 전혀 나타나지 않으면 먼저 트래픽이 진입하는 경로를 확인하세요. 일부 앱은 시스템 프록시를 따르지 않으므로 앱에서 프록시를 별도로 설정하거나 TUN을 사용해야 합니다. 요청이 기존 연결을 재사용했을 수도 있습니다. 페이지를 계속 새로고침하는 대신 해당 앱을 종료한 뒤 요청을 다시 보내면 원인을 구분하기 쉽습니다.
포트 충돌 및 TUN 시작 실패
address already in use: 포트 사용 프로세스 확인
대표적인 메시지는 listen tcp 127.0.0.1:7890: bind: address already in use입니다. 수신 주소와 포트가 충돌했다는 뜻이며 원격 노드 오류가 아닙니다. 다른 프록시 클라이언트가 백그라운드에서 실행 중이거나 같은 커널이 두 번 시작된 경우가 흔합니다. 충돌한 포트가 혼합 포트인지, DNS 수신 포트인지, 컨트롤 인터페이스 포트인지도 확인하세요.
# Windows: 7890 포트 조회. LISTENING 행과 해당 PID를 중점적으로 확인
netstat -ano | findstr :7890
# macOS: TCP 7890에서 대기 중인 프로세스 확인
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux: TCP 7890에서 대기 중인 프로세스 확인
ss -ltnp 'sport = :7890'
프로세스의 정체를 확인한 다음 해당 앱을 정상 종료하거나 수신 포트를 변경하세요. 정체를 알 수 없는 시스템 프로세스를 바로 종료하지 마세요. mixed-port를 7890에서 7891로 변경했다면 브라우저 확장 프로그램, 명령줄 환경 변수, 프록시 주소를 직접 설정한 앱도 함께 업데이트해야 합니다. Linux에서 다른 사용자의 프로세스 정보를 보려면 추가 권한이 필요할 수 있습니다.
TUN 권한 및 라우팅 문제: 시작 단계부터 확인
TUN은 가상 네트워크 장치와 시스템 권한이 필요합니다. operation not permitted, 장치 생성 실패, 경로 추가 실패가 발생하면 구독 노드를 조정하기 전에 클라이언트의 서비스 모드, 시스템 권한, 가상 네트워크 어댑터 상태를 확인하세요. Windows에서는 관리자 권한이나 설치된 서비스가 필요한 경우가 많습니다. macOS와 Linux의 권한 방식은 클라이언트 구현에 따라 다릅니다.
TUN이 정상적으로 시작됐는데도 대상 요청이 커널에 전달되지 않으면 tun.auto-route, 경로 제외 설정, 다른 VPN 및 보안 소프트웨어의 영향을 확인하세요. 라우팅을 변경하는 다른 클라이언트를 먼저 종료한 뒤 다시 테스트합니다. 진단을 위해 시스템 방화벽을 장시간 끄지 마세요. 차단 여부를 확인해야 한다면 해당 프로그램, 인터페이스, 포트에 적용된 규칙을 살펴보세요.
TLS 및 인증 오류: 연결 후 설정도 확인하세요
로그가 TLS 핸드셰이크 단계까지 진행된 뒤 x509: certificate has expired or is not yet valid가 나타난다면 먼저 시스템 날짜, 시간, 시간대를 확인하고 인증서 유효 기간을 살펴보세요. 인증서 이름이 일치하지 않는다면 노드의 servername 또는 프로토콜에 맞는 SNI 설정, 서버 도메인, 서버 인증서를 확인하세요.
EOF, connection reset by peer, TLS handshake timeout은 원인이 하나로 정해져 있지 않습니다. 원격 서버의 연결 종료, 전송 설정 불일치, 중간 네트워크 간섭, 핸드셰이크 미완료 등이 원인일 수 있습니다. 프로토콜, 노드 포트, 오류 발생 단계를 함께 확인해야 하며 모든 EOF를 비밀번호 오류로 간주해서는 안 됩니다.
- 프로토콜 유형, 포트, 비밀번호 또는 UUID, 전송 계층 설정이 서버와 일치하는지 확인하세요.
- WebSocket 등 전송 방식을 사용한다면 경로와 Host 설정을 확인하세요. 설정 키 이름은 현재 프로토콜 설정을 기준으로 합니다.
- 인증 실패 메시지가 명확히 표시되면 인증 정보와 구독 상태부터 다시 확인하세요.
skip-cert-verify: true를 범용 해결책으로 사용하지 마세요. 인증서 검증을 건너뛰면 연결 상대의 신원을 확인하는 기능이 약화되며, 포트나 프로토콜 오류도 해결되지 않습니다.
일정한 순서로 원인을 좁히고 재검증 결과를 기록하세요
하나의 로그에는 여러 앱, 여러 노드, 여러 번의 재시도가 함께 기록될 수 있습니다. 최종 판단은 화면에서 가장 눈에 띄는 빨간 문구가 아니라 재현 가능한 단일 요청을 기준으로 내려야 합니다. 아래 순서대로 확인하면 관련 없는 설정을 번갈아 바꾸는 일을 줄일 수 있습니다.
- 시작 단계: 설정이 정상적으로 로드됐는지, 수신 포트와 TUN이 시작됐는지 확인하세요. 시작에 실패했다면 먼저 문법, 포트, 권한 문제를 해결합니다.
- 진입 단계: 프록시 주소를 명시한 요청이 커널에 전달되는지 확인하세요. 명시적 프록시는 성공하지만 원래 앱에서 실패한다면 시스템 프록시, 앱 프록시 또는 TUN을 점검합니다.
- 라우팅 단계: 대상, 매칭된 규칙, 정책 그룹, 최종 노드를 확인해 요청 경로가 예상과 일치하는지 살펴보세요.
- DNS 조회 단계: 조회에 실패한 대상이 노드 도메인, DNS 서비스 도메인, 접속 도메인 중 무엇인지 확인한 뒤 해당 조회 경로를 점검하세요.
- 연결 단계: 시간 초과, 거부, 경로 없음, TLS 오류, 인증 실패를 구분하고 관련 설정은 한 번에 하나씩만 변경하세요.
- 앱 단계: HTTP 응답을 받았다면 그다음에는 웹사이트 상태, 로그인 상태, 앱 프로토콜을 확인하세요. 모든 실패를 프록시 연결 문제로 돌리지 마세요.
유지관리자에게 문의할 때는 클라이언트 및 커널 버전, 운영체제, 재현 단계, 실행 모드, 관련 설정 부분, 같은 요청에서 나온 로그를 첨부하세요. 공유 전에 구독 링크, 액세스 토큰, 비밀번호, UUID, 개인 도메인을 삭제하세요. 오류 키워드, 항목 이름, 포트 관계, 시간 순서는 유지합니다. 주소를 바꾸는 경우 여러 로그 행에서 같은 대상을 동일한 이름으로 표시하세요.
문제가 해결되면 같은 진입 경로와 같은 대상으로 다시 테스트하고 어떤 변경으로 해결됐는지 기록하세요. 마지막으로 임시로 켠 debug를 평소 레벨로 되돌립니다. 설정 의미를 확인하려면 설정 필드 참고를 살펴보고, 프록시 진입점과 TUN을 처음 설정한다면 입문 가이드에 따라 하나씩 확인하세요.