구독을 가져온 뒤 특정 웹사이트나 IP 대역의 트래픽을 따로 라우팅하려는 사용자에게 적합합니다. 도메인 조건과 IP 조건의 차이를 먼저 살펴보고, 규칙 순서와 DNS 조회 시점도 확인합니다. 글을 읽고 나면 제한된 범위의 예외 규칙을 작성하고 로그를 통해 규칙이 적용되거나 적용되지 않은 이유를 파악할 수 있습니다.
라우팅 매칭 우선순위: 먼저 일치하는 규칙이 적용됩니다
V2Ray와 Xray의 일반적인 라우팅 규칙은 routing.rules 배열을 위에서 아래로 확인합니다. 규칙 하나가 일치하면 지정된 아웃바운드를 사용하고, 더 정확한 다음 규칙을 찾으러 가지 않습니다. 따라서 정확한 도메인 규칙을 넓은 범위의 분류 규칙 뒤에 두면 자동으로 우선 적용되지 않습니다. 예외 규칙은 앞쪽에 배치해야 합니다.
한 규칙 안에서 domain 배열의 여러 항목은 일반적으로 OR 조건입니다. 항목 중 하나라도 일치하면 됩니다. 서로 다른 조건 필드는 보통 AND 조건으로 처리됩니다. domain과 port를 함께 지정하면 도메인과 대상 포트가 모두 일치해야 합니다. 도메인과 IP를 같은 규칙에 넣었다고 해서 둘 중 하나만 맞으면 적용되는 것은 아닙니다.
다음은 지정한 호스트의 443 포트만 프록시로 보내는 코어 규칙입니다. 여기서 proxy는 아웃바운드 태그이지 내장 키워드가 아닙니다. 전체 설정에 같은 이름의 아웃바운드가 있어야 합니다. 노드 표시 이름도 아니므로 구독에 있는 노드 이름으로 확인 없이 바꾸면 안 됩니다.
{
"type": "field",
"domain": ["full:portal.example.com"],
"port": "443",
"outboundTag": "proxy"
}
domain, full, regexp: 도메인 작성법과 매칭 범위
domain은 규칙의 필드 이름이고, domain:은 필드 값에 사용하는 매칭 프리픽스 중 하나입니다. 서로 다른 단계의 표현입니다. "domain": ["domain:example.com"]처럼 작성해야 완전한 필드 표현이 됩니다. full이나 regexp를 domain과 같은 수준의 규칙 필드로 취급하지 마세요.
| 항목 형식 | 의미 | 범위 관련 참고 사항 |
|---|---|---|
full:example.com | 호스트 이름 전체와 정확히 일치 | www.example.com은 포함하지 않음 |
domain:example.com | 루트 도메인과 하위 도메인에 매칭 | a.example.com은 포함하지만 notexample.com은 포함하지 않음 |
regexp:^api[0-9]+\.example\.com$ | 정규식으로 매칭 | 여기에는 매칭 표현식을 표시합니다. JSON에 입력할 때는 백슬래시를 한 번 더 이스케이프해야 합니다 |
example.com | 프리픽스가 없는 문자열은 부분 문자열로 매칭 | 예상보다 넓은 범위와 일치할 수 있어 정확한 예외 규칙에는 부적합 |
geosite:cn | 도메인 데이터베이스의 분류 참조 | 분류 항목은 현재 불러온 데이터 파일에 따라 달라집니다 |
사이트 하나만 예외 처리하려면 full:을 우선 사용하세요. 루트 도메인과 모든 하위 도메인을 같은 출구로 보내려면 domain:을 사용하면 됩니다. 호스트 이름에 일정한 패턴이 있을 때만 정규식을 쓰세요. 도메인 항목에는 https://, 경로 또는 쿼리 매개변수를 입력하지 마세요. 라우팅은 브라우저 주소창의 전체 URL이 아니라 대상 호스트를 기준으로 판단합니다.
{
"type": "field",
"domain": [
"full:portal.example.com",
"domain:static.example.net",
"regexp:^api[0-9]+\\.example\\.com$"
],
"outboundTag": "proxy"
}
이 배열의 세 항목은 대체 조건입니다. api12.example.com에 접속하면 정규식이 매칭될 수 있고, img.static.example.net에 접속하면 도메인 접미사가 매칭될 수 있습니다. JSON의 \\.는 파싱된 뒤 정규식의 \.가 됩니다. 이스케이프를 한 단계 덜 하면 설정을 불러오지 못할 수 있습니다.
ip, geoip, geosite: IP 대역과 분류 데이터는 구분해서 작성
ip 배열에는 대상 IP 조건을 지정합니다. 단일 주소, CIDR 대역, geoip: 분류를 입력할 수 있습니다. geosite:는 도메인 조건이므로 domain 배열에 넣어야 합니다. 두 분류 프리픽스를 서로 바꿔 쓰면 도메인과 주소를 함께 라우팅하려는 의도대로 동작하지 않습니다.
{
"type": "field",
"ip": [
"192.168.10.0/24",
"10.0.0.8/32",
"geoip:private"
],
"outboundTag": "direct"
}
- 단일 장치:
10.0.0.8/32는 이 IPv4 주소 하나만 매칭합니다. 단일 IPv6 주소에는/128을 사용할 수 있습니다. - 전체 대역:
192.168.10.0/24는 해당 IPv4 대역 전체를 포함하며, 명확한 로컬 네트워크 대상에 적합합니다. - 주소 분류:
geoip:cn은 IP 주소 데이터베이스를 사용하며, 특정 웹사이트의 실제 서비스 지역과 일치한다고 보장할 수 없습니다. - 도메인 분류:
geosite:cn은 도메인 데이터베이스를 사용합니다. 데이터베이스에 등록되지 않은 새 도메인은 사이트가 중국어를 사용한다고 해서 자동으로 매칭되지 않습니다.
웹사이트는 여러 콘텐츠 전송 네트워크를 함께 사용할 수 있으며, 같은 도메인도 네트워크 환경에 따라 서로 다른 지역의 IP로 확인될 수 있습니다. 도메인 분류와 주소 분류가 서로 다른 출구를 선택하더라도 규칙이 잘못된 것은 아닐 수 있습니다. 먼저 목표가 “이 웹사이트를 항상 프록시로 보내기”인지 “이 주소 대역을 직접 연결하기”인지 확인한 뒤 조건을 선택하세요.
domainStrategy: 라우팅을 위해 도메인을 조회하는 시점
routing.domainStrategy는 라우팅 단계에서 도메인 규칙과 IP 규칙을 어떻게 처리할지 정합니다. DNS 서버 주소도 아니고 아웃바운드 연결 시의 주소 선택 정책과도 다릅니다. 아래 세 값은 V2Ray/Xray의 일반적인 라우팅 설정에 해당합니다. 실제 동작은 실행 중인 코어 버전에 따라 다를 수 있으므로 해당 버전을 기준으로 확인하세요.
AsIs
권장도메인 형태로 들어온 대상은 라우팅 매칭을 위해 IP를 별도로 조회하지 않습니다. IP 형태로 들어온 대상은 계속 IP 규칙과 매칭할 수 있습니다. 도메인 예외와 규칙 순서를 먼저 조정할 때 변수를 줄이는 데 적합합니다.
적합한 경우: 도메인 규칙 우선, 사용자 지정 라우팅을 처음 검증할 때
IPIfNonMatch
도메인이 기존 규칙과 일치하지 않을 때 IP를 조회해 이후 규칙 매칭에 사용합니다. 앞쪽의 포괄적인 규칙이 요청을 처리하면 뒤에 geoip 항목이 있다는 이유만으로 IP 조회가 반드시 실행되는 것은 아닙니다.
적합한 경우: 주요 트래픽은 도메인 규칙으로 처리하고 IP 분류는 보완용으로 사용할 때
IPOnDemand
매칭 중 대상 IP가 필요한 규칙을 만나면 도메인 조회를 시도합니다. IP 규칙을 앞쪽에 두면 DNS 조회가 더 일찍 시작될 수 있으며, 뒤에 있는 도메인 예외보다 먼저 출구가 결정될 수도 있습니다.
적합한 경우: 주소 조건을 우선 판단에 반영해야 할 때
결론: 조회 전략보다 규칙 순서를 먼저 조정하세요
먼저 AsIs로 정확한 도메인 예외가 적용되는지 확인하세요. 도메인 요청에 geoip 판단을 추가해야 하는 경우에만 IPIfNonMatch를 시험하고, 두 테스트의 로그에서 대상 주소와 아웃바운드 태그를 함께 기록하세요.
앱이 먼저 도메인을 조회한 다음 순수 IP 주소를 프록시에 전달하면 코어가 원래 도메인을 알지 못할 수 있습니다. 일부 프로토콜에서는 트래픽 스니핑으로 도메인 정보를 보완할 수 있지만 모든 연결에서 작동하지는 않습니다. 사용하도록 설정한 뒤에도 “라우팅에만 사용”하는지 “대상을 바꾸는지” 설정 효과를 구분해야 합니다. 스니핑을 켜면 도메인 규칙이 반드시 적용된다고 생각하지 마세요.
전체 라우팅 예시: 정확한 예외 규칙을 분류 규칙보다 앞에 배치
다음은 전체 설정에 포함할 수 있는 routing 부분만 보여 주며, 단독으로 실행되는 설정 파일은 아닙니다. 예시에서는 direct와 proxy라는 아웃바운드 태그가 이미 있다고 가정합니다. 순서는 로컬 네트워크 주소, 정확한 도메인 예외, 도메인 분류, IP 분류, 마지막으로 TCP/UDP 기본 규칙입니다.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["full:portal.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
놓치기 쉬운 점은 마지막 network 규칙이 일반적인 TCP/UDP 요청을 처리한다는 것입니다. IPIfNonMatch에서는 도메인 요청이 이 규칙에 이미 매칭되면 앞의 IP 분류가 일치하지 않았더라도 “아무 규칙도 매칭되지 않아 IP를 조회하는” 단계로 넘어가지 않습니다. 따라서 이 예시의 geoip:cn은 주로 대상 IP가 이미 지정된 요청을 처리합니다. 남은 모든 도메인에 주소 분류를 적용하는 규칙으로 해석하면 안 됩니다.
- 이 명시적 기본 규칙을 유지하려는 경우: 도메인 요청은 주로 도메인 규칙으로, IP 요청은 주로 IP 규칙으로 라우팅합니다.
- 도메인이 매칭되지 않을 때 IP 분류를 적용하려는 경우: 모든 연결을 먼저 처리하는 규칙을 제거하고 기본 아웃바운드를 확인하세요. 일반적인 기본 동작에서는 첫 번째 아웃바운드를 사용합니다.
- IP 조건을 만날 때마다 조회하려는 경우:
IPOnDemand를 검토할 수 있지만, 앞쪽 IP 규칙과 정확한 도메인 예외의 우선순위를 다시 테스트해야 합니다.
기본 아웃바운드는 전체 설정에서 직접 확인해야 합니다. 클라이언트 화면에서 “현재 선택된 노드”만 보고 추측하면 안 됩니다. v2rayN은 실행 설정을 생성하므로 임시 생성 파일을 직접 수정해도 노드를 바꾸거나 다시 시작하면 변경 내용이 덮어써질 수 있습니다. 장기간 사용할 규칙은 클라이언트의 라우팅 설정에 저장하세요.
v2rayN 사용자 지정 라우팅: 규칙을 하나씩 검증
v2rayN은 데스크톱 클라이언트이며 실제 트래픽은 선택한 코어가 처리합니다. 다음 절차는 「설정」→「라우팅 설정」 메뉴가 있는 데스크톱 화면을 기준으로 합니다. 버전에 따라 버튼 위치와 필드 번역이 달라질 수 있습니다. 편집하기 전에 현재 라우팅 설정 이름을 기록하고 기존 규칙을 보관해 구독 노드 문제와 라우팅 문제를 혼동하지 않도록 하세요.
-
라우팅 설정 열기
「설정」→「라우팅 설정」으로 이동해 현재 사용 중인 라우팅 설정을 기록합니다. 먼저 기존 규칙을 내보내거나 복사한 다음 예외 규칙을 추가하세요.
-
도메인 조건 입력
규칙 편집 창의 도메인 조건에
full:portal.example.com을 입력합니다. 그래픽 인터페이스의 필드는 보통 항목만 입력받으므로 전체 routing JSON을 붙여 넣지 마세요. -
대상 아웃바운드 선택
필요에 따라 프록시 또는 직접 연결을 선택합니다. 코어 JSON을 편집한다면
outboundTag와outbounds의 태그가 한 글자까지 동일한지 확인하세요. -
위로 이동한 뒤 활성화
예외 규칙을 도메인 분류와 포괄적인 기본 규칙보다 앞에 배치합니다. 저장한 뒤 메인 화면의 라우팅 선택 메뉴에서 이 설정을 활성화하세요. 저장만 하고 기존 설정을 계속 사용하지 않도록 주의하세요.
-
새 연결로 테스트
테스트 중인 페이지와 기존 연결을 닫은 다음 새 요청을 보냅니다. 코어 로그에서 대상 호스트, 대상 포트, 아웃바운드 태그를 확인하고 매번 조건 하나만 변경하세요.
검증할 때는 실제 테스트 호스트를 먼저 full: 예외로 지정해 매칭을 확인한 다음 domain:이나 분류 규칙으로 범위를 넓힐 수 있습니다. 브라우저가 연결을 재사용하면 기존 연결이 이전 출구를 계속 사용할 수 있으므로 페이지를 새로고침해도 새 연결이 만들어지지 않을 수 있습니다. 명령줄 도구로 테스트할 때는 클라이언트 화면에 표시된 로컬 프록시 포트를 명시하세요. 모든 기기에서 같은 포트를 사용한다고 가정하면 안 됩니다.
라우팅 규칙이 적용되지 않을 때: 증상별 원인 확인
도메인을 올바르게 입력했는데 왜 직접 연결되나요?
정확한 규칙을 분류 규칙보다 앞에 배치한 다음 수정한 라우팅 설정이 현재 활성화되어 있는지 확인하세요. 로그에 대상 IP만 표시된다면 앱이 미리 도메인을 조회했는지, 코어가 도메인 정보를 가져올 수 있는지도 점검하세요.
geosite를 저장한 뒤 코어가 시작되지 않는 이유는 무엇인가요?
로그에 도메인 데이터 파일이 없거나 분류를 불러올 수 없다는 메시지가 있는지 확인하세요. geosite.dat의 리소스 경로와 분류 이름을 점검한 뒤, 먼저 full 도메인 규칙 하나로 기본 설정을 검증하고 분류 항목을 다시 추가하세요.
웹사이트는 프록시를 사용하는데 이미지는 왜 직접 연결되나요?
브라우저 개발자 도구의 네트워크 패널에서 이미지 요청의 실제 호스트 이름을 확인하세요. 이미지가 다른 루트 도메인에서 제공될 수 있어 사이트의 domain 항목이 적용되지 않을 수 있습니다. 용도를 확인한 뒤 리소스 도메인에 별도 규칙을 추가하세요.
443 포트 규칙에 매칭됐는데 다운로드가 실패하는 이유는 무엇인가요?
포트 조건은 트래픽을 어디로 보낼지 결정할 뿐 대상에 연결할 수 있다고 보장하지 않습니다. 로그에서 아웃바운드 태그가 올바른지 확인한 뒤 노드 연결 상태, DNS 결과, UDP 지원을 각각 점검하세요. 443 포트에는 TCP뿐 아니라 UDP 트래픽도 전달될 수 있습니다.
클라이언트를 다시 시작한 뒤 사용자 지정 규칙이 사라진 이유는 무엇인가요?
변경 사항이 임시로 생성된 코어 설정에만 저장됐는지 확인하세요. 「설정」→「라우팅 설정」으로 돌아가 규칙을 저장하고 해당 설정을 활성화하세요. 별도의 사용자 지정 설정을 쓴다면 실제로 불러오는 원본 파일을 수정해야 합니다.
마지막으로 세 가지를 확인하세요. 연결이 코어에 들어왔는지, 코어가 도메인과 IP 중 무엇을 확인했는지, 첫 번째로 일치한 규칙이 어떤 아웃바운드를 지정했는지입니다. 이 세 가지를 먼저 확인하면 DNS 변경, 코어 교체, 구독 재설정을 한꺼번에 시도하는 것보다 원인을 쉽게 찾을 수 있습니다. 필드에 대한 자세한 설명은 프로토콜 및 코어 참고 자료를, 익숙하지 않은 용어는 용어집을 확인하세요.