V2Ray 사용자 지정 라우팅 규칙 설정법: domain·IP·geosite 매칭 문법과 우선순위

domain 접두사 full·domain·keyword·regexp와 geosite·geoip 데이터셋 사용법, 위에서부터 적용되는 규칙 순서 및 규칙 충돌 방지법을 설명합니다.

이 글 한눈에 보기

노드를 이미 가져왔으며 직접 연결과 프록시 분할 설정을 조정하려는 사용자를 위한 글입니다. 먼저 도메인 매칭과 IP 매칭을 구분하고, 설정 예시로 규칙 순서와 DNS 조회 정책, 기본 아웃바운드를 설명합니다. 특히 키워드 매칭은 보통 문자열을 그대로 입력하며, 설명에 나온 keyword를 범용 JSON 접두사처럼 사용하면 안 됩니다. 예시 도메인만 사용하며 연결 가능한 프록시 노드는 포함하지 않습니다.

1. 라우팅은 아웃바운드를 선택하며 노드를 만들지는 않습니다

V2Ray 라우팅은 연결의 대상 주소와 포트, 네트워크 유형 등을 확인한 뒤 해당 연결을 아웃바운드로 전달합니다. 구독을 노드로 변환하는 기능은 없으며, outboundTag: "proxy"를 작성해도 프록시 서버가 자동으로 생성되지 않습니다. 태그는 참조값일 뿐이므로 현재 설정의 outbounds에 일치하는 tag가 있어야 합니다.

인바운드에서 연결 수신대상 정보 확인순서대로 규칙 매칭아웃바운드 태그 선택대상에 연결

도메인 규칙의 적용 여부는 코어가 도메인 정보를 전달받았는지에 따라 달라집니다. 앱이 SOCKS를 통해 도메인을 전달하면 코어에서 바로 매칭할 수 있습니다. 반면 앱이 먼저 도메인을 조회한 뒤 IP를 전달하면 도메인 정보가 사라졌을 수 있습니다. 트래픽 스니핑으로 일부 프로토콜에서 호스트명을 확인할 수는 있지만, 모든 암호화 트래픽에서 도메인을 복원할 수 있는 것은 아니며 DNS를 대체하지도 않습니다.

2. domain 매칭 방식 네 가지: 정확히 일치, 하위 도메인, 키워드, 정규식

domain은 문자열 배열입니다. 같은 배열에 있는 항목은 OR 조건이므로 하나라도 일치하면 됩니다. 경계 차이를 확인할 수 있도록 example.com을 예로 들겠습니다. 도메인 항목에 전체 URL이나 경로, 쿼리 매개변수를 넣지 마세요. 라우팅은 브라우저 주소창의 전체 URL을 대상으로 매칭하지 않습니다.

방식매칭 범위경계 조건
full:example.comexample.com만www.example.com은 포함하지 않음
domain:example.com루트 도메인과 하위 도메인notexample.com은 매칭하지 않음
example도메인에 example이 포함된 문자열notexample.net도 매칭될 수 있음
regexp:^api[0-9]+\.example\.com$api 뒤에 숫자가 오는 특정 하위 도메인JSON에서 백슬래시를 이스케이프해야 함
{
  "type": "field",
  "domain": [
    "full:login.example.com",
    "domain:static.example.com",
    "regexp:^api[0-9]+\\.example\\.com$"
  ],
  "outboundTag": "proxy"
}

위 정규식은 JSON 문자열이므로 정규식의 백슬래시 하나를 두 개로 입력해야 합니다. ^와 $는 문자열의 시작과 끝을 지정해 도메인의 일부만 매칭되는 것을 방지합니다. 사이트 전체를 분할 라우팅하려면 범용 키워드나 복잡한 정규식보다 domain:을 사용하는 편이 확인하기 쉽습니다.

3. geosite와 geoip: 분류 데이터는 자동으로 추론되지 않습니다

geosite는 도메인 분류를 참조하며 domain 배열에 넣습니다. geoip는 IP 분류를 참조하며 ip 배열에 넣습니다. 두 방식 모두 코어에서 읽을 수 있는 데이터 파일과 그 안에 실제로 존재하는 분류가 필요합니다. 분류명을 입력한다고 온라인 검색이 실행되거나 누락된 데이터가 자동으로 다운로드되지는 않습니다.

도메인 분류 규칙

규칙 필드
domain
항목 예시
geosite:cn
일반적인 데이터 파일
geosite.dat
매칭 기준
데이터셋에 등록된 도메인 규칙

분류 내용은 데이터 파일에 따라 결정되며 서버 위치와는 다릅니다.

IP 분류 규칙

규칙 필드
ip
항목 예시
geoip:private
일반적인 데이터 파일
geoip.dat
매칭 기준
데이터셋에 포함된 IP 주소 대역

예시 분류가 현재 데이터 파일에 있는지 확인하세요. 로드 오류가 나면 먼저 파일과 분류명을 점검하세요.

도메인이 특정 분류에 속한다고 해서 모든 CDN 주소의 IP가 같은 지역에 속하는 것은 아닙니다. 반대로 특정 IP가 지역 분류에 포함되어 있다고 해서 그 주소를 사용하는 모든 도메인을 직접 연결해야 하는 것도 아닙니다. 명시적으로 제어할 도메인은 별도 규칙으로 작성해 광범위한 분류보다 앞에 배치하세요.

4. ip, CIDR, 포트: 같은 필드는 OR, 서로 다른 필드는 AND

ip에는 단일 주소와 CIDR 대역, 지원되는 데이터셋 참조를 지정할 수 있습니다. CIDR의 슬래시 뒤 숫자는 프리픽스 길이이며 포트가 아닙니다. 아래 세 숫자는 입력 문법을 확인하기 위한 경계값이지 네트워크 속도 측정 결과가 아닙니다.

/32
단일 IPv4 주소의 프리픽스
/128
단일 IPv6 주소의 프리픽스
443
아래 예시에서 제한하는 대상 포트
{
  "type": "field",
  "ip": [
    "192.168.0.0/16",
    "10.0.0.0/8",
    "fc00::/7"
  ],
  "port": "443",
  "network": "tcp",
  "outboundTag": "direct"
}

이 규칙은 ‘대상 IP가 세 대역 중 하나에 속하고, 대상 포트가 443이며, 네트워크 유형이 TCP’인 연결만 직접 연결합니다. 모든 사설 네트워크 트래픽을 직접 연결하는 규칙은 아닙니다. 내부 기기의 80번 포트에 접속하거나 UDP 서비스를 이용하는 연결은 이후 규칙을 계속 확인해야 합니다.

같은 규칙에 domain을 추가해도 ‘도메인 또는 IP 중 하나만 조건을 충족하면 됨’이 아니라, 두 조건을 모두 충족해야 하는 규칙이 됩니다. 특히 처음 전달된 대상이 도메인이고 아직 DNS 조회가 이루어지지 않았다면 예상과 다르게 동작할 수 있습니다. ‘지정 도메인은 직접 연결하고 지정 IP도 직접 연결’하려면 규칙을 두 개로 나누세요.

요점: 규칙을 먼저 나누고 조건은 필요할 때 결합하세요

도메인 예외와 IP 대역 예외를 각각 별도 규칙으로 작성하고, 각각 제대로 매칭되는지 확인하세요. 그다음 포트나 네트워크 유형을 함께 제한해야 하는지 검토하면 됩니다.

5. 규칙은 위에서부터 매칭되며, ‘더 구체적인 규칙 우선’으로 정렬되지 않습니다

한 차례 규칙을 확인할 때 먼저 매칭된 규칙이 아웃바운드를 결정하며, 뒤에 있는 규칙은 결과를 다시 바꾸지 않습니다. 코어가 full:을 geosite:보다 앞에 자동 배치하거나 도메인이 길수록 우선순위를 높이지도 않습니다. 구체적인 예외와 서비스별 규칙, 광범위한 분류, 최종 기본 규칙은 설정에서 직접 순서를 정해야 합니다.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["full:login.example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["domain:example.com"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

병합할 때 사용하는 routing 조각이며 완전한 클라이언트 설정은 아닙니다. proxy와 direct 아웃바운드가 이미 있어야 하며, direct는 일반적으로 freedom 프로토콜을 사용합니다. 첫 번째 규칙은 로그인 도메인을 프록시로 보내고, 두 번째 규칙은 나머지 루트 도메인과 하위 도메인을 직접 연결합니다. 두 규칙의 순서를 바꾸면 두 번째 규칙이 로그인 도메인에 먼저 적용됩니다.

  1. 도메인을 먼저 확인하고 매칭되지 않을 때 IP 규칙을 시도하려면 IPIfNonMatch를 사용하고, 모든 트래픽에 미리 매칭되는 기본 규칙은 피하세요.
  2. IP 규칙까지 확인할 때 조회를 시도하려면 IPOnDemand를 검토하고, 추가 DNS 요청과 대기 시간을 함께 고려하세요.
  3. 전체 트래픽에 매칭되는 기본 규칙을 작성하지 않았다면 outbounds의 첫 항목을 확인하세요. 어떤 규칙에도 매칭되지 않은 트래픽은 첫 번째 아웃바운드를 사용합니다. 태그 이름 자체에 특별한 기본 동작은 없습니다.

6. domainStrategy와 DNS: 먼저 대상 정보부터 확인하세요

같은 규칙 그룹이 브라우저에서는 정상 작동하지만 다른 프로그램에서는 다르게 동작할 수 있습니다. 반드시 규칙이 무시된 것은 아닙니다. 한 프로그램은 도메인을 전달하고 다른 프로그램은 이미 조회된 IP를 전달하는 등 대상 정보가 서로 다를 수 있습니다. 라우팅 조회 정책은 라우팅 판단에 필요한 조회 방식만 제어하며 앱과 시스템, 코어가 같은 DNS를 사용한다고 보장하지 않습니다.

정책실행 조건확인할 사항
AsIs라우팅에서 도메인에 IP를 자동으로 추가 조회하지 않음원래 대상이 도메인이라면 IP 분류에 따른 분할 라우팅을 기대할 수 없음
IPIfNonMatch도메인이 첫 번째 규칙 확인에서 매칭되지 않으면 조회한 뒤 다시 매칭너무 앞에 있는 전체 매칭 규칙이 두 번째 확인을 막을 수 있음
IPOnDemand도메인 요청이 IP 판단이 필요한 규칙에 매칭되면 조회 시도IP 규칙의 위치와 DNS 연결 가능 여부 모두 결과에 영향을 줌

라우팅을 변경해도 이미 연결된 장시간 연결은 보통 아웃바운드를 다시 선택하지 않습니다. 테스트 프로그램의 기존 연결을 닫고 새 요청을 보내세요. 필요하면 코어를 다시 시작합니다. DNS와 스니핑, 라우팅 순서를 동시에 바꾸면 어떤 변경이 결과에 영향을 줬는지 파악하기 어렵습니다. 한 번에 변수 하나만 바꾸고 복구할 수 있도록 설정 사본을 보관하세요.

7. 클라이언트에 적용하고 규칙이 적용되지 않을 때 확인할 사항

v2rayN은 데스크톱 클라이언트이며, v2rayNG는 Xray 코어를, v2flyNG는 v2fly 코어를 사용합니다. 이 글의 예시는 두 코어에서 일반적으로 사용하는 네이티브 라우팅 필드를 사용하지만, 확장 문법과 데이터 파일, UI 가져오기 형식이 모두 동일하다는 뜻은 아닙니다. 클라이언트에 저장된 규칙 항목과 최종 생성되는 코어 JSON의 파일 형식도 다를 수 있습니다.

  1. 현재 설정을 백업하세요. v2rayN의 ‘설정’ → ‘라우팅 설정’에서 현재 활성화된 라우팅 구성을 확인하세요. UI 버전에 따라 메뉴 이름과 위치가 조금 다를 수 있습니다. 먼저 구성을 복사한 다음 명확한 full: 예외 규칙을 하나 추가하세요.
  2. 생성된 설정을 확인하세요. 실제 실행 설정에서 routing.rules의 순서와 outbounds 태그를 확인하고, 전역 프록시 또는 전역 직접 연결 모드가 설정을 덮어쓰지 않았는지도 점검하세요.
  3. 규칙 입력 양식과 전체 설정을 구분하세요. v2rayNG의 ‘설정’ → ‘라우팅 설정’에서 자주 사용하는 도메인 및 IP 분할 항목을 확인할 수 있습니다. 이 입력 양식은 네이티브 JSON 편집기와 다릅니다. 순서가 중요한 복잡한 규칙은 현재 버전에서 지원하는 사용자 지정 설정 방식을 사용하세요.
  4. 새로 연결하세요. 설정을 적용하고 서비스를 다시 시작한 뒤 실행 로그를 확인하세요. 페이지 새로고침만으로는 기존 연결이 계속 사용될 수 있습니다. 로그에 라우팅 세부 정보가 표시되지 않으면 테스트 중에만 로그 수준을 높이고, 테스트를 마친 뒤 원래대로 되돌리세요.

도메인을 입력했는데도 왜 프록시를 통해 연결되나요?

먼저 해당 규칙이 프록시 기본 규칙보다 앞에 있는지 확인한 다음, 테스트를 위해 단일 full: 규칙으로 바꿔 보세요. 코어에 전달된 대상이 도메인인지 IP인지 확인하세요. IP만 전달된 경우 도메인 항목을 추가해도 누락된 도메인 정보를 복구할 수 없습니다.

geosite를 추가한 뒤 서비스가 시작되지 않으면 어떻게 하나요?

먼저 이전 설정으로 되돌리고 로그에서 구체적인 분류명과 파일 경로를 확인하세요. 데이터 파일을 읽을 수 있고 분류가 실제로 존재하는지 확인한 뒤 규칙을 추가하세요. 여러 분류명을 연달아 바꿔 가며 추측하지 마세요.

규칙 저장은 완료됐는데 왜 아무 변화가 없나요?

편집한 라우팅 구성이 현재 활성화되어 있는지, 전역 모드가 설정을 덮어쓰지 않았는지 확인하세요. 코어를 다시 시작하고 새로 연결한 뒤 입력 양식의 안내만 보지 말고 실제 설정의 아웃바운드 태그를 확인하세요.

모든 조건을 규칙 하나에 넣어도 되나요?

모든 조건이 동시에 충족되어야 할 때만 그렇게 설정하세요. 도메인과 IP, 포트, 네트워크 유형을 함께 지정하면 AND 조건이 됩니다. 서로 별개인 예외를 표현하려면 규칙을 나누고, 명확한 예외가 먼저 매칭되도록 순서를 정하세요.

마지막으로 새 연결을 세 번 만들어 설정을 확인하세요. 정확히 일치하는 예외 도메인 하나, 일반 하위 도메인 하나, 확인된 사설 IP 하나를 테스트합니다. 각각 대상 형식과 매칭된 규칙, 아웃바운드 태그를 기록하세요. 이렇게 하면 ‘문법이 로드되는지’, ‘규칙이 실제로 매칭되는지’, ‘아웃바운드로 연결할 수 있는지’를 따로 확인할 수 있어 노드 오류를 라우팅 문제로 오해하지 않습니다. 자세한 개념은 용어집에서 확인하고, 설정의 범위는 고급 설정을 참고하세요.

클라이언트 다운로드v2rayN / v2rayNG