이 글은 v2rayN, v2rayNG 또는 v2flyNG를 이미 정상적으로 사용하면서 어떤 요청을 직접 연결하고 프록시 또는 차단할지 더 세밀하게 제어하려는 사용자를 위한 내용입니다. domain, ip, geosite의 매칭 범위와 위에서 아래로 적용되는 우선순위, 여러 조건을 조합하는 방법을 설명하고, 구조를 바로 확인할 수 있는 Xray 라우팅 예시를 제공합니다.
먼저 라우팅 규칙이 처리하는 대상 이해하기
V2Ray와 Xray의 라우팅 모듈은 노드 연결을 직접 만드는 기능이 아니라, 연결이 코어에 들어온 뒤 어느 아웃바운드로 보낼지 결정하는 기능입니다. 일반적인 아웃바운드 태그는 proxy, direct, block이며 각각 프록시, 직접 연결, 차단에 해당합니다. 태그 이름은 프로토콜 키워드가 아니라 설정에 이미 정의된 outboundTag입니다. 클라이언트가 생성하는 태그가 다르면 실제로 생성된 이름을 규칙에도 사용해야 합니다.
하나의 요청에는 도메인, 대상 포트, 유입 경로, 조회된 IP가 동시에 포함될 수 있습니다. 규칙 배열은 순서대로 확인되며, 일반적으로 처음으로 완전히 일치한 규칙이 아웃바운드를 결정합니다. 따라서 “더 구체적인 규칙은 앞에, 범위가 넓은 규칙은 뒤에” 배치하는 것이 가장 중요한 정렬 원칙입니다. 적용 범위가 큰 geosite:cn 또는 geoip:cn을 앞에 두면 뒤에 작성한 특정 도메인 프록시 규칙이 적용될 기회를 잃을 수 있습니다.
같은 필드 안의 여러 값은 “하나라도 일치하면 됨”을 뜻하고, 서로 다른 필드는 “모두 동시에 충족해야 함”을 뜻합니다. 예를 들어 한 규칙에 domain과 port를 함께 지정하면 도메인 조건과 포트 조건이 모두 충족될 때만 일치합니다. 반면 domain 배열에 도메인 세 개를 넣으면 그중 하나만 일치해도 됩니다. 이 차이 때문에 규칙이 맞아 보이지만 실제로는 예상한 요청을 처리하지 못하는 경우가 많습니다.
| 매칭 대상 | 대표적인 작성법 | 적합한 사용 사례 | 주요 제한 사항 |
|---|---|---|---|
| 도메인 | domain:example.com |
웹사이트·API·다운로드 도메인별 트래픽 분할 | 애플리케이션이 도메인을 코어에 전달하거나 코어가 도메인을 조회할 수 있어야 함 |
| IP | 192.0.2.0/24 |
고정 네트워크 대역·로컬 네트워크·조회 결과별 트래픽 분할 | 도메인 요청을 IP 매칭으로 전환할지는 domainStrategy의 영향을 받음 |
| geosite | geosite:category-ads-all |
관리 중인 도메인 목록을 기준으로 일괄 매칭 | 클라이언트가 현재 사용하는 지리 데이터 파일과 분류 태그에 의존함 |
| geoip | geoip:private |
사설 주소 또는 국가·지역별 IP 대역 | 대상 IP만 매칭하며 geosite 도메인 분류와는 다름 |
domain을 작성하는 다섯 가지 방법
domain:은 일상적인 규칙 관리에 가장 적합한 도메인 작성법입니다. domain:example.com은 example.com과 api.example.com 같은 하위 도메인까지 매칭하지만, notexample.com을 같은 도메인 접미사로 처리하지는 않습니다. 특정 사이트와 모든 서비스 하위 도메인을 함께 적용하려면 이 형식을 우선 사용하세요.
full:은 완전한 도메인 일치만 처리합니다. full:api.example.com은 해당 호스트 이름과 일치하지만 www.example.com이나 v2.api.example.com에는 적용되지 않습니다. 특정 API만 프록시로 보내고 같은 주 도메인의 다른 서비스에는 일반 규칙을 적용할 때 적합합니다.
접두사가 없는 일반 문자열은 부분 문자열 매칭으로 처리됩니다. 예를 들어 example은 도메인 안에서 해당 문자열을 포함하는 여러 위치와 일치할 수 있어 범위가 예상보다 넓어집니다. regexp:는 정규 표현식을 지원해 가장 유연하지만, 규칙이 많으면 원인을 추적하기 어렵고 경계를 정확히 작성하지 않을 경우 오매칭도 늘어납니다. domain:이나 full:로 표현할 수 있다면 처음부터 정규식을 사용할 필요는 없습니다.
domain 접미사 매칭
권장주 도메인과 모든 하위 도메인을 함께 처리하며 의미가 명확해 대부분의 웹사이트 규칙에 적합합니다.
적합: 전체 사이트 프록시, 전체 사이트 직접 연결
full 완전 일치
하나의 특정 호스트 이름만 처리하며 같은 주 도메인의 다른 서비스까지 확장하지 않습니다.
적합: 단일 API, 단일 다운로드 도메인
regexp 정규식 매칭
복잡한 이름 규칙을 표현할 수 있지만 점의 이스케이프와 문자열 양끝 경계는 직접 처리해야 합니다.
적합: 규칙적인 하위 도메인이 많은 경우
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:static.example.net",
"regexp:^img-[0-9]+\\.example\\.org$"
],
"outboundTag": "proxy"
}
위 예시의 domain 세 항목은 “또는” 관계입니다. 요청이 그중 하나와 일치하면 해당 규칙의 다른 필드를 계속 확인합니다. 예시에는 추가 필드가 없으므로 바로 proxy 아웃바운드로 전달됩니다. 정규식의 점은 이스케이프해야 하며, JSON 문자열에서는 백슬래시도 보존해야 하므로 설정에는 \\.로 표시됩니다.
ip·CIDR과 domainStrategy의 연동
IP 규칙에는 단일 주소나 CIDR 네트워크 대역을 사용할 수 있습니다. IPv4 단일 주소는 192.0.2.10, 네트워크 대역은 192.0.2.0/24로 작성할 수 있으며 IPv6는 2001:db8::/32처럼 작성합니다. CIDR 뒤의 숫자는 네트워크 프리픽스 길이를 의미합니다. /24는 IPv4 주소 256개를 포함하며 포트나 주소 개수로 해석하면 안 됩니다.
geoip:private는 사설 주소를 직접 연결할 때 자주 사용하며 대표적인 로컬 네트워크 대역을 처리할 수 있습니다. 실제 설정에서는 루프백 주소와 로컬 서비스도 별도로 처리해야 라우터 관리 페이지, NAS 또는 127.0.0.1에서 실행 중인 프로그램이 원격 프록시로 전달되는 일을 막을 수 있습니다. v2rayN에서 흔히 사용하는 로컬 SOCKS 수신 포트는 10808이며 HTTP 포트는 같은 혼합 진입점이나 인접 포트에서 제공될 수 있습니다. 정확한 값은 「설정」→「매개변수 설정」의 로컬 수신 설정을 기준으로 확인하세요.
- AsIs: 요청에 포함된 도메인을 우선 매칭하며, IP 규칙을 시도하기 위해 도메인을 임의로 조회하지 않습니다.
- IPIfNonMatch: 먼저 도메인 규칙을 확인하고, 도메인 규칙에서 결과가 나오지 않을 때 대상 도메인을 조회한 뒤 IP 규칙을 시도합니다.
- IPOnDemand: 대상 IP가 필요할 가능성이 있는 규칙을 확인하면 조회를 시작할 수 있습니다. IP 기반 분할 라우팅이 명확한 설정에 적합하지만 DNS 결과가 더 일찍 개입합니다.
- 직접 IP 요청: 애플리케이션이 IP에 직접 연결하는 경우 도메인을 주소로 변환할 필요가 없으며 IP와 geoip 규칙이 바로 매칭에 참여할 수 있습니다.
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private",
"127.0.0.0/8",
"192.0.2.0/24"
],
"outboundTag": "direct"
}
]
}
결론: 도메인 예외를 IP 대분류보다 먼저 배치
특정 도메인을 반드시 프록시로 보내야 하는데 해당 도메인이 직접 연결 규칙에 포함된 주소 대역으로 조회될 수 있다면, 해당 도메인의 프록시 규칙을 IP 직접 연결 규칙보다 앞에 배치하세요. 로그를 통해 요청이 처음부터 도메인을 포함했는지 IP만 포함했는지도 확인해야 합니다.
geosite 분류 활용법
geosite는 도메인 집합으로 구성된 데이터 분류이며 실시간 조회 서비스가 아닙니다. geosite:cn은 데이터 파일에서 해당 분류에 포함된 도메인을 의미하고, geosite:category-ads-all은 일반적으로 광고 도메인 모음에 사용됩니다. 분류 내용은 클라이언트에 포함된 데이터 버전에 따라 달라지므로 geosite는 넓은 범위의 기본 분할 라우팅에 활용하고, 중요한 사용자 지정 도메인 예외는 앞에 별도로 작성해야 합니다.
geosite와 geoip는 서로 바꿔 사용할 수 없습니다. 어떤 도메인이 특정 geosite 분류에 속한다고 해서 현재 조회된 IP가 같은 이름의 geoip 분류에 속한다는 뜻은 아닙니다. 콘텐츠 전송 네트워크를 사용하면 같은 도메인도 네트워크 환경에 따라 다른 주소를 받을 수 있습니다. 먼저 geosite로 도메인의 의미를 처리하고, 매칭되지 않은 연결에는 geoip를 예비 규칙으로 사용하는 편이 IP만 기준으로 관리하는 것보다 일반적으로 쉽습니다.
차단 분류는 순서에 특히 주의해야 합니다. 어떤 업무 API가 광고 분류에 포함되어 있지만 페이지를 정상적으로 로드하는 데 필요한 경우, 일반 차단 규칙이 해당 API까지 막을 수 있습니다. 모든 광고 분류를 삭제하는 대신 차단 규칙 앞에 full: 또는 domain: 예외 규칙을 추가하고 direct 또는 proxy로 보내세요.
[
{
"type": "field",
"domain": [
"full:required-api.example.com"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
}
]
매칭 우선순위와 규칙 편집 순서
규칙 우선순위는 domain, ip, geosite의 유형이 자동으로 결정하는 것이 아니라 주로 배열에서의 위치로 결정됩니다. 코어는 첫 번째 규칙부터 확인하고, 일치하면 뒤의 규칙이 결과를 덮어쓰지 못합니다. 따라서 단일 도메인 예외는 분류 규칙보다 앞에, 분류 규칙은 최종 예비 규칙보다 앞에 배치해야 하며, 차단 규칙을 업무 예외보다 무조건 앞에 두어서도 안 됩니다.
v2rayN 7.x의 화면 문구는 소버전에 따라 달라질 수 있지만 확인 순서는 동일하게 유지할 수 있습니다. 먼저 사용 중인 코어를 확인하고, 라우팅 설정을 연 다음, 활성화된 라우팅 구성과 규칙 순서를 확인하세요. 수정 후에는 코어를 재시작하거나 설정을 다시 불러와야 하며, 창에서 저장만 한 채 이전 실행 설정을 계속 사용하면 안 됩니다.
코어 확인
「설정」→「매개변수 설정」→「Core 유형」을 열어 현재 설정이 Xray 또는 v2fly에 해당하는 코어를 사용하는지 확인하세요. 프로토콜과 라우팅 필드는 선택한 코어가 지원해야 합니다.
라우팅 설정 열기
「설정」→「라우팅 설정」으로 이동해 현재 활성화된 라우팅 구성을 선택하세요. 화면에 여러 구성이 있다면 먼저 메인 화면에서 실제로 선택된 구성 이름을 확인합니다.
예외 추가
반드시 프록시 또는 직접 연결해야 하는
full:·domain:규칙을 먼저 추가한 다음, geosite·geoip처럼 범위가 넓은 분류 규칙을 추가하세요.아웃바운드 확인
규칙 대상이 프록시, 직접 연결, 차단 중 무엇인지 확인하세요. 원본 설정을 편집할 때는
outboundTag가 기존 아웃바운드 태그와 한 글자씩 정확히 일치하는지도 확인해야 합니다.다시 불러온 뒤 검증
저장한 후 코어를 재시작하고, 예외에 일치하는 도메인 하나, 분류에 일치하는 도메인 하나, 로컬 네트워크 주소 하나를 각각 테스트하세요. 코어 로그에서 실제 라우팅 결과도 확인합니다.
결론: 범위가 좁은 규칙부터 넓은 규칙 순으로 배치
완전한 도메인, 도메인 접미사, geosite 분류, geoip 네트워크 대역, 최종 예비 규칙 순으로 범위를 넓히면 넓은 규칙이 요청을 너무 일찍 가로채는 문제를 줄일 수 있습니다. 실제 업무 예외는 항상 해당 대분류보다 앞에 배치하세요.
직접 연결·프록시·차단 3방향 규칙 예시
다음은 구조를 이해하기 위한 완전한 라우팅 예시입니다. 지정한 API를 먼저 프록시로 보내고, 광고 분류를 차단한 다음, 로컬 네트워크와 지정 도메인은 직접 연결합니다. 앞의 규칙에 처리되지 않은 연결은 마지막으로 프록시로 보냅니다. 사용하기 전에 설정에 proxy, direct, block이라는 세 아웃바운드가 존재하는지 확인하세요.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:services.example.net"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"domain": [
"domain:printer.example.lan",
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private",
"127.0.0.0/8"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
마지막 규칙은 network만 제한하며 TCP와 UDP를 모두 포함하므로 예비 규칙 역할을 합니다. 반드시 배열의 마지막에 배치해야 합니다. 첫 번째에 두면 대부분의 일반적인 연결이 즉시 프록시로 들어가 뒤의 직접 연결 및 차단 규칙이 확인되지 않습니다. TCP만 프록시로 보내려면 UDP까지 예비 규칙에 포함하지 마세요. DNS나 실시간 통신 트래픽의 아웃바운드도 바뀔 수 있습니다.
포트 조건도 도메인과 조합할 수 있습니다. 예를 들어 domain에 domain:example.com, port에 443을 지정하면 해당 도메인의 443 포트에 접속할 때만 일치합니다. 같은 도메인의 80 포트에 접속하면 뒤의 규칙을 계속 확인합니다. 포트 범위는 코어가 지원하는 형식으로 작성할 수 있지만, 일상적인 설정에서는 명확한 업무 포트로 범위를 제한해 해석하기 어려운 광범위한 매칭을 피하는 것이 좋습니다.
- 프록시 예외 테스트: 첫 번째 규칙에 명시한 도메인에 접속해 로그에
proxy가 표시되는지 확인합니다. - 차단 규칙 테스트: 현재 geosite 분류에 확실히 포함된 도메인을 선택하고 연결이
block으로 전달되는지 확인합니다. - 로컬 네트워크 직접 연결 테스트: 라우터 또는 로컬 네트워크 서비스 주소에 접속해
geoip:private또는 명시한 CIDR에 일치하는지 확인합니다. - 최종 예비 규칙 테스트: 앞의 어떤 분류에도 속하지 않는 대상을 선택하고 마지막 규칙이 아웃바운드를 처리하는지 확인합니다.
규칙이 적용되지 않을 때 단계별 점검
문제 해결의 핵심은 “코어가 실제로 어떤 대상을 받았는가”와 “어느 규칙이 먼저 일치했는가”를 확인하는 것입니다. 브라우저에서 도메인에 접속해도 코어가 도메인을 받을 수 있고, 상위 애플리케이션이 조회한 IP만 받을 수도 있습니다. 투명 진입점, 시스템 프록시, 애플리케이션 내부 프록시는 전달하는 정보가 서로 완전히 같지 않습니다. 브라우저 주소 표시줄만 보고 코어가 반드시 도메인을 받았다고 판단하지 마세요.
다음으로 클라이언트가 설정을 다시 생성하고 불러왔는지 확인하세요. v2rayN에서 라우팅 구성을 수정했더라도 현재 선택된 구성이 방금 편집한 구성이 아니면 저장한 내용이 실제 트래픽에 반영되지 않습니다. v2rayNG 또는 v2flyNG에서 구독 설정을 사용하는 경우에는 구독 업데이트와 로컬 라우팅 수정도 구분해야 하며, 구독을 업데이트하면서 이전 변경 사항이 덮어쓰이지 않았는지 확인하세요.
도메인을 따로 지정했는데 왜 여전히 직접 연결되나요?
해당 도메인 규칙을 geosite:cn 및 geoip:cn보다 앞으로 이동하고, outboundTag가 프록시를 가리키는지 확인하세요. 그런 다음 코어를 재시작하고 로그에서 앞쪽의 직접 연결 규칙이 먼저 일치하지 않았는지 확인합니다.
geosite 태그를 추가하자마자 시작에 실패하나요?
코어 오류 로그에 표시된 정확한 태그 이름을 확인하고 현재 데이터 파일에 해당 분류가 포함되어 있는지 점검하세요. 먼저 일반적인 분류 하나로 최소 구성을 테스트하고, 출처가 불명확한 태그를 여러 개 동시에 추가하지 마세요. 태그가 존재하지 않으면 명확한 domain: 규칙으로 바꾸어야 합니다.
도메인 규칙은 일치하는데 IP 규칙은 일치하지 않나요?
domainStrategy를 확인하세요. 도메인 규칙이 일치하지 않은 뒤에도 조회를 계속해 IP 규칙을 시도해야 한다면 IPIfNonMatch를 사용할 수 있습니다. 변경 후에는 DNS가 예상한 주소를 반환하는지도 함께 확인하세요.
로컬 네트워크 관리 페이지가 프록시로 전송되나요?
최종 프록시 예비 규칙 앞에 geoip:private와 필요한 로컬 네트워크 CIDR의 직접 연결 규칙을 추가하세요. 사용자 지정 로컬 네트워크 도메인을 사용한다면 해당 도메인에 대한 full: 또는 domain: 직접 연결 항목도 추가합니다.
규칙을 저장해도 결과가 전혀 바뀌지 않나요?
메인 화면에서 방금 편집한 라우팅 구성이 활성화되어 있는지 확인한 다음 코어를 재시작하세요. 이어서 「설정」→「매개변수 설정」→「Core 유형」을 확인해 현재 실행 중인 코어 및 데이터 집합과 다른 설정을 사용하고 있지 않은지 점검합니다.
규칙을 관리할 때는 한 번에 하나의 대상만 조정하는 것이 좋습니다. 먼저 특정 도메인의 아웃바운드를 해결하고, 그다음 geosite 분류로 확장한 뒤, 마지막으로 IP와 geoip 예비 규칙을 처리하세요. 변경할 때마다 프록시·직접 연결·차단 테스트 대상을 하나씩 유지하면 구독, 코어 또는 지리 데이터가 업데이트되어도 어느 계층에서 변화가 발생했는지 빠르게 찾을 수 있습니다.