노드를 가져올 수 있고 직결·프록시·차단 범위를 더 세밀하게 제어하려는 사용자에게 적합한 글입니다. 도메인과 IP 조건의 실제 매칭 방식, geosite와 geoip 데이터셋의 역할, 규칙 충돌 시 적용 순서, 기존 아웃바운드 태그에 맞춰 조정할 수 있는 routing 설정을 다룹니다.
먼저 routing의 매칭 과정 이해하기
V2Ray 라우팅은 VMess, VLESS 같은 노드 프로토콜 자체를 변경하지 않습니다. 핵심에 요청이 들어온 뒤 어떤 outbound로 보낼지를 처리하며, 각 연결을 프록시·직결·차단 아웃바운드 또는 이미 정의된 다른 출구로 보낼지 결정합니다. 라우팅 결과는 요청 대상, 규칙 순서, 아웃바운드 태그에 따라 달라지므로 노드에 연결된다고 해서 트래픽 분기 규칙이 반드시 올바른 것은 아닙니다.
요청은 보통 로컬 SOCKS, HTTP 또는 투명 프록시 입구가 먼저 받은 뒤 routing.rules로 전달됩니다. 핵심은 배열의 첫 번째 규칙부터 확인하며, 조건을 만족하는 첫 규칙을 찾으면 더 이상 매칭하지 않고 해당 규칙의 outboundTag 또는 balancerTag를 사용합니다. 뒤에 있는 규칙이 더 구체적으로 작성되어 있어도 이미 매칭된 앞선 규칙을 덮어쓸 수 없습니다.
한 규칙 안의 여러 필드는 일반적으로 ‘모두 만족’해야 합니다. 예를 들어 network: "tcp"와 port: "443"를 함께 지정하면 TCP 443 연결만 매칭됩니다. 반면 필드 내부의 배열은 ‘하나라도 일치하면 충족’하는 방식입니다. domain 배열에 세 가지 도메인 조건이 있으면 그중 하나만 매칭되어도 해당 필드가 충족됩니다.
- 규칙 간: 배열 순서에 따라 위에서 아래로 확인하며, 먼저 매칭된 규칙이 적용됩니다.
- 서로 다른 필드: domain, network, port 등의 조건을 모두 충족해야 합니다.
- 같은 필드의 배열: 배열의 여러 값은 일반적으로 하나라도 일치하면 매칭된 것으로 처리됩니다.
- 최종 아웃바운드: outboundTag는 outbounds에 이미 존재하는 tag와 완전히 일치해야 합니다.
domain·full·regexp·geosite 작성법
domain 필드는 문자열 배열을 받지만 배열 안의 문자열에는 여러 매칭 문법을 사용할 수 있습니다. 일반 문자열은 도메인 부분 문자열 매칭에 사용되고, domain:은 지정한 도메인과 하위 도메인을 매칭합니다. full:은 완전한 도메인만 매칭하며, regexp:은 정규 표현식을 사용합니다. geosite:은 외부 도메인 분류 데이터를 참조합니다. 일반적인 트래픽 분기에서는 domain, full, geosite를 우선 사용하고, 기존 문법으로 범위를 표현하기 어려울 때만 regexp를 고려하세요.
정확한 매칭과 접미사 매칭
- 완전한 도메인
- full:api.example.com
- 도메인 및 하위 도메인
- domain:example.com
- 일반 문자열
- example
- 정규 표현식
- regexp:^.+\.example\.com$
고정된 호스트 이름을 알고 있다면 full을 우선 사용하고, 사이트 전체와 하위 도메인까지 적용하려면 domain을 사용하세요.
분류 데이터 매칭
- 중국 본토에서 자주 쓰이는 도메인
- geosite:cn
- 광고 분류
- geosite:category-ads-all
- 중국 본토 외 분류
- geosite:geolocation-!cn
- 데이터 출처
- 핵심이 불러오는 데이터 파일
사용할 수 있는 분류 이름은 현재 핵심이 실제로 불러온 데이터 파일과 그 버전에 따라 달라집니다.
domain:example.com은 example.com과 www.example.com을 모두 포함하므로 사이트 전체에 정책을 적용할 때 적합합니다. full:example.com은 하위 도메인을 자동으로 포함하지 않아 특정 호스트 이름 하나만 처리할 때 알맞습니다. 일반 문자열은 범위가 더 넓어 같은 문자가 포함된 다른 사이트까지 의도치 않게 매칭될 수 있으므로, 너무 짧은 단어를 규칙으로 사용하는 것은 권장하지 않습니다.
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:static.example.com",
"geosite:cn"
],
"outboundTag": "direct"
}
geosite는 실시간 인터넷 조회 서비스가 아니라 핵심이 읽는 로컬 도메인 분류 데이터입니다. 클라이언트나 핵심을 업데이트하면 데이터 파일에 따라 분류 내용이 달라질 수 있습니다. 로그에 특정 geosite 분류를 찾을 수 없다고 표시되면 먼저 분류 이름이 실제로 존재하는지 확인한 뒤, 클라이언트가 V2Ray 핵심을 사용하는지 Xray 핵심을 사용하는지 점검하세요. 데이터 누락 문제를 규칙 순서만 반복해서 바꾸며 가리지 않도록 주의해야 합니다.
ip·CIDR·geoip 매칭 조건
ip 필드는 연결 대상의 IP 주소를 기준으로 판단하며, 단일 주소·CIDR 네트워크·geoip: 분류를 입력할 수 있습니다. 일반적인 작성 예로는 127.0.0.0/8, 192.168.0.0/16, geoip:private, geoip:cn이 있습니다. CIDR 접미사는 네트워크 프리픽스 길이를 의미하므로 한 자리만 잘못 입력해도 매칭 범위가 크게 또는 작게 달라질 수 있습니다.
애플리케이션이 IP로 직접 요청하면 핵심은 즉시 ip 규칙으로 판단할 수 있습니다. 애플리케이션이 도메인으로 요청할 때 라우팅 매칭을 위해 해석할지는 routing.domainStrategy에 따라 달라집니다. AsIs는 주로 원래 도메인을 유지해 판단하고, IPIfNonMatch는 도메인 규칙에서 결과가 나오지 않을 때 해석을 시도한 뒤 IP 매칭을 계속합니다. IPOnDemand는 매칭 과정에서 IP 조건이 필요할 때 해석을 실행할 수 있습니다.
| 작성 예 | 매칭 범위 | 대표적인 용도 |
|---|---|---|
127.0.0.0/8 |
로컬 루프백 주소 대역 | 로컬 서비스가 원격 프록시로 전달되지 않도록 방지 |
192.168.0.0/16 |
일반적인 로컬 네트워크 주소 대역 | 라우터·스토리지 장치·내부 네트워크 서비스에 접근 |
geoip:private |
데이터 파일이 정의한 사설 주소 | 여러 사설 네트워크 대역을 한 번에 처리 |
geoip:cn |
데이터 파일이 중국 본토 주소로 분류한 대역 | 도메인 기반 트래픽 분기를 보완하는 조건 |
결론: 도메인 규칙으로 주로 분기하고 IP 규칙으로 보완
먼저 full, domain, geosite로 명확한 서비스 범위를 표현한 다음 geoip:private, geoip:cn 또는 명시적인 CIDR로 IP에 직접 접속하는 연결을 처리하세요. 불필요한 DNS 해석을 줄일 수 있고, 로그를 통해 요청이 특정 아웃바운드에 매칭된 이유도 더 쉽게 확인할 수 있습니다.
IPIfNonMatch를 사용할 때는 해석 경로에도 주의해야 합니다. 라우팅 판단에 사용된 IP와 실제 원격 연결에 사용된 해석 결과가 가능한 한 일치해야 합니다. 내장 DNS, 시스템 DNS, 원격 해석이 서로 다른 결과를 사용하면 같은 도메인이 시간에 따라 서로 다른 주소 분류에 들어갈 수 있습니다. 트래픽 분기가 간헐적으로 바뀐다면 dns 설정, domainStrategy, 핵심 로그에 표시된 대상 주소를 함께 확인하세요.
규칙 우선순위와 일반적인 충돌
V2Ray은 어떤 규칙이 ‘더 구체적인지’를 자동으로 판단하지 않습니다. 배열에서 앞에 있는 규칙일수록 우선순위가 높으므로, 규칙은 ‘예외를 앞에, 넓은 범위를 뒤에, 최종 대체 규칙은 마지막에’ 두는 방식으로 구성해야 합니다. 예를 들어 특정 도메인은 프록시로 보내야 하지만 동시에 geosite:cn에 속한다면, 해당 도메인의 프록시 규칙을 먼저 작성한 뒤 geosite 직결 규칙을 배치해야 합니다.
- 먼저 차단하거나 별도로 처리해야 하는 정확한 규칙을 배치하세요. 예를 들면
full:도메인 규칙입니다. - 그다음 로컬 장치 요청이 프록시로 들어가지 않도록 로컬 네트워크와 사설 주소의 직결 규칙을 배치하세요.
- 이후 서비스 도메인 그룹, geosite 분류, 지정 네트워크 대역 규칙을 배치합니다.
- 마지막에는 적용 범위가 넓은 프록시 또는 직결 대체 규칙을 둡니다.
- 수정 후에는 핵심 로그로 도메인·IP·TCP·UDP 요청을 하나씩 검증하세요.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"full:service.example.com"
],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
위 예시의 첫 번째 규칙은 geosite 직결 범위의 예외이므로 가장 앞에 둡니다. 두 번째 규칙은 로컬 네트워크 접근을 먼저 보호하고, 세 번째와 네 번째 규칙은 각각 중국 본토 도메인과 주소를 처리합니다. 마지막 규칙은 나머지 TCP·UDP 요청을 proxy로 보냅니다. 실제로 사용하기 전에 outbounds에 proxy와 direct 두 태그가 모두 존재하는지 반드시 확인하세요. 존재하지 않는 아웃바운드를 참조하면 핵심이 시작되지 않습니다.
v2rayN에서 라우팅 설정 및 검증하기
v2rayN의 메뉴 이름은 버전에 따라 달라질 수 있지만, 일반적인 경로는 「설정」→「라우팅 설정」입니다. 사용자 지정 규칙 세트를 만든 뒤에는 현재 규칙 세트가 선택되어 있는지 먼저 확인하고, 설정을 저장한 다음 현재 핵심을 재시작하세요. 전체 사용자 지정 설정 파일을 사용하는 경우 노드를 전환하거나 구독을 업데이트할 때 클라이언트가 설정을 다시 생성하는지도 확인해야 합니다. 수동으로 수정한 내용이 덮어써질 수 있기 때문입니다.
| 점검 항목 | 구체적인 작업 | 예상 결과 |
|---|---|---|
| 로컬 입구 | 「설정」→「매개변수 설정」에서 SOCKS 10808, HTTP 10809 확인 | 브라우저 또는 테스트 프로그램이 실제로 활성화된 포트에 연결 |
| 아웃바운드 태그 | 규칙의 proxy·direct가 기존 outbound tag와 일치하는지 확인 | 핵심 시작 로그에 알 수 없는 아웃바운드 태그가 표시되지 않음 |
| 규칙 순서 | 정확한 도메인·geosite 도메인·직접 IP·로컬 네트워크 주소를 각각 테스트 | 네 종류의 요청이 예상한 아웃바운드에 매칭됨 |
| UDP 요청 | 대체 규칙에 udp가 포함되어 있는지 확인하고 노드 및 입구 관련 설정을 점검 | DNS 또는 기타 UDP 트래픽이 누락되지 않음 |
검증할 때 웹페이지가 열리는지만 확인하지 마세요. 핵심 로그를 켜고 최소한 다음 여섯 가지 대상을 준비해야 합니다. 정확한 프록시 도메인 하나, geosite 직결 도메인 하나, 중국 본토 IP 하나, 로컬 네트워크 IP 하나, 차단 대상 도메인 하나, 앞선 규칙에 포함되지 않는 도메인 하나입니다. 하나씩 요청한 뒤 매칭된 outboundTag를 기록하고, 규칙 번호까지 확인할 수 있다면 함께 기록하세요.
결론: 한 번에 한 그룹의 조건만 조정
먼저 domainStrategy와 아웃바운드 태그를 고정한 다음 규칙 하나를 이동하거나 매칭 항목 하나만 수정하세요. DNS, geosite 분류, 규칙 순서를 한 번에 바꾸면 로그 결과를 단일 원인과 연결할 수 없어 오히려 문제 해결에 시간이 더 걸립니다.
- 규칙을 수정한 뒤 설정을 저장하고 현재 핵심을 재시작하세요. 설정 창만 닫아서는 안 됩니다.
- 노드를 전환한 뒤 로그를 다시 확인하여 클라이언트가 기본 라우팅으로 되돌아가지 않았는지 확인하세요.
- 구독 업데이트가 노드 데이터만 관리하는 경우 모든 사용자 지정 필드를 보존한다고 가정하지 마세요.
- 규칙 수가 늘어나면 용도별로 묶어 기록하고, 의미가 서로 반대인 광범위한 규칙 두 개가 생기지 않도록 하세요.
자주 발생하는 문제와 점검 순서
라우팅 문제는 특정 사이트가 잘못된 출구로 연결되거나, 로컬 네트워크 장치에 접근할 수 없거나, 규칙을 저장해도 변화가 없거나, 핵심이 바로 시작되지 않는 형태로 나타납니다. 문제를 확인할 때는 먼저 설정이 실제로 로드되었는지 확인하고, 다음으로 태그와 순서를 점검한 뒤, 마지막에 DNS 해석과 분류 데이터를 살펴보세요. 이 순서대로 진행하면 설정이 적용되지 않은 기본 문제부터 배제할 수 있습니다.
domain 규칙을 작성했는데 왜 앞의 geosite에 계속 매칭되나요?
정확한 domain 또는 full 규칙을 geosite 규칙보다 앞에 배치하고 저장한 뒤 핵심을 재시작하세요. 규칙은 정확도에 따라 자동 정렬되지 않으며, 먼저 매칭된 geosite가 이미 해당 요청의 매칭을 종료합니다.
IP 접속은 분기되는데 도메인 접속은 왜 geoip으로 처리되지 않나요?
routing.domainStrategy를 확인하세요. AsIs를 사용하면 모든 IP 규칙을 적용하기 위해 도메인을 일괄 해석하지 않습니다. 도메인 규칙이 매칭되지 않은 뒤 IP 판단을 시도해야 한다면 IPIfNonMatch 사용을 검토할 수 있습니다.
geosite를 추가한 뒤 핵심 시작 오류가 발생하면 어떻게 해야 하나요?
먼저 방금 추가한 분류를 삭제해 정상적으로 시작되는지 확인한 다음, 분류 이름과 현재 핵심이 불러온 데이터 파일을 대조하세요. 분류가 존재하지 않거나 데이터 파일을 읽을 수 없다면 규칙 순서를 바꿔도 오류가 해결되지 않습니다.
로컬 네트워크 주소가 왜 프록시로 전달되나요?
광범위한 프록시 규칙보다 앞에 geoip:private를 추가하거나 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16을 명시하세요. 그런 다음 라우터와 내부 네트워크 서비스 주소가 direct에 매칭되는지 테스트합니다.
규칙은 올바르게 보이는데 저장 후에도 변화가 없나요?
현재 방금 편집한 라우팅 설정이 활성화되어 있는지 확인한 뒤 핵심을 재시작하고 생성된 설정을 확인하세요. 노드를 전환한 뒤 규칙이 사라진다면 클라이언트가 routing 구간을 다시 생성하는지 점검해야 합니다.
관리하기 쉬운 트래픽 분기 설정에는 중복 규칙을 많이 쌓을 필요가 없습니다. 먼저 정확한 예외, 사설 주소, 주요 geosite 또는 geoip 분류, 최종 대체 규칙만 유지하고 로그를 확인하면서 꼭 필요한 항목만 추가하세요. 새 규칙을 만들 때 용도·대상 아웃바운드·검증 결과를 기록해 두면 데이터 파일을 업데이트하거나 핵심을 바꿀 때 어떤 규칙이 여전히 필요한지 빠르게 판단할 수 있습니다.
- 먼저 로드 여부 확인: 핵심 시작 로그와 생성된 routing 설정을 확인합니다.
- 다음은 태그 확인: outboundTag의 철자·대소문자와 연결된 아웃바운드를 대조합니다.
- 그다음은 순서 확인: 정확한 예외를 광범위한 분류보다 앞에 배치합니다.
- 마지막은 해석 확인: domainStrategy, DNS 설정, 실제 대상 IP를 함께 확인합니다.