프록시 그룹 종류와 활용
프록시 그룹은 규칙에 일치한 뒤 어떤 출구를 사용할지 결정합니다. 어떤 요청을 프록시로 보낼지를 정하는 기능은 아닙니다. 규칙이 연결을 그룹에 전달하면 그룹은 수동 선택, 상태 확인 또는 분배 알고리즘에 따라 다음 경로를 정합니다. 문제를 확인할 때는 연결 상세 정보에서 일치한 규칙을 찾고, 그다음 최종 선택된 노드를 살펴보세요. 요청이 대상 그룹에 들어오지 않았다면 테스트 간격을 조정해도 소용이 없습니다. 그룹 이름은 설정에서 참조하는 식별자이므로 이름을 바꾼 뒤에는 규칙, 중첩 그룹, 클라이언트에 저장된 선택 상태도 함께 확인해야 합니다.
용도에 맞는 그룹 유형 선택
select는 출구를 직접 선택해야 할 때 적합하며, 그룹에 노드뿐 아니라 다른 프록시 그룹도 넣을 수 있습니다. url-test는 테스트 결과를 바탕으로 성능이 나은 후보를 선택합니다. 다만 테스트는 지정한 주소에 대한 결과일 뿐, 모든 서비스의 속도가 더 빠르다는 뜻은 아닙니다. fallback은 목록 앞쪽에 있고 검사에 통과한 후보를 우선 사용하므로 출구 우선순위가 고정된 환경에 적합합니다. load-balance는 서로 다른 연결을 여러 후보에 분배합니다. 하나의 다운로드 연결을 나눠 대역폭을 합산하는 방식은 아닙니다.
| 유형 | 선택 기준 | 주요 제약 |
|---|---|---|
| select | 사용자가 직접 선택 | 선택한 출구가 끊기면 보통 직접 조치해야 함 |
| url-test | 후보별 테스트 결과 | 테스트 주소와 실제 서비스 환경이 다를 수 있음 |
| fallback | 목록 순서와 사용 가능 여부 | 최저 테스트 시간보다 우선순위가 중요함 |
| load-balance | 연결 분배 방식 | 서비스에서 여러 출구 IP가 관찰될 수 있음 |
추적하기 쉬운 수동 선택 계층부터 구성
최상위에 수동 선택 그룹을 하나 두고 자동 선택 그룹을 그 안에 넣는 구성을 권장합니다. 각 서비스 규칙이 자동 그룹을 바로 참조하지 않도록 하면, 문제가 생겼을 때 출구를 임시로 고정해 자동 전환 문제와 규칙 오류를 구분할 수 있습니다. 아래 예제는 참조 관계만 보여 줍니다. 두 후보는 내장 정책이며 사용 가능한 프록시 노드를 뜻하지 않습니다. 실제로는 가져온 뒤 연결이 확인된 노드나 그룹으로 바꾸고 이름이 정확히 일치하는지 확인하세요.
mode: rule
proxy-groups:
- name: 출구 선택
type: select
proxies:
- DIRECT
- 고장 차단
- name: 고장 차단
type: select
proxies:
- REJECT
rules:
- DOMAIN-SUFFIX,example.org,출구 선택
- MATCH,DIRECT
자동 그룹의 주요 매개변수에는 테스트 주소 url, 검사 간격 interval, 전환 허용 오차 tolerance가 있습니다. 테스트 주소는 안정적으로 응답하고 현재 네트워크에서 접근할 수 있어야 합니다. 간격이 너무 짧으면 테스트 요청이 늘고, 너무 길면 장애 상태가 오래 유지될 수 있습니다. 허용 오차는 후보 간 성능 차이가 작을 때 잦은 전환을 줄이는 데 쓰입니다. 단위와 세부 의미는 사용 중인 코어의 문서를 확인하세요. 상태 검사 실패만으로 노드가 완전히 오프라인이라고 단정하지 마세요. 테스트 도메인의 DNS, 대상 사이트의 제한, 프록시 경로가 모두 실패 원인일 수 있습니다.
전환이 실제 연결에 영향을 주는지 확인
그룹을 바꾼 뒤에는 새 요청을 만들어 결과를 확인하세요. 브라우저 연결 풀, HTTP/2 장기 연결, 진행 중인 다운로드는 기존 연결을 계속 사용할 수 있습니다. 따라서 출구가 바로 바뀌지 않더라도 전환이 실패했다고 단정할 수는 없습니다. 테스트 페이지를 닫고 새 연결을 만든 다음 연결 상세 정보에서 전체 정책 경로를 확인하세요. 기존 연결을 끊어야 한다면 클라이언트의 연결 관리 기능을 사용하세요. 유용한 로그를 잃지 않도록 상태를 새로 고치려고 시스템 전체를 재시작하는 일은 피하세요.
로그인, 결제, 장시간 유지되는 세션은 출구를 고정하는 편이 나을 수 있습니다. 로드 밸런싱을 사용하면 같은 서비스의 연결마다 다른 주소를 사용해 세션 검증이나 지역 판정에 영향을 줄 수 있습니다. 이런 서비스는 별도의 수동 그룹으로 분리할 수 있습니다. 그룹을 중첩할 때는 A 그룹이 B 그룹을 참조하고 B 그룹이 다시 A 그룹을 참조하는 순환 구조도 피해야 합니다. 설정을 불러올 수 있는지는 첫 단계일 뿐입니다. 최종 출구, 장애 시 대체 동작, 복구 후 우선순위도 확인하세요. 매개변수별 자세한 비교는 자동 프록시 그룹 유형과 설정 방법을 참고하세요.
규칙 세트 구독 관리
규칙 세트를 사용하면 자주 바뀌는 매칭 항목과 비교적 안정적인 출구 정책을 분리해 관리할 수 있습니다. 기본 설정에는 규칙 세트 선언, 참조 순서, 최종 기본 규칙만 두고 도메인이나 IP 대역 목록은 별도 파일로 관리하세요. 그러면 서비스 도메인을 업데이트할 때 전체 정책 구조를 바꾸지 않아도 되고 변경 사항도 쉽게 검토할 수 있습니다. 단, 외부 규칙 세트도 설정에 입력되는 데이터입니다. 출처와 형식, 업데이트 범위를 확인하고 다운로드가 된다는 이유만으로 로컬 규칙 우선순위를 덮어쓰게 두지 마세요.
선언, 내용, 참조를 구분
rule-providers는 출처와 파싱 방식을 선언하고, RULE-SET은 규칙 목록에서 해당 규칙 세트를 호출하며, 실제 파일은 매칭 항목을 제공합니다. behavior는 도메인, IP 대역, 클래식 규칙 문법 중 어떤 방식으로 내용을 해석할지 결정합니다. format은 파일 형식을 지정합니다. 두 항목을 혼동하지 마세요. 예를 들어 YAML 파일에 도메인 목록이나 클래식 규칙을 담을 수 있습니다. 파일 확장자만으로 코어가 내용을 올바르게 판단한다고 볼 수는 없습니다.
네트워크 다운로드 문제를 함께 끌어들이지 않도록, 아래에서는 로컬 파일로 최소 검증 절차를 구성합니다. 규칙 파일을 코어 작업 디렉터리의 해당 경로에 둔 뒤 선언을 기존 설정에 추가하세요. 경로는 보통 코어 작업 디렉터리를 기준으로 하며 편집 중인 파일의 위치를 기준으로 하지 않을 수 있습니다. 그래픽 클라이언트는 별도의 설정 디렉터리를 쓸 수도 있으니 로그나 설정 관리 화면에서 확인하세요. 샌드박스와 서비스 실행 방식에 따라 접근 가능한 경로가 제한될 수도 있습니다.
rule-providers:
로컬 도메인:
type: file
behavior: domain
format: yaml
path: ./rules/local-domains.yaml
rules:
- RULE-SET,로컬 도메인,DIRECT
- MATCH,출구 선택
이에 해당하는 rules/local-domains.yaml의 내용은 다음과 같습니다. 예시용으로 예약된 도메인을 사용하므로 파일이 로드되고 규칙이 일치하는지만 확인할 수 있습니다. 실제 서비스 규칙을 대신하거나 프록시 노드를 추가하지는 않습니다.
payload:
- 'example.org'
- '+.example.net'
규칙 순서에 따라 적용 범위가 달라짐
규칙은 일반적으로 위에서 아래로 평가되며 먼저 일치한 항목이 후속 처리를 결정합니다. 구체적인 예외 규칙을 넓은 범위의 분류 규칙보다 앞에 두고, 기본 규칙인 MATCH는 마지막에 배치하세요. 넓은 범위의 직접 연결 규칙을 서비스 프록시 규칙보다 앞에 두면 뒤의 규칙이 적용되지 않을 수 있습니다. 규칙 세트 간에 겹치는 항목이 있는 것은 흔합니다. 모든 세트를 서로 겹치지 않게 만드는 것보다 특정 대상이 앞선 규칙에 가로막힌 이유를 설명할 수 있도록 관리하는 것이 중요합니다.
도메인 규칙은 연결에서 도메인 정보를 확인할 수 있어야 하고, IP 규칙은 DNS 조회를 유발할 수 있습니다. 이 매개변수를 지원하는 IP 매칭 규칙에서 no-resolve는 해당 규칙에 일치시키려고 도메인을 새로 조회하지 않는다는 뜻입니다. 연결 전체에서 DNS 조회가 사라진다는 의미는 아닙니다. 사용 여부는 규칙의 목적에 따라 결정하세요. 내부 네트워크 대역의 예외 규칙에는 추가 조회가 필요하지 않은 경우가 많지만, 대상 IP의 지리적 속성에 의존하는 정책이라면 조회 결과의 출처를 고려해야 합니다.
type: http로 전환하려면 규칙 세트 URL을 추가하고 업데이트 간격과 캐시 경로를 명시해야 합니다. 먼저 현재 네트워크에서 출처에 접근할 수 있는지 확인한 뒤 업데이트 요청에 사용할 출구를 정하세요. 그렇지 않으면 규칙을 가져와야 규칙 출처에 접속할 수 있는 순환 의존이 생길 수 있습니다. 업데이트가 실패하면 캐시를 계속 사용할 수도 있지만, 첫 실행 시에는 캐시가 없을 수 있습니다. 캐시가 있는 경우와 빈 경우를 각각 테스트하고, 한 번 업데이트에 성공했다는 메시지만으로 판단하지 마세요.
업데이트 실패 원인을 순서대로 확인
먼저 로그에서 다운로드 실패, 파일 읽기 실패, 형식 파싱 실패 중 무엇인지 확인하세요. 다운로드 실패라면 출처 DNS, TLS 연결, 출구를 점검합니다. 읽기 실패라면 디렉터리 권한과 경로를 확인하고, 파싱 실패라면 payload 구조와 들여쓰기, 동작 유형을 살펴보세요. 클래식 규칙 세트의 항목에는 일반적으로 최종 정책이 포함되지 않습니다. 정책은 바깥쪽 RULE-SET에서 지정하기 때문입니다. 기본 규칙 전체를 규칙 세트 안에 옮기면 필드 수가 맞지 않거나 의미가 혼란스러워질 수 있습니다.
업데이트가 끝나면 규칙에 확실히 포함되는 도메인 하나와 포함되지 않는 도메인 하나를 골라 새 연결을 만드세요. 적용된 규칙을 확인하고 앞선 규칙이 먼저 일치하지 않았는지도 살펴봅니다. 클라이언트 연결 화면에 표시된 규칙 이름은 웹페이지가 열린다는 사실보다 유용한 판단 근거입니다. 페이지가 열려도 기본 규칙이 적용됐을 수 있습니다. 이전에 작동한 규칙 파일과 출처 정보를 보관하고, 잘못 분류된 항목이 있으면 먼저 범위를 좁힌 로컬 예외를 추가한 뒤 상위 규칙의 변경을 조사하세요. 곧바로 전체 규칙 시스템을 전역 프록시로 바꾸지 마세요.
DNS 설정 최적화
DNS 문제를 살펴볼 때는 먼저 두 가지를 구분하세요. 앱이 도메인을 누구에게 조회하는지, 그리고 코어가 최종 주소를 누구에게 조회하는지입니다. 앱은 시스템 DNS, 브라우저의 암호화 DNS, 자체 리졸버를 사용할 수 있습니다. 프록시 노드 서버의 도메인도 먼저 조회해야 합니다. nameserver만 바꿔도 모든 앱의 DNS 요청이 코어를 거치는 것은 아닙니다. 먼저 문제가 특정 앱에서만 발생하는지 확인한 뒤 조회 시작 지점, 상위 DNS, 연결 출구를 살펴보세요. DNS 오류가 보인다는 이유만으로 주소를 모두 한꺼번에 바꾸지 마세요.
DNS 조회 경로를 점검 가능한 단계로 나누기
default-nameserver는 DNS 상위 서버 자체의 도메인을 조회하는 부트스트랩 역할을 주로 합니다. nameserver는 일반 조회에 사용하는 상위 DNS이고, nameserver-policy는 특정 도메인의 조회 경로를 지정할 수 있습니다. 노드 서버 도메인을 별도로 처리해야 한다면 사용 중인 코어에서 proxy-server-nameserver를 지원하는지 확인하세요. 아직 구성되지 않은 프록시 출구에 노드 조회를 의존시키지 말고, 암호화 DNS 서버의 도메인을 해당 서버 자체로만 조회하도록 설정하지 마세요.
아래 예제는 체인을 먼저 검증할 수 있도록 실제 IP 주소를 사용하는 상위 DNS를 지정하고, 로컬 루프백 주소에 테스트 포트를 엽니다. 운영체제의 DNS 설정을 자동으로 변경하거나 DNS 하이재킹을 자동으로 활성화하지는 않습니다. 실제 주소를 확인하도록 redir-host를 사용합니다. 기존 클라이언트가 DNS를 관리한다면 최종 설정을 먼저 확인해 포트 중복을 피하세요.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
default-nameserver:
- 223.5.5.5
nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver-policy:
'example.org':
- 223.5.5.5
시스템에 dig가 설치되어 있다면 이 수신 포트를 직접 조회해 시스템 기본 DNS 결과와 비교할 수 있습니다. 이 테스트는 코어의 DNS 서비스에 접속할 수 있는지 확인할 뿐, 브라우저가 해당 서비스를 사용한다는 뜻은 아닙니다. 조회가 시간 초과되면 서비스 수신 상태, 포트 충돌, 상위 DNS 접근성을 확인하세요. 주소가 반환되는데 웹페이지가 열리지 않는다면 연결 규칙, TLS 핸드셰이크, 앱의 프록시 설정을 계속 점검합니다.
dig @127.0.0.1 -p 1053 example.org A
dig @127.0.0.1 -p 1053 example.org AAAA
상위 DNS 선택과 도메인별 정책
여러 상위 DNS의 실행 방식과 결과 처리 방식은 코어 구현과 필드에 따라 다릅니다. 목록을 단순한 주·보조 순서로 해석하지 마세요. 상위 DNS를 고를 때는 현재 네트워크에서 안정적으로 접근 가능한지, 내부 도메인에 적합한지, 반환되는 주소와 실제 출구가 맞는지 확인해야 합니다. 회사 내부 도메인은 보통 사내 DNS에 맡기는 것이 좋습니다. 공용 DNS는 내부 영역을 알지 못합니다. 내부 도메인을 외부로 보내면 조회가 실패하거나 도메인 정보 노출 범위가 커질 수 있습니다.
DoH나 DoT는 DNS 조회 전송을 보호할 수 있지만 잘못된 출구나 라우팅을 자동으로 고치지는 않으며 대상 서비스가 분할 규칙을 우회하도록 만들지도 않습니다. 규칙 기반 DNS 라우팅을 활성화하기 전에 respect-rules와 노드 도메인 조회 사이의 의존 관계를 이해하고 노드 조회 경로를 명확히 설정하세요. 기존 설정에 fallback이나 필터 조건이 있다면 함께 검토해야 합니다. 상위 DNS 목록만 붙여 넣고 조회 대상이 바뀌었다고 가정하지 마세요.
IPv6는 무조건 끄거나 켜는 대신 실제 네트워크의 지원 여부에 따라 설정하세요. 주소를 조회할 수 있고, 시스템에 사용 가능한 경로가 있으며, 클라이언트의 트래픽 처리 방식이 해당 트래픽을 지원해야 IPv6 경로가 완성됩니다. 웹페이지가 간헐적으로 멈춘다면 A와 AAAA 조회, IPv4와 IPv6 연결을 각각 테스트해 특정 주소 유형이 계속 실패하는지 확인하세요. DNS에서 AAAA 응답을 차단하더라도 앱이 캐시나 자체 DNS를 통해 IPv6 주소를 얻지 못한다고 보장할 수는 없습니다.
캐시, 브라우저 DNS, 장애 재현 확인
DNS 정책을 바꾼 뒤에도 코어, 운영체제, 브라우저의 캐시에 이전 결과가 남을 수 있습니다. 먼저 직접 조회해 새 결과를 확인한 다음 클라이언트가 제공하는 방법으로 DNS 캐시를 비우고 테스트 앱을 재시작해 새 연결을 만드세요. 같은 페이지를 반복해서 새로 고치는 것만으로는 부족할 수 있습니다. 연결 풀 때문에 새 DNS 조회가 발생하지 않을 수도 있습니다. 브라우저에서만 문제가 발생한다면 보안 DNS 설정과 확장 프로그램의 영향을 확인하고 관련 기능을 끄기 전후의 차이를 기록하세요.
테스트할 때는 조회 도메인, 레코드 유형, 반환 주소, 소요 시간 또는 시간 초과 여부, 관련 연결 로그를 함께 기록하세요. NXDOMAIN, 빈 결과, 요청 시간 초과는 서로 다른 문제입니다. NXDOMAIN은 도메인이 없다는 응답이고, 빈 결과는 해당 레코드 유형에 데이터가 없다는 뜻일 수 있습니다. 시간 초과는 보통 경로나 상위 DNS 응답에 문제가 있음을 나타냅니다. 앱 측 점검은 자주 묻는 질문을 참고하세요. DNS 단계의 문제를 확인한 뒤에 Fake-IP나 DNS 트래픽 처리 방식을 조정해야 합니다.
TUN과 Fake-IP
TUN은 트래픽이 들어오는 경로를, Fake-IP는 도메인과 IP의 매핑을 처리합니다. 함께 사용하는 경우가 많지만 같은 기능은 아닙니다. TUN은 가상 네트워크 인터페이스로 트래픽을 받아 시스템 프록시를 따르지 않는 앱까지 처리하는 데 적합합니다. Fake-IP는 가상 주소를 먼저 반환한 뒤 코어가 매핑을 통해 도메인을 복원하고 연결을 처리합니다. 시스템 프록시는 앱이 직접 따르는 방식이고, TUN은 시스템 라우팅, 권한, 네트워크 스택에 영향을 줍니다. 활성화 여부는 실제로 처리되지 않는 앱이 있는지 확인한 뒤 결정하세요.
먼저 트래픽을 누가 처리하는지 확인
한 기기에서 VPN, 게임 가속기, 가상 네트워크 카드 도구를 여러 개 실행하면 경로와 DNS 설정이 서로 덮어쓸 수 있습니다. 시스템 프록시 상태, 기존 가상 인터페이스, 기본 경로를 기록한 뒤 트래픽 처리 지점을 하나만 남겨 비교하세요. 데스크톱 클라이언트는 서비스 프로세스로 권한을 얻거나 별도 승인을 요구할 수 있습니다. 모바일 시스템은 보통 운영체제가 제공하는 VPN 통로를 사용합니다. 플랫폼마다 화면 설정이 다르므로 이를 동일한 하위 라우팅 동작으로 간주하지 마세요.
아래 설정은 mihomo에서 TUN, DNS 트래픽 처리, Fake-IP를 함께 사용하는 방법만 보여 주며 프록시 노드는 포함하지 않습니다. 클라이언트가 일부 필드를 자동 생성할 수 있으므로 최종 설정을 기준으로 확인하세요. 활성화하기 전에 로컬 화면에서 TUN을 끌 수 있는지 확인하고 네트워크 연결 없이도 복구할 수 있도록 원본 설정을 별도로 보관하세요.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '*.lan'
- '*.local'
nameserver:
- 223.5.5.5
auto-route는 트래픽 처리 경로를 설정하고, auto-detect-interface는 실제 출구 인터페이스를 선택하는 데 도움을 줍니다. stack은 트래픽 처리 구현 방식에 영향을 줍니다. system, gVisor, 혼합 스택의 지원 여부와 호환성은 플랫폼과 코어 빌드에 따라 다릅니다. 특정 명칭을 사용하려고 무작정 방식을 바꾸지 마세요. 먼저 클라이언트가 권장하는 기본값으로 연결을 확인하고 문제가 있는 프로토콜만 하나씩 비교해 변경 전후 로그를 기록하세요.
가상 주소의 사용 범위 이해
Fake-IP 주소는 대상 서버의 실제 주소가 아니므로 인터넷에서 연결 가능한지 판단하는 데 사용할 수 없습니다. 앱이 가상 주소를 받은 뒤 연결하려면 매핑 정보를 가진 코어를 다시 거쳐야 합니다. 앱이 TUN을 우회해 직접 연결하거나 매핑이 사라지거나 트래픽이 다른 프록시 인스턴스로 들어가면 대상 도메인을 복원하지 못할 수 있습니다. 캐시에 가상 주소가 남아 있다면 트래픽 처리를 끈 뒤에도 잠시 문제가 발생할 수 있으므로 관련 캐시를 지우고 앱에서 다시 조회하세요.
fake-ip-filter에 지정된 도메인은 일반적으로 실제 DNS 응답을 반환합니다. 그렇다고 자동으로 직접 연결되는 것은 아니며 최종 출구는 여전히 규칙에 따라 결정됩니다. 로컬 네트워크 장치 검색, 실제 주소 확인이 필요한 앱, 특정 기기 간 통신에는 범위를 좁혀 제외를 설정한 뒤 문제가 해결되는지 확인할 수 있습니다. 트래픽 처리 이상을 감추기 위해 모든 도메인을 필터 목록에 넣지 마세요. DNS 동작 방식 전체가 바뀌어 문제를 비교하기 어려워집니다.
예제의 DNS 트래픽 처리는 목적지 포트가 53인 일반 DNS 요청을 대상으로 합니다. 앱이 직접 사용하는 DoH나 DoT를 복호화하지는 않습니다. 브라우저 내장 DNS, 기업 VPN의 내부 DNS, 특수 네트워크 인터페이스는 각각 따로 확인해야 합니다. 로컬 네트워크 브로드캐스트, 멀티캐스트, 일부 로컬 서비스는 일반 인터넷 연결과 다르므로 TUN 스위치 하나로 모두 올바르게 전달된다고 가정하지 마세요. 라우터나 프린터에 접속할 수 없다면 프록시 노드부터 바꾸지 말고 내부 경로와 DNS를 먼저 확인하세요.
영향이 적은 순서로 되돌리기
기기 전체에서 인터넷이 끊기면 먼저 TUN을 끄고 기본 경로와 시스템 DNS가 복구되는지 확인한 다음 원래 설정을 되돌리세요. 클라이언트가 비정상 종료된 뒤 경로가 복구되지 않으면 클라이언트의 복구 기능을 사용하거나 네트워크 인터페이스를 껐다 켜세요. 시스템 라우팅 명령에 익숙하지 않다면 경로를 일괄 삭제하는 명령을 그대로 실행하지 마세요. 기본 네트워크를 복구한 뒤 시스템 프록시와 TUN을 각각 확인하고, 네트워크가 불안정한 상태에서 규칙을 계속 추가하지 마세요.
안정화되면 브라우저, 명령줄, 평소 시스템 프록시를 따르지 않는 앱 하나를 각각 테스트하세요. 연결이 코어에 들어오는지, 도메인 정보가 있는지, 규칙이 일치하는지 확인합니다. UDP 서비스는 노드 프로토콜과 서버가 필요한 전송을 지원하는지도 확인해야 합니다. TUN이 트래픽을 받더라도 출구가 해당 전송을 지원한다는 뜻은 아닙니다. 동작 방식 비교는 TUN과 시스템 프록시의 작동 방식을 참고하세요. 입구에서 트래픽을 받는 범위와 출구의 처리 능력을 구분한 뒤 다음 변경을 결정하세요.
도메인 스니핑
도메인 스니핑은 연결에서 도메인 정보를 보완하는 기능이지 웹페이지 내용을 복호화하는 도구가 아닙니다. 앱이 별도 DNS, 캐시된 주소, 직접 IP를 사용해 연결하면 코어에는 대상 주소만 보이고 예상한 도메인 규칙을 적용하지 못할 수 있습니다. 스니핑은 HTTP 요청이나 TLS·QUIC 핸드셰이크에서 확인할 수 있는 호스트 정보를 추출해 이후 판단에 활용합니다. 실제 프로토콜에 노출된 정보만 이용하므로 암호화된 클라이언트 헬로, 비표준 프로토콜, IP만 사용하는 서비스에서는 도메인을 얻지 못할 수 있습니다.
먼저 도메인 정보가 누락됐는지 확인
연결 화면에서 안정적으로 재현할 수 있는 요청을 찾아 대상이 IP로만 표시되고 도메인 규칙이 적용되지 않았는지 확인하세요. 화면에 이미 올바른 도메인이 표시되는데도 잘못된 규칙이 적용된다면 규칙 순서와 정책 참조를 먼저 살펴보세요. 스니핑을 켜도 해결되지 않는 경우가 많습니다. 브라우저가 별도의 암호화 DNS를 사용한다면 그 경로가 의도한 동작인지 먼저 확인한 뒤 브라우저 DNS 방식을 조정할지, 스니핑으로 코어에 정보를 보완할지 결정하세요.
아래 예제는 포트 범위를 보수적으로 설정해 HTTP와 TLS 스니핑만 보여 줍니다. override-destination을 꺼서 스니핑 결과가 연결 대상 변경에 미치는 영향을 줄였습니다. 어떤 정보를 사용할 수 있는지와 구체적인 동작은 사용 중인 코어에 맞춰 확인하세요. 이 설정은 기존 설정에 병합해야 하며 단독으로 연결할 수 있는 완성된 설정이 아닙니다.
sniffer:
enable: true
parse-pure-ip: true
force-dns-mapping: true
override-destination: false
sniff:
HTTP:
ports:
- 80
- 8080
TLS:
ports:
- 443
skip-domain:
- '+.lan'
- '+.local'
parse-pure-ip는 IP만 사용하는 연결도 처리할 수 있게 하고, force-dns-mapping은 특정 DNS 매핑 상황에서 스니핑이 동작하는 방식과 관련됩니다. 어느 쪽도 모든 연결에서 도메인을 얻을 수 있다는 보장은 아닙니다. 포트 범위는 검사할 연결의 범위를 정할 뿐, 해당 포트의 트래픽이 반드시 특정 프로토콜이라는 뜻은 아닙니다. 앱이 일반적이지 않은 포트에서 TLS를 사용한다면 실제 서비스에 따라 범위를 넓힐지 판단하세요. 한 가지 문제를 해결하려고 모든 포트를 검사 대상으로 넣지 마세요.
규칙 정보와 연결 대상 변경을 구분
스니핑으로 도메인을 얻으면 서비스 분류를 복원하는 데 도움이 됩니다. 반면 대상 덮어쓰기는 연결하려던 대상의 의미까지 바꿀 수 있습니다. 고정 IP, 사용자 지정 Host, 특수 리버스 프록시에 의존하는 서비스는 무분별하게 덮어쓰면 정상 요청도 실패할 수 있습니다. 도메인을 스니핑했는지와 대상 덮어쓰기를 허용할지를 별도의 실험으로 나눠 확인하세요. 먼저 로그와 규칙 적용 결과를 살펴보고 서비스 핸드셰이크가 정상인지 테스트합니다.
하나의 IP에 여러 도메인이 연결될 수 있으므로 IP 주소만으로 현재 요청의 호스트를 정확히 추정할 수 없습니다. TLS에서 보이는 서버 이름도 앱이 이후에 불러오는 모든 리소스를 나타내지는 않습니다. 웹페이지는 CDN, 로그인, 이미지, API 도메인에 추가로 연결될 수 있습니다. 따라서 첫 화면의 규칙 적용만 보고 사이트 전체가 같은 정책을 사용한다고 판단하지 마세요. 연결 목록에서 앱이나 시간 범위를 기준으로 관련 요청을 살펴보고, 특히 로그인 리디렉션이나 리소스 로딩에 실패하는 경우를 확인하세요.
QUIC은 일반적으로 UDP를 사용합니다. 관련 스니핑을 활성화하려면 코어 지원 여부, 실제 포트, 출구의 UDP 지원을 확인해야 합니다. 브라우저 QUIC을 끈 뒤 증상이 달라졌다면 프로토콜 경로가 달라졌다는 뜻일 뿐 UDP 노드를 사용할 수 없다는 증거는 아닙니다. TLS 핸드셰이크 정보를 볼 수 없다면 스니핑으로 도메인을 만들어 낼 수도 없습니다. 이럴 때는 앱의 DNS 요청을 코어로 보내거나 이미 파악한 서비스 규칙을 사용하고, 필요하다면 프로세스별 분할을 고려하세요. 스니핑 범위를 끝없이 넓히는 것은 적절한 해결책이 아닙니다.
제외 항목을 설정하고 재검증 기록 보관
내부 서비스, 기기 관리 페이지, 호환성에 민감한 일부 앱에는 명확한 제외 항목을 설정할 수 있습니다. 범위는 최대한 구체적으로 잡고 재현 가능한 도메인이나 대상 하나부터 테스트한 뒤 확대 여부를 판단하세요. 코어마다 지원하는 스니핑 제외 도메인, 출발지 주소, 목적지 주소 필드가 다를 수 있습니다. 설정 검사에서 알 수 없는 필드가 나타나면 매개변수를 계속 추가하지 말고 코어 종류와 지원 범위를 확인한 뒤 필요한 항목만 남기세요.
검증할 때는 먼저 스니핑을 끄고 한 번 접속해 대상 도메인, 적용 규칙, 출구를 기록하세요. 그런 다음 스니핑을 켜고 새 연결을 만들어 세 항목을 비교합니다. 스니핑을 켠 뒤에만 실패한다면 되돌린 다음에도 앱 캐시와 기존 연결이 정리됐는지 확인하세요. 남아 있는 상태를 롤백 실패로 오해하지 않도록 주의해야 합니다. 로그에 내부 호스트 이름, 요청 주소, 앱 정보가 포함되어 있다면 공유 전에 가리세요. 스니핑은 정보를 보완하는 계층으로 활용하고, 장기적으로 안정적인 설정은 명확한 DNS 경로와 설명 가능한 규칙을 우선하세요.
로컬 오버라이드와 여러 구독 병합
장기 설정에서는 원격 입력과 로컬 설정을 분리하세요. 구독은 노드와 업데이트할 콘텐츠를 제공하고, 로컬 오버라이드는 고정 규칙, DNS, 프록시 그룹 구조, 기기별 설정을 관리합니다. 클라이언트가 생성한 임시 설정 파일을 직접 편집하면 구독 업데이트나 설정 전환 시 변경 사항이 사라지는 경우가 많습니다. 먼저 클라이언트에서 영구 오버라이드, 설정 병합, 스크립트 처리 중 어떤 방식을 제공하는지 확인하고 최종 생성 파일을 살펴보세요. 편집기의 원문만으로 실행 중인 코어가 변경 사항을 사용한다고 판단할 수는 없습니다.
병합 순서와 배열 처리 방식 확인
YAML은 데이터 형식일 뿐 파일 간 병합 규칙을 공통으로 정의하지 않습니다. 클라이언트마다 맵을 재귀적으로 병합하거나 배열 전체를 교체할 수 있고, 항목을 앞이나 뒤에 추가하거나 이름으로 갱신하는 기능을 제공할 수도 있습니다. rules를 통째로 교체하는 방식과 뒤에 추가하는 방식은 결과가 크게 다릅니다. 전자는 구독 규칙을 잃게 할 수 있고, 후자는 로컬 예외가 MATCH 뒤에 놓일 수 있습니다. 오버라이드를 적용하기 전에 범위를 좁힌 테스트 규칙 하나로 실제 순서를 확인하세요.
아래는 로컬 설정 의도를 보여 주는 예제입니다. 프록시 그룹에는 직접 연결 후보만 넣어 이름을 안정적으로 유지하고 규칙 위치를 설명합니다. 모든 클라이언트에서 사용할 수 있는 오버라이드 형식은 아닙니다. 클라이언트 설명에 나온 병합 경로에 맞춰 변환하거나 적용하세요. 이 부분만 완성된 프록시 구독처럼 가져오면 안 됩니다.
proxy-groups:
- name: 일상 출구
type: select
proxies:
- DIRECT
rules:
- DOMAIN-SUFFIX,example.org,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,일상 출구
실제 병합 시에는 “일상 출구”가 기존 노드, 노드 제공자 또는 하위 자동 그룹을 참조하도록 설정하세요. 기본 규칙은 이처럼 안정적인 진입점만 참조하면 노드 제공자가 바뀌어도 서비스 규칙을 다시 작성할 필요가 없습니다. 구독 자체에서도 같은 이름의 그룹을 정의한다면 어느 쪽이 우선하는지 명확히 정하세요. 중복된 이름은 신뢰할 수 있는 병합 방법이 아닙니다. 클라이언트에 저장된 이전 선택이 삭제된 노드를 가리킬 수 있으므로 업데이트 후 현재 그룹 선택이 유효한지도 확인하세요.
여러 구독은 출처를 분리한 뒤 병합
여러 구독은 클라이언트의 병합 기능이나 proxy-providers 같은 코어 기능으로 구성할 수 있습니다. 하지만 노드 구독, 완성된 설정 구독, 규칙 세트는 서로 다른 유형의 입력입니다. 노드 제공자는 일반적으로 노드 목록에 맞는 구조여야 합니다. DNS, 규칙, 컨트롤러가 포함된 전체 설정 URL을 그대로 넣고 모든 내용이 자동으로 병합되기를 기대하지 마세요. 구독에서 반환되는 콘텐츠 유형을 먼저 확인하고, 필요하다면 신뢰할 수 있고 검토 가능한 로컬 변환 절차를 사용하세요.
출처마다 이름, 캐시 경로, 노드 이름을 구분하세요. 여러 출처의 노드가 모두 “홍콩”으로 표시되면 로그와 선택 기록에서 구분하기 어렵고 이름 충돌이 발생할 수도 있습니다. 접두어에는 출처나 용도가 드러나도록 하되 구독 인증 정보는 노드 이름에 넣지 마세요. 후보를 필터링할 때는 결과가 비어 있지 않은지 먼저 살펴보세요. 정규식, 이름 변경, 지역 태그 조정으로 정상적인 그룹에 갑자기 구성원이 하나도 남지 않을 수 있습니다.
원격 구독 URL에는 접근 인증 정보가 포함되는 경우가 많으므로 클라이언트의 로컬 설정 관리 기능에 보관하세요. 스크린샷, 문제 보고, 동기화 저장소, 온라인 변환 도구를 사용하면 노출 범위가 커질 수 있습니다. 설정을 공유하기 전에 URL 쿼리 매개변수, 노드 비밀번호, 컨트롤러 키, 로그에 표시된 전체 주소를 함께 확인하세요. 노드 목록만 가려도 구독 주소가 유출될 수 있습니다. 이런 정보가 포함된 백업은 접근을 통제할 수 있는 위치에 두고 열람 가능한 계정을 제한하세요.
생성, 검사, 재시작을 나눠 검증
변경 후 최종 설정 파일을 확인해 규칙 순서, 그룹 구성원, DNS 필드가 올바른지 살펴본 다음 코어 설정 검사를 실행하세요. 명령줄 환경에서는 아래 방법을 사용할 수 있으며 config.yaml은 실제로 실행할 최종 파일이어야 합니다. 그래픽 클라이언트에서는 작업 디렉터리가 달라 파일 경로가 일치하지 않는 문제를 피하도록 내장 검사 기능을 우선 사용하세요. 검사에 통과했다면 구조와 참조가 대체로 유효하다는 뜻일 뿐, 프록시 노드가 대상 서비스에 접속할 수 있다는 의미는 아닙니다.
mihomo -t -f config.yaml
재시작한 뒤 로컬 예외, 일반 프록시 규칙, 최종 기본 규칙을 각각 테스트하고 구독을 다시 업데이트한 뒤에도 설정이 남아 있는지 확인하세요. 업데이트 후 이전 동작으로 돌아갔다면 오버라이드가 영구 설정 생성 과정에 포함되지 않았거나 나중 단계에서 덮어쓴 것입니다. 롤백할 때는 로컬 오버라이드와 해당 구독의 스냅샷을 복원하세요. 임시로 생성된 파일을 복사해 영구적인 해결책으로 삼지 마세요. 병합 문제가 복잡하면 구독 하나와 최상위 그룹 하나만 남긴 뒤 출처를 하나씩 복구해 차이를 만든 단계를 찾으세요.
외부 컨트롤 패널
외부 컨트롤 패널은 코어 제어 API를 통해 상태를 읽고 정책을 전환하며 연결을 관리합니다. 실제 서비스 트래픽을 전달하는 기능은 없습니다. 패널이 열리지 않는 문제와 프록시로 인터넷에 접속하지 못하는 문제는 별개일 수 있습니다. 먼저 코어가 실행 중인지 확인한 다음 제어 API, 인증, 페이지 출처를 점검하세요. 일상적인 작업은 대부분 클라이언트 내장 화면으로 할 수 있습니다. 별도 상태 확인이나 원격 관리가 꼭 필요한 경우에만 제어 기능을 추가로 열어 기기의 관리 진입점이 불필요하게 늘어나지 않도록 하세요.
먼저 로컬 접속만 허용
external-controller는 제어 API의 수신 주소를 지정하고, secret은 API 인증에 사용하며, external-ui는 로컬 정적 패널 디렉터리를 지정합니다. 아래에는 로컬 관리 설정만 나와 있습니다. 예시 키는 설명용 임의 값입니다. 실제로 사용할 때는 기기에서 생성한 충분히 강한 난수로 바꾸고 공개 파일에 기록하지 마세요. 정적 패널 파일은 신뢰할 수 있는 로컬 디렉터리에 미리 준비해야 합니다. 이 필드를 설정해도 페이지 파일이 자동으로 생성되지는 않습니다.
external-controller: 127.0.0.1:9090
secret: "your-controller-secret"
external-ui: ./ui
루프백 주소로 수신하면 해당 기기에서만 사용할 수 있습니다. 다른 기기에서 접속할 수 없다고 모든 인터페이스에 수신하도록 바꾸거나 인증을 끄지 마세요. 기기 간 관리가 꼭 필요하다면 먼저 인증, 접근 제어, 안전한 전송 방식을 설계하고 허용할 출발지만 제한하세요. 시스템 방화벽, 컨테이너 포트 매핑, 클라이언트 설정이 실제 노출 범위에 함께 영향을 줄 수 있습니다. 설정 텍스트만 보지 말고 수신 상태와 실제 접속 결과를 기준으로 확인하세요.
프록시 포트와 관리 포트 구분
mixed-port 같은 프록시 포트는 앱 트래픽을 받는 진입점이고, 제어 API는 코어를 관리하는 인터페이스입니다. 서로 바꿔 쓸 수 없습니다. 브라우저의 프록시 서버를 제어 포트로 설정해도 정상적인 프록시 연결은 되지 않습니다. 패널에 프록시 포트를 API 주소로 입력해도 그룹 정보를 읽을 수 없습니다. 패널의 API 주소에는 올바른 프로토콜, 호스트, 포트가 지정되어야 하며 인증 키는 현재 실행 중인 인스턴스와 일치해야 합니다. 특히 한 기기에서 여러 코어 프로세스가 실행 중인지 주의하세요.
먼저 로컬 API에 요청을 보내 응답 여부를 확인할 수 있습니다. 아래 명령에는 예제와 같은 가짜 키를 사용하며 로컬 테스트 용도입니다. 실제로 실행할 때는 터미널 기록과 화면 공유에 유의하고 인증 헤더를 공개하지 마세요. 인증 실패 응답은 API가 응답했지만 인증 정보가 일치하지 않는다는 뜻입니다. 연결이 거부되면 주소, 포트, 프로세스 상태를 확인하세요. 시간 초과라면 접근 경로와 방화벽도 점검해야 합니다.
curl --fail --silent --show-error \
-H 'Authorization: Bearer your-controller-secret' \
http://127.0.0.1:9090/proxies
API가 정상인데 페이지가 비어 있다면 정적 파일이 모두 있는지, 디렉터리 경로가 올바른지, 브라우저 개발자 도구에 요청 오류가 있는지 확인하세요. 보안 페이지에서 일반 HTTP API에 접속하면 혼합 콘텐츠 제한에 걸릴 수 있습니다. 페이지와 API의 출처가 다르면 교차 출처 정책도 문제가 될 수 있습니다. 브라우저 오류를 없애려고 모든 출처를 허용하거나 인증을 제거하지 마세요. 로컬 패널과 제어 API가 서로 호환되는 접근 방식을 사용하도록 구성하는 것이 우선입니다.
패널을 활용해 문제 해결 기록을 완성
연결 화면에서 대상, 규칙, 정책 경로, 연결 상태를 함께 확인하세요. 최종 노드 이름만으로는 서비스 규칙에 따라 선택된 것인지 우연히 기본 규칙으로 연결된 것인지 알 수 없습니다. 정책을 바꾼 뒤 새 연결을 만드세요. 필요한 경우 영향 범위를 확인한 다음 특정 기존 연결만 종료합니다. 모든 연결을 한꺼번에 지우고 결과를 관찰하지 마세요. 로그인 세션, 다운로드 작업, 원격 터미널이 끊길 수 있고 장애 상황을 보여 주는 정보도 사라질 수 있습니다.
문제를 설명할 수 있는 수준으로 로그를 설정하고, 자세한 로그가 필요했다면 재현 테스트가 끝난 뒤 원래 수준으로 되돌리세요. 상세 로그에는 내부 도메인, 목적지 주소, 프로세스 정보, 요청 경로가 포함될 수 있습니다. 문의를 보내기 전에는 문제와 관련된 시간대만 남기고 민감 정보를 가리세요. 패널에 표시되는 정보는 연결된 인스턴스에서 가져옵니다. 클라이언트는 정상인데 패널의 규칙 목록이 크게 다르다면 구독 업데이트를 의심하기 전에 제어 주소와 프로세스를 확인하세요.
마지막으로 문제 해결 과정을 재현 가능한 한 줄의 흐름으로 정리하세요. 어떤 앱이 요청했는지, 코어에 들어왔는지, 도메인을 어떻게 확인했는지, 어떤 규칙이 일치했는지, 프록시 그룹이 어떤 출구를 골랐는지, DNS 조회·연결·서비스 응답 중 어느 단계에서 실패했는지 기록합니다. 브라우저와 터미널의 결과가 다르면 시스템 프록시와 터미널 문제 해결 체크리스트를 참고하세요. 처음 설정하는 중이라면 고급 옵션을 계속 늘리기보다 입문 가이드로 돌아가 기본 절차를 완료하는 편이 더 확실합니다.