JSON / INBOUNDS / OUTBOUNDS / ROUTING / DNS / POLICY
V2Ray 설정 파일 가이드
필드 의미부터 규칙 실행 순서까지 장별로 설정을 확인하세요.
구독을 처음 가져오고 서버를 선택해 시스템 프록시를 켜려면 빠른 시작 가이드를 따라가세요. 이 페이지에서는 클릭 절차를 반복하는 대신 클라이언트가 생성하는 JSON의 각 부분이 맡은 역할과 함께 변경할 수 있는 필드, 문제 발생 시 확인할 지점을 설명합니다. 연결에 성공한 뒤 라우팅과 DNS를 조정하면 원인을 더 쉽게 파악할 수 있습니다.
JSON 구조 한눈에 보기: 먼저 데이터 흐름 파악하기
V2Ray 설정은 서로 무관한 스위치의 모음이 아닙니다. 애플리케이션이 인바운드에 연결되면 코어가 대상 정보를 바탕으로 라우팅을 선택해 아웃바운드로 전달합니다. DNS는 이름 조회가 필요한 단계에 결과를 제공하고, 정책과 로그는 연결 관리와 문제 확인을 담당합니다. 필드를 하나씩 외우기보다 먼저 이 데이터 흐름을 따라가 보세요. 같은 접속 실패라도 애플리케이션의 요청이 인바운드에 도달하지 않은 경우와 아웃바운드가 핸드셰이크를 완료하지 못한 경우는 해결 방법이 다릅니다.
최상위 객체와 필드의 역할
최상위에는 JSON 객체 하나가 와야 합니다. inbounds와 outbounds는 배열이며 각각 여러 인바운드와 아웃바운드를 정의할 수 있습니다. routing, dns, policy, log는 보통 객체입니다. 인바운드의 listen을 아웃바운드에 넣거나 라우팅 규칙을 최상위에 바로 넣지 마세요. 편집기가 괄호를 인식한다고 해서 구문을 파싱할 수 있다는 뜻일 뿐, 필드 위치까지 올바르다는 의미는 아닙니다.
{
"log": {
"loglevel": "warning"
},
"inbounds": [],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
위 구조 예시는 필드 간 관계를 보여줄 뿐 로컬 리스닝 인바운드가 없으므로 브라우저가 바로 연결할 수 없습니다. 빈 배열도 유효한 JSON이지만 실제 동작은 코어의 기본 동작을 함께 고려해야 합니다. 다른 사람이 제공한 설정 조각을 읽을 때는 먼저 어떤 필드를 대체하는지 확인한 다음 배열 전체를 교체할지 객체 하나만 추가할지 결정하세요. 완성된 객체 두 개를 그대로 이어 붙이면 파싱할 수 없는 문서가 됩니다.
| 필드 | 담당 기능 | 확인할 사항 |
|---|---|---|
inbounds | 로컬 애플리케이션의 연결 수신 | 주소, 포트, 프로토콜 |
outbounds | 후속 연결 설정 | 태그, 프로토콜, 원격 설정 |
routing | 연결을 아웃바운드에 할당 | 규칙 순서와 태그 참조 |
dns | 코어에서 도메인 조회 | DNS 서버와 조회 정책 |
policy | 연결 관리 및 통계 설정 | 레벨 설정과 통계 의존성 |
구문이 맞아도 설정이 유효한 것은 아닙니다
여러 도구에서 설정을 복사해 쓸 수 있도록 이 페이지에서는 엄격한 JSON을 사용합니다. 키와 문자열은 영문 큰따옴표로 감싸고, 배열의 마지막 항목 뒤에는 쉼표를 붙이지 않으며, 설명은 코드 블록에 넣지 않습니다. 일부 파서에서 주석을 허용하더라도 구독 처리기나 다른 코어에서 허용된다는 뜻은 아닙니다. 불리언 값은 따옴표 없는 true 또는 false로 작성하세요. 숫자와 문자열도 겉모양만 보고 바꿔 쓰지 말고 해당 코어에서 요구하는 형식을 확인하세요.
같은 객체 안에서 키를 중복해 쓰지 마세요. 예를 들어 routing을 두 번 쓰면 처리기에 따라 앞 항목을 덮어쓰거나 설정 읽기를 거부할 수 있습니다. 규칙 두 묶음이 모두 있는 것처럼 보여도 실제로는 하나만 적용될 수 있습니다. 설정을 합칠 때는 규칙을 하나의 rules 배열에 넣으세요. 배열 순서에도 의미가 있습니다. 아웃바운드 첫 항목이 기본 출구에 영향을 줄 수 있고, 라우팅 앞쪽 규칙이 연결을 먼저 가로챌 수도 있으므로 자동 정렬 도구로 순서를 함부로 바꾸지 마세요.
태그는 설정 구간을 연결하는 참조 지점입니다. 아웃바운드에 direct를 정의해야 라우팅에서 outboundTag로 해당 출구를 지정할 수 있습니다. 대소문자와 철자를 일치시키세요. 각 인바운드와 아웃바운드에는 바꾸지 않고 사용할 고유한 태그를 지정하는 편이 좋습니다. 로그와 라우팅에서 태그를 기준으로 구분하기 때문입니다. 태그는 이름일 뿐 proxy라고 붙인다고 프록시 기능이 생기지 않습니다. 실제 동작은 객체의 프로토콜과 설정에 따라 달라집니다.
설정 출처를 확인한 뒤 편집하세요
그래픽 클라이언트에서는 구독 기록, 화면 설정, 실행 설정이 보통 서로 다른 파일로 관리됩니다. 먼저 클라이언트에서 복원할 수 있는 백업을 보관하고 이번 실행에서 실제로 생성된 내용을 확인하세요. 코어가 실행 중일 때 임시 파일을 바꿨다고 해서 다음 실행에도 변경 사항이 유지되지는 않습니다. 화면 설정으로 바꿀 수 있는 항목은 해당 설정 화면에서 저장하세요. 사용자 지정 설정이 필요하다면 클라이언트가 안내하는 방식으로 불러오세요.
수정할 때마다 “이 도메인은 직접 연결 출구를 사용한다”처럼 기대하는 결과를 구체적으로 적으세요. “네트워크 최적화”처럼 막연하게 정하지 마세요. 목표와 관련된 설정 한 곳만 변경하고 다시 불러온 뒤 같은 방식으로 확인하세요. 그러면 구문 오류, 필드 호환성 문제, 규칙 미매칭을 구분해 찾을 수 있습니다. 첫 연결부터 되지 않았다면 복잡한 규칙을 추가하기보다 기본 튜토리얼로 돌아가 먼저 기초 연결을 확인하세요.
클라이언트와 코어: 먼저 설정 형식 확인하기
V2Ray는 흔히 생태계 전체를 가리키는 이름으로 쓰이지만, 클라이언트 화면과 실제 연결을 처리하는 코어는 서로 다릅니다. v2rayN은 데스크톱에서 구독과 설정을 관리하고 실행을 제어하며, 코어는 설정을 파싱하고 연결을 수립해 라우팅을 실행합니다. 메뉴 이름이 비슷해도 지원 기능까지 같은 것은 아닙니다. 필드를 확인하기 전에 현재 실행 중인 코어를 파악하고, 클라이언트의 화면 설정이 다른 형식으로 변환되는지도 확인하세요.
V2Fly와 Xray의 공통 구조와 차이점
Project V 생태계에서 V2Fly와 Xray는 공통된 역사적 배경을 바탕으로 비슷한 JSON 구조를 다수 유지하고 있습니다. 다만 프로토콜 구현, 전송 설정, 추가 기능과 필드 변경 시점이 완전히 일치하지는 않습니다. 이 페이지의 예시는 일반적인 기존 JSON 구조를 바탕으로 기본 개념을 설명하며, 모든 확장 필드를 서로 다른 코어에서 그대로 쓸 수 있다고 보장하지 않습니다. 특히 VLESS, XTLS, REALITY 설정은 사용 중인 코어와 해당 프로토콜 조합의 지원 여부를 항목별로 확인해야 합니다.
Android에서 v2rayNG는 주로 Xray 코어를 사용하는 클라이언트이고, v2flyNG는 V2Fly 코어를 사용하는 대안입니다. 데스크톱에서는 먼저 v2rayN을 살펴보되, 실제 코어는 설정 요구사항에 맞춰 선택하세요. 클라이언트에서 링크를 가져올 수 있다고 해서 링크의 모든 매개변수가 정상 작동하는 것은 아닙니다. 링크 가져오기와 파싱, 설정 생성, 코어 실행은 각각 확인해야 하는 별도의 단계입니다.
| 클라이언트 | 주요 용도 | 설정 확인 항목 |
|---|---|---|
| v2rayN | 데스크톱 구독 및 실행 관리 | 현재 코어, 생성된 설정, 시스템 프록시 |
| v2rayNG | Android 연결 관리 | Xray 매개변수, 시스템 연결 권한, 앱 범위 |
| v2flyNG | Android용 V2Fly 클라이언트 | V2Fly 필드, 프로토콜 호환성 |
그래픽 설정 화면은 원본 JSON과 일치하지 않습니다
클라이언트는 드롭다운 옵션 하나로 여러 필드를 설정하거나 프로그램이 관리하는 태그와 포트를 숨길 수 있습니다. 예를 들어 화면의 라우팅 모드는 최상위의 특정 키 하나가 아니라 여러 규칙을 묶어 나타낼 수 있습니다. 생성된 파일을 수정한 뒤 모드를 바꾸면 기존 변경 사항이 덮어써질 수 있습니다. 설정을 볼 때는 현재 서버에서 가져온 값, 전역 설정에서 가져온 값, 클라이언트가 시작 시 자동으로 채우는 값을 구분하세요.
사용자 지정 설정이 클라이언트에서 관리하는 모든 기능을 지원하는 것도 아닙니다. 가져오는 방식에 따라 전체 설정으로 실행하기도 하고 연결 항목 하나로만 사용하기도 합니다. 시스템 프록시가 가리키는 로컬 포트, 클라이언트의 상태 확인용 인바운드, 통계에 필요한 태그에는 별도 규칙이 있을 수 있습니다. 화면에는 실행 중이라고 표시되지만 앱이 연결되지 않는다면 원격 서버가 문제라고 단정하지 말고 실제 리스닝 포트부터 확인하세요.
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
이 아웃바운드는 직접 연결을 정의하므로 공통 필드를 설명하기에는 적합하지만, 원격 연결 전체 설정을 나타내지는 않습니다. 설정 호환성을 확인하는 방법도 보여줍니다. 먼저 프로토콜 이름을 확인하고 해당 프로토콜의 settings를 살펴본 다음 전송 관련 매개변수를 점검하세요. 프로토콜 이름만 바꾸고 기존 프로토콜 설정을 그대로 두면 대개 올바르게 작동하지 않습니다. 각 프로토콜의 서버, 인증, 전송 필드는 한 묶음으로 확인해야 합니다.
코어를 바꾸기 전 지원 기능을 확인하세요
코어를 바꾸기 전에 현재 실제로 사용하는 프로토콜, 전송 방식, 라우팅 데이터베이스, DNS 정책, 인바운드 기능을 정리하세요. 새 코어가 해당 기능을 지원하는지 확인한 뒤 설정 하나만 골라 범위를 좁혀 검증하세요. 전체 설정을 한꺼번에 바꾸고 화면에 실행 표시가 뜨는지만 보고 이전이 성공했다고 판단하지 마세요. 코어가 실행되더라도 드문 라우팅 규칙, 특정 UDP 사용 방식, 추가 전송 동작이 이전과 다를 수 있습니다.
라우팅 데이터베이스도 호환성에 영향을 줍니다. 설정에 geosite:cn이 적혀 있어도 현재 코어가 해당 리소스를 찾을 수 있어야 하고 파일에 그 분류가 포함되어 있어야 합니다. 클라이언트가 규칙 리소스를 갱신하는 디렉터리와 다른 코어가 검색하는 디렉터리는 다를 수 있습니다. 수동으로 이전할 때 JSON만 가져오지 말고 리소스 경로도 확인하세요. 형식이 다른 데이터 파일의 이름을 임의로 바꿔 함께 사용하지 마세요.
문제를 진단할 때는 ‘클라이언트 이름, 실제 코어, 설정 출처, 오류 필드’ 네 가지를 먼저 기록하세요. 홈페이지 화면을 캡처하는 것보다 보통 더 유용합니다. 설치 파일이 필요하다면 클라이언트 페이지를 확인하고, 두 코어 계열의 차이를 비교하려면 Xray와 V2Fly 코어 비교를 읽어보세요. 클라이언트 변경을 만능 해결책으로 여기지 말고 구체적인 호환성 문제가 해결되는지 먼저 확인하세요.
inbounds 인바운드: 앱 연결 진입점 정의
인바운드는 앱이 연결을 코어에 전달하는 방식을 결정합니다. 흔히 사용하는 로컬 진입점은 SOCKS와 HTTP 프록시이며, 앱은 올바른 프로토콜과 포트로 연결해야 합니다. 인바운드 포트는 원격 서버 포트가 아니며, 로컬에서 리스닝 중이라고 원격 연결까지 성공한 것은 아닙니다. 문제 해결의 첫 단계는 앱 요청이 실제로 인바운드에 도달하는지 확인하는 것입니다. 요청이 코어에 들어오지 않았다면 아웃바운드 인증 설정을 바꿔도 결과는 달라지지 않습니다.
로컬 주소, 포트, 프로토콜을 함께 확인하세요
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
이 설정은 로컬 루프백 주소에서만 리스닝하는 인바운드 두 개를 만듭니다. SOCKS 앱은 10808, HTTP 프록시 앱은 10809 포트를 사용합니다. 두 포트를 서로 바꿔 쓸 수 있는 별칭처럼 취급하면 안 됩니다. 포트 번호는 예시일 뿐이며 클라이언트에서 반드시 같은 값을 사용하는 것은 아닙니다. 화면에 다른 값이 표시된다면 실제 실행 설정을 따르고 앱의 프록시 주소도 함께 수정하세요.
listen이 127.0.0.1이면 다른 기기에서 LAN 주소를 통해 인바운드에 접속할 수 없습니다. 모든 인터페이스에서 리스닝하도록 바꾸면 접속 범위가 이 기기 안으로 제한되지 않으므로 인증, 시스템 방화벽, 신뢰할 수 있는 네트워크 범위를 함께 고려해야 합니다. 위 SOCKS 예시는 인증을 요구하지 않으므로 로컬 접속으로 범위를 명확히 제한한 경우에만 적합합니다. 그대로 외부에 공개된 공유 프록시로 바꾸지 마세요.
UDP 설정만으로 전체 연결이 보장되지는 않습니다
SOCKS 설정의 udp는 인바운드에서 해당 UDP 요청을 처리하도록 허용하지만, 실제 통신이 가능한지는 앱이 SOCKS의 UDP 기능을 사용하는지, 아웃바운드 프로토콜이 지원하는지, 원격 네트워크가 허용하는지에 따라 달라집니다. HTTP 프록시 인바운드는 주로 HTTP 요청과 터널 연결에 쓰이며 범용 UDP 인바운드와 같지 않습니다. 브라우저는 정상인데 실시간 앱이 작동하지 않는다면 먼저 각각 어떤 전송 방식을 사용하는지 구분하세요.
마찬가지로 시스템 프록시는 시스템 설정을 따르는 앱에 프록시 진입점을 알려줄 뿐 모든 트래픽을 자동으로 가로채지 않습니다. 일부 프로그램은 자체 프록시 설정을 따르고, 일부는 네트워크에 직접 연결합니다. TUN은 가상 네트워크 인터페이스, 권한, 라우팅, DNS 설정이 필요한 별도의 트래픽 처리 방식이므로 SOCKS 인바운드 하나로 대체할 수 없습니다. 실제 적용 범위를 확인하려면 트레이 아이콘 상태만 보지 말고 구체적인 앱의 트래픽 진입점부터 살펴보세요.
스니핑은 도메인 단서일 뿐 모든 연결을 식별하지 않습니다
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
]
}
스니핑은 이미 받은 트래픽에서 프로토콜이나 도메인 정보를 추출해 대상 IP만 포함된 연결을 코어가 처리하도록 돕습니다. 복호화 도구는 아니며 모든 연결에서 도메인을 알아낼 수 있는 것도 아닙니다. 일부 핸드셰이크 방식, 암호화된 메타데이터, HTTP나 TLS가 아닌 트래픽은 식별을 어렵게 합니다. 활성화한 뒤에는 현재 코어에서 대상 덮어쓰기 방식이 어떻게 동작하는지도 확인하세요. 라우팅에 쓸 도메인 단서와 실제 연결 대상은 같은 의미가 아닙니다.
인바운드에 고정 태그를 붙이면 진입점별 라우팅에 유용합니다. 예를 들어 별도의 테스트 인바운드는 라우팅의 inboundTag와 함께 사용해 해당 진입점에서 들어온 연결에만 적용할 수 있습니다. 다만 규칙은 순서대로 실행되므로 앞에 더 광범위한 규칙이 있으면 인바운드 전용 규칙이 선택되지 않을 수 있습니다. 인바운드를 추가할 때 태그를 정해두고, 나중에 이름을 바꾸더라도 이를 참조하는 라우팅 규칙을 빠뜨리지 마세요.
인바운드를 확인할 때는 수동 프록시를 지원하는 앱에서 로컬 주소와 해당 포트를 지정한 뒤 로그에 요청이 기록되는지 살펴보세요. 기록이 없다면 앱 설정, 리스닝 주소, 방화벽을 확인합니다. 기록은 있지만 그 뒤에 오류가 발생한다면 아웃바운드와 DNS를 확인하세요. LAN 기기에서만 접속할 수 없다면 바인딩 주소와 허용 범위를 별도로 확인하세요. 문제를 세 가지로 나누면 불필요한 설정 변경을 줄일 수 있습니다.
outbounds 아웃바운드: 연결 방식과 태그 구분
아웃바운드는 연결을 넘겨받은 뒤 대상에 실제로 접속하는 방식을 담당합니다. 직접 연결하거나 원격 프로토콜로 연결하거나 요청을 명시적으로 차단할 수 있습니다. 인바운드는 ‘앱이 어떻게 들어오는지’, 아웃바운드는 ‘코어가 어떻게 나가는지’를 결정하며 두 구간에서 같은 프로토콜을 쓸 필요는 없습니다. 앱이 SOCKS 인바운드로 들어와도 여러 유형의 아웃바운드로 라우팅될 수 있습니다. 로컬 SOCKS 포트를 보고 원격에서도 SOCKS를 쓴다고 판단하지 마세요.
직접 연결과 차단을 위한 기본 출구 만들기
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
freedom은 코어가 대상으로 직접 연결하는 방식이고 blackhole은 할당된 트래픽을 버리는 방식입니다. direct와 block은 이 예시에서 사용하는 태그일 뿐이므로 이름을 바꿀 수 있지만 라우팅의 참조도 함께 수정해야 합니다. 차단 출구는 명확한 거부 정책에 사용하며 연결이 실패할 때 자동으로 대신 사용하는 출구가 아닙니다. 자주 쓰는 요청이 규칙 오류로 이쪽에 전달되면 앱에는 시간 초과나 연결 중단으로 보일 수 있습니다.
기존 설정에서는 규칙에 선택되지 않은 트래픽이 아웃바운드 배열의 첫 번째 출구로 전달되는 경우가 많습니다. 위 예시의 첫 항목은 직접 연결이므로 기본 동작도 직접 연결입니다. 원격 아웃바운드를 배열 끝에 추가해도 모든 요청이 자동으로 원격으로 바뀌지는 않습니다. 기본 출구를 변경하기 전에 클라이언트가 별도의 기본 규칙을 생성하는지, 로드 밸런싱 같은 추가 기능을 사용하는지 확인하세요. 배열 순서만으로 모든 상황을 판단할 수는 없습니다.
원격 설정은 필요한 필드를 한 묶음으로 유지하세요
VMess, VLESS, Trojan 등의 프로토콜은 인증 및 전송 필드가 서로 다릅니다. 원격 주소, 포트, 사용자 정보, 전송 유형, TLS 관련 매개변수는 서버의 실제 설정과 일치해야 합니다. 한 링크의 인증 정보를 다른 프로토콜 객체로 옮기거나, 파싱되게 하려고 모르는 필드를 삭제하지 마세요. 파싱에 성공했다는 것은 형식이 받아들여졌다는 뜻일 뿐 양쪽의 핸드셰이크 설정이 일치한다는 보장은 아닙니다.
원격에서 TLS를 사용하는 경우 연결 주소, 핸드셰이크에 사용하는 서버 이름, 애플리케이션 계층 요청의 호스트 필드가 각각 다른 역할을 할 수 있습니다. 값이 같은 경우도 있지만 모두 도메인처럼 보인다는 이유로 같은 항목으로 취급해서는 안 됩니다. 전송 경로도 서버에서 정해줄 수 있습니다. 받은 전체 설정을 기준으로 항목별로 비교하세요. 이름이나 경로를 임의로 바꾸면 명확했던 오류가 여러 가지 불일치로 번질 수 있습니다.
| 확인 단계 | 주요 내용 | 흔한 실수 |
|---|---|---|
| 객체 식별 | tag、protocol | 태그를 프로토콜 기능으로 오해 |
| 프로토콜 설정 | settings의 연결 매개변수 | 서로 다른 프로토콜의 인증 구조 혼용 |
| 전송 설정 | streamSettings 등 해당 필드 | 전송 이름만 바꾸고 관련 설정은 그대로 둠 |
| 라우팅 참조 | outboundTag | 출구는 있지만 선택되지 않음 |
오류가 발생한 단계 찾기
연결이 아웃바운드에 할당된 뒤에도 도메인 조회, 기본 연결 수립, TLS 핸드셰이크, 프로토콜 인증, 데이터 전송 순으로 여러 단계가 이어질 수 있습니다. 특정 단계에서 실패했다고 바로 ‘서버를 사용할 수 없다’고 단정하지 마세요. 예를 들어 로컬 DNS 조회가 실패하면 대상 주소를 얻기도 전에 막힙니다. 기본 포트에 연결할 수 있다고 프로토콜 인증까지 성공한 것도 아닙니다. 로그에서는 마지막 요약 줄만 복사하지 말고 가장 먼저 나타난 구체적인 오류를 찾으세요.
직접 연결과 원격 아웃바운드는 서로 다른 명확한 대상으로 시험하세요. 먼저 같은 로컬 인바운드로 직접 접속할 수 있다고 알려진 페이지를 열어 앱과 코어 사이의 연결을 확인합니다. 그런 다음 기존 원격 아웃바운드를 선택해 라우팅과 핸드셰이크 결과를 살펴보세요. 두 시험이 모두 실패하면 공통으로 사용하는 인바운드나 클라이언트 실행 문제부터 확인하세요. 원격 경로만 실패한다면 원격 설정, 네트워크 상태, 프로토콜 호환성을 점검하세요.
인증서 검증을 건너뛰는 설정을 기본 문제 해결 방법으로 사용하지 마세요. 인증서 이름, 시스템 시각, 신뢰 체인, 서버 설정이 TLS에 영향을 줄 수 있습니다. 검증을 끄면 실제 불일치를 감출 수 있습니다. 먼저 연결 정보의 출처와 기기 시간을 확인하고 로그에 나온 구체적인 원인을 해결하세요. 인증 정보가 포함된 전체 JSON을 공개 게시판에 올리지도 마세요. 보통은 프로토콜 유형, 필드 이름, 민감 정보를 제거한 오류 내용만으로도 문제를 설명할 수 있습니다.
클라이언트에서 구독을 갱신하면 원격 아웃바운드가 다시 작성될 수 있으므로, 오래 유지할 로컬 라우팅은 클라이언트에서 지원하는 관리 방식으로 설정하는 편이 좋습니다. 클라이언트를 새로 설치하려면 다운로드 페이지를 확인하고, 가져온 뒤 검증하는 순서는 v2rayN 첫 연결 점검에서 확인하세요. 처음에는 아웃바운드를 최소한으로 유지하고 연결 하나가 검증된 뒤 복잡한 구성을 추가하세요.
routing 라우팅: 연결을 순서대로 판단
라우팅 우선순위는 규칙 수가 아니라 설정 순서로 결정됩니다. 일반적으로 위에서 아래로 확인하다가 일치하는 규칙을 찾으면 그 출구를 선택하고 나머지 규칙은 해당 연결에 적용하지 않습니다. 따라서 구체적인 예외를 포괄적인 분류보다 앞에 배치하세요. 특정 도메인을 직접 연결하도록 적었는데도 원격으로 나간다면 클라이언트를 반복해서 재시작하기보다 앞쪽에 더 넓은 규칙이 있는지 먼저 확인하세요.
규칙 순서와 태그 참조
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "block"
}
]
}
}
이 예시는 direct와 block 아웃바운드가 이미 있고 GeoIP, GeoSite 데이터를 불러올 수 있다고 가정합니다. 마지막 규칙은 나머지 TCP와 UDP 연결을 차단 출구로 보내는 제한 정책입니다. 모든 사용자에게 권장하는 기본 설정은 아닙니다. 그 외 연결을 기존 원격 출구로 보내려면 실제로 존재하는 아웃바운드의 태그를 지정하세요. ‘프록시’라는 이름의 태그를 임의로 만들어 쓰지 마세요.
한 규칙 안의 서로 다른 조건 필드는 보통 모두 만족해야 합니다. 같은 목록에 여러 후보가 있으면 대개 그중 하나와 일치하면 됩니다. 예를 들어 규칙에 inboundTag와 domain을 함께 지정하면 해당 도메인에 일치하면서 지정된 인바운드로 들어온 연결을 뜻합니다. 둘 중 하나만 맞으면 되는 조건이 아닙니다. 무관한 조건 여러 개를 규칙 하나에 넣으면 규칙이 전혀 선택되지 않을 수 있습니다. 서로 독립적인 경로 두 개를 나타내려면 규칙 객체를 따로 만드세요.
도메인 매칭은 목적에 맞는 유형을 선택하세요
domain:example.com은 해당 도메인과 하위 도메인을 매칭하고, full:example.com은 도메인 전체를 정확히 매칭합니다. 일반 문자열과 정규 표현식은 의미가 다르므로 한 번 매칭됐다고 경계도 올바르다고 생각하면 안 됩니다. 일반적인 도메인 라우팅에는 의미가 분명한 도메인 매칭 형식을 사용해 짧은 키워드가 다른 도메인에 잘못 매칭되는 일을 피하세요. 정규 표현식이 필요하다면 경계와 이스케이프 처리를 별도로 확인하세요.
JSON 문자열 자체에도 이스케이프 처리가 있고 정규 표현식에도 별도의 이스케이프 처리가 있으므로 다른 도구에서 규칙을 복사할 때 주의하세요. 먼저 JSON 안에서 실제 문자열이 어떻게 표현되는지 확인한 다음 코어가 이를 어떻게 해석하는지 확인하세요. 도메인과 하위 도메인을 매칭하는 것뿐이라면 간결하게 보이려고 복잡한 표현식을 쓸 필요가 없습니다. 규칙을 읽기 쉽게 작성하면 나중에 잘못 매칭된 원인을 추측에 의존하지 않고 찾을 수 있습니다.
domainStrategy는 IP 주소를 활용하는 시점을 결정합니다
AsIs는 라우팅을 위해 도메인을 IP로 적극 변환하지 않습니다. 다만 이미 IP가 알려진 연결은 IP 규칙과 매칭될 수 있습니다. IPIfNonMatch는 도메인 단계에서 일치하는 규칙을 찾지 못한 뒤 IP를 조회해 IP 조건으로 다시 판단합니다. IPOnDemand는 매칭 과정에서 IP 정보가 필요할 때 조회합니다. 이 설정은 라우팅 단계의 조회 시점을 바꾸는 것으로 기기 전체 DNS를 전환하거나 원격 출구를 지정하는 설정과는 다릅니다.
기본 규칙의 영향에 특히 주의하세요. 도메인 단계에서 포괄적인 규칙이 먼저 연결을 처리하면 IPIfNonMatch가 IP 조회 후 매칭 단계까지 도달하지 못할 수 있습니다. 이 경우 사설 IP 규칙이 특정 도메인을 처리할 거라 생각했지만 실제로는 마지막 네트워크 기본 규칙이 먼저 선택될 수 있습니다. 규칙을 구성할 때 도메인 분류로 처리할 대상과 조회 후 주소를 확인할 대상을 명확히 정하세요. 필드 이름만 보고 실행 순서를 추측하지 마세요.
규칙을 관리할 때는 ‘로컬 주소, 명시적 예외, 서비스 분류, 최종 기본 규칙’ 순서로 읽기 쉽게 구성하고 한 번에 한 종류만 추가하거나 수정하세요. 규칙 리소스를 업데이트한 뒤에는 분류 내용이 달라질 수 있으므로 대표 대상 몇 개를 다시 확인하세요. 리소스가 없거나 분류를 찾을 수 없다면 모든 라우팅 규칙을 삭제해 덮으려 하지 말고 시작 로그부터 확인하세요. 리소스 관리 방법은 GeoIP와 GeoSite 데이터베이스 업데이트 안내에서 확인할 수 있습니다.
마지막으로 로그에서 대상 도메인, 인바운드 태그, 선택된 아웃바운드를 확인하세요. 브라우저에서 페이지가 열렸다는 사실만으로 예상한 출구가 선택됐다고 단정할 수는 없습니다. 직접 연결과 원격 연결이 모두 성공할 수 있기 때문입니다. 라우팅 결과가 예상과 다르면 실제로 불러온 설정의 규칙 순서를 먼저 확인하고, 앱이 도메인을 전달했는지, 데이터베이스가 정상인지 차례로 점검하세요. 이 순서로 확인하면 도메인 정보 누락을 분류 오류로 오해하는 일을 줄일 수 있습니다.
dns 설정: 도메인을 누가 조회하는지 구분하기
한 번의 접속에서도 여러 주체가 도메인을 조회할 수 있습니다. 앱 자체, 운영체제, 코어 내장 DNS가 조회하거나 원격 연결의 반대편에서 처리할 수 있습니다. 설정에 dns가 있다고 해서 기기의 모든 조회가 이 설정을 거치는 것은 아닙니다. 먼저 앱이 도메인과 IP 중 무엇을 인바운드에 전달하는지 확인한 다음 해당 설정이 현재 요청에 관여하는지 판단하세요. 그렇지 않으면 코어 DNS를 변경해 놓고 시스템 조회 결과를 관찰해 잘못 결론 내릴 수 있습니다.
servers와 queryStrategy의 기본 역할
{
"dns": {
"servers": [
"1.1.1.1",
"localhost"
],
"queryStrategy": "UseIPv4"
}
}
이 설정은 명시적인 주소를 가진 DNS 서버와 로컬 시스템 조회 경로를 함께 지정하고, 코어에서 지원하는 조회 주소 계열을 IPv4로 제한합니다. 여기서 localhost는 원격 호스트 이름이 아니라 로컬 시스템의 DNS 조회 방식을 의미합니다. 목록을 ‘첫 번째 서버에 실패하면 두 번째 서버를 시도하는 고정 주·보조 구성’으로 단순하게 해석해서는 안 됩니다. 실제 선택, 병렬 조회, 대체 동작은 서버 객체와 매칭 도메인, 코어 구현에 따라 달라집니다.
UseIPv4는 성능 향상을 위한 공식이 아니라 주소 계열을 선택하는 설정입니다. 대상에 사용 가능한 IPv6 주소만 있다면 IPv4로 제한했을 때 접속하지 못할 수 있습니다. 반대로 기기의 IPv6 경로에 문제가 있는데 듀얼 스택을 허용하면 다른 유형의 연결 실패가 나타날 수 있습니다. 먼저 로컬 네트워크와 원격 경로가 지원하는 주소 계열을 확인한 뒤 조회 정책을 설정하세요. 이 필드는 시스템의 IPv6를 자동으로 끄지 않으며 기기의 네트워크 설정을 대신하지도 않습니다.
도메인별로 DNS 서버 선택하기
{
"dns": {
"servers": [
{
"address": "1.1.1.1",
"port": 53,
"domains": ["domain:example.com"]
},
"localhost"
],
"queryStrategy": "UseIP"
}
}
서버 객체를 사용하면 특정 도메인에 사용할 DNS 서버를 지정할 수 있습니다. 이 예시에서는 example.com과 하위 도메인을 지정된 서버의 매칭 범위로 설정합니다. 나머지 조회는 전체 대체 처리 방식을 함께 확인해야 합니다. domains는 라우팅의 domain 필드와 다른 항목이므로 이름이 비슷하다고 서로 바꿔 쓰면 안 됩니다. 더 복잡한 서버 객체에는 예상 주소 유형이나 대체 설정이 포함될 수 있으므로 추가 전에 해당 코어가 정확히 어떤 의미를 지원하는지 확인하세요.
DNS 서버에 네트워크로 연결할 수 있는지도 확인해야 합니다. 평문 DNS, 암호화 DNS, 로컬 조회 경로는 서로 다른 연결 경로를 사용할 수 있습니다. 일부 방식은 일반 라우팅의 영향을 받고 다른 방식은 로컬에서 처리될 수 있으므로 ‘servers에 넣으면 무조건 프록시를 거친다’고 일반화하지 마세요. DNS 서버 주소 자체가 도메인이라면 시작 단계에서 그 주소를 어떻게 얻는지도 고려해야 합니다. 조회가 자기 자신에 의존해 완료할 수 없는 순환 구조를 피하세요.
| 설정 위치 | 주요 역할 | 이 설정만으로 판단할 수 없는 사항 |
|---|---|---|
| 시스템 네트워크 설정 | 시스템 DNS를 사용하는 프로그램에 영향 | 코어의 모든 조회가 이 설정을 사용함 |
최상위 dns | 코어에서 DNS 조회 기능 제공 | 기기의 모든 DNS 트래픽을 가로챔 |
| 라우팅 조회 정책 | 매칭에 주소 정보가 필요한지 결정 | 특정 연결의 출구 지정 |
| 앱 자체의 DNS 설정 | 해당 앱의 DNS 조회 경로에 영향 | 다른 프로그램에도 같은 결과가 적용됨 |
캐시, 스니핑, FakeDNS의 범위
조회 정책을 변경한 뒤에도 앱, 운영체제, 코어에 이전 결과가 캐시되어 있을 수 있고 기존 연결이 계속 재사용될 수 있습니다. 새 연결을 만들어 확인하고 필요하면 해당 프로그램의 방식에 따라 캐시를 처리하세요. 같은 페이지를 한 번 새로고침하는 것만으로는 부족할 수 있습니다. 브라우저가 별도의 암호화 DNS를 사용하면 시스템의 조회 결과와 다를 수 있습니다. 결과를 비교하기 전에 검사 도구가 어떤 조회 경로를 이용하는지 확인해야 변경 사항이 실제 요청에 적용됐는지 판단할 수 있습니다.
FakeDNS는 가상 주소에 도메인 매핑을 저장해 이후 트래픽에서 도메인 정보를 복원하도록 돕습니다. 공용 네트워크에 실제 대상 주소를 할당하는 기능은 아닙니다. 트래픽 가로채기 방식, 매핑 해제, 스니핑 설정과 함께 사용해야 하며 필드 하나만 켠다고 모든 앱이 정상 작동하는 것은 아닙니다. 프로그램이 예상한 진입점을 우회해 가상 주소로 직접 접속하면 연결에 실패할 수 있습니다. 일반 시스템 프록시가 이미 작동한다면 설정을 늘리려고 굳이 활성화할 필요는 없습니다.
DNS 문제는 세 단계로 확인하세요. 먼저 조회 결과를 받았는지, 다음으로 그 결과가 현재 네트워크에서 유효한지, 마지막으로 접속이 실제로 어떤 결과를 사용했는지 살펴봅니다. 로그에 조회 시간 초과가 표시되면 DNS 서버에 연결할 수 있는지 확인하세요. 주소를 받았는데 연결에 실패한다면 주소 계열, 아웃바운드, 원격 경로를 점검하세요. 관련 내용은 FakeDNS 작동 방식과 사용 사례에서 확인할 수 있습니다. 모든 접속 실패의 원인을 DNS로 돌리지 마세요.
설정이 안정되면 서로 다른 DNS 조회 경로를 확인할 수 있는 대표 대상을 몇 개 정해 회귀 테스트에 사용하세요. 서버, 조회 정책, 트래픽 처리 방식을 바꿀 때마다 같은 대상으로 다시 확인합니다. DNS 결과는 서버 운영 상황에 따라 바뀔 수 있으므로 주소가 항상 같아야 하는 것은 아닙니다. 확인할 것은 조회가 완료되는지, 반환된 주소를 사용할 수 있는지, 연결이 예상한 라우팅 범위를 따르는지입니다.
policy와 로그: 연결을 관리하고 근거 남기기
policy는 연결 관리와 통계 관련 정책을 다루며 특정 도메인이 어느 출구를 사용할지 결정하지 않습니다. 라우팅 이상은 routing을, 인증 오류는 아웃바운드를 먼저 확인하세요. 정책에 ‘시간 초과’ 필드가 있다고 해서 모든 연결 실패를 대기 시간 부족으로 돌리지 마세요. 대부분의 일반적인 사용에서는 기본 정책을 유지하고, 로그에서 연결 수명주기가 요구사항과 맞지 않는 것이 명확해졌을 때 필요한 부분만 조정하면 됩니다.
레벨 정책과 연결의 연관 방식
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
여기서 레벨 키 "0"는 객체 키이므로 큰따옴표로 감싸야 합니다. 연결에 어떤 레벨을 적용하는지는 해당 프로토콜에서 사용자 레벨을 어떻게 설정하는지 확인해야 합니다. 일부 인바운드는 userLevel로 연결하고, 일부 프로토콜은 사용자 객체 안에 레벨을 지정합니다. 레벨 객체를 하나 추가해도 모든 연결이 자동으로 해당 레벨을 사용하는 것은 아닙니다. 예시의 숫자는 필드 설명을 위한 것이며 모든 네트워크에 권장되는 공통값은 아닙니다.
handshake는 연결을 설정할 때의 핸드셰이크 대기와 관련되고, connIdle은 연결이 유휴 상태인 시간을 처리합니다. uplinkOnly와 downlinkOnly는 단방향 전송 상태에서 연결을 유지하는 시간과 관련이 있습니다. 시간 값은 보통 초 단위지만 구체적인 역할은 프로토콜과 연결 단계에 따라 달라집니다. 모든 값을 크게 설정하면 잘못된 연결이 리소스를 더 오래 점유할 뿐, 서버 주소나 인증 매개변수 오류를 해결하지는 못합니다.
통계 설정만으로 통계 기능이 완성되지는 않습니다
정책의 통계 불리언 값은 특정 데이터의 기록을 허용할 뿐이며, 실제 조회에는 통계 모듈, 사용자 식별자, 인터페이스 설정, 클라이언트의 호출 방식이 추가로 필요할 수 있습니다. 설정 몇 개를 켠다고 화면에 모든 통계가 바로 표시되지는 않습니다. 그래픽 클라이언트를 사용한다면 클라이언트가 관리하는 통계 설정을 유지하세요. 태그를 직접 바꾸거나 인터페이스를 삭제하면 화면에서 코어와 통신하지 못할 수 있습니다.
통계를 확인하려고 관리 인터페이스를 무작정 외부에 공개하지 마세요. 리스닝 여부와 주소, 접근 가능한 대상을 각각 확인해야 합니다. 관리 인터페이스는 일반 앱용 프록시 진입점이 아닙니다. 클라이언트에서 이미 트래픽 정보를 제공한다면 외부에서 접근 가능한 인터페이스를 별도로 만들 필요가 없는 경우가 많습니다. 이 페이지의 기준 설정에 관리 인터페이스가 없는 것은 연결 경로를 명확히 하기 위한 것이며 완성된 모니터링 배포 구성을 제공하려는 목적은 아닙니다.
로그는 warning으로 두고 필요할 때만 잠시 상세 수준을 높이세요
{
"log": {
"loglevel": "warning"
}
}
평소에는 warning을 사용하면 일반 로그 출력을 줄일 수 있습니다. 문제를 해결하면서 요청이 어디로 향하는지 봐야 한다면 로그 수준을 잠시 높이고 문제를 다시 재현하세요. 디버그 로그를 지나치게 많이 장시간 남기지 마세요. 대상 주소와 연결 세부 정보가 기록되고 저장 공간도 더 많이 필요할 수 있습니다. 원인을 찾은 뒤 일반 로그 수준으로 되돌리고 클라이언트에서 지원하는 방식으로 불필요한 로그를 처리하세요.
{
"log": {
"access": "access.log",
"error": "error.log",
"loglevel": "info"
}
}
이 설정 조각은 액세스 로그와 오류 로그를 상대 경로 파일에 기록합니다. 상대 경로는 보통 프로세스의 작업 디렉터리를 기준으로 하므로 JSON 파일을 연 디렉터리에 저장된다는 보장이 없습니다. 클라이언트가 로그 출력을 별도로 관리할 수도 있습니다. 사용 전에 디렉터리에 쓸 수 있는지, 파일 위치를 찾을 수 있는지, 로그가 계속 커지는지 확인하세요. 로그 경로 오류로 시작에 실패하면 연결 설정을 근거 없이 반복해서 바꾸지 말고 클라이언트 기본 로그 출력 방식으로 복구하세요.
로그를 읽을 때는 시간 순서에 따라 한 번의 접속 과정을 되짚으세요. 코어가 시작됐는지, 인바운드가 연결을 받았는지, 라우팅이 어떤 출구를 선택했는지, DNS 조회가 성공했는지, 핸드셰이크가 어느 단계에서 실패했는지 확인합니다. 첫 번째 명확한 오류가 설정 필드를 인식할 수 없다는 내용이라면 그 뒤의 연결 상태를 분석할 필요가 없습니다. 시작은 정상이지만 접속 기록이 없다면 앱의 진입점으로 돌아가세요. 가장 먼저 발생한 확실한 이상을 찾은 뒤 수정할 부분을 결정하세요.
모바일에서는 프로세스 수명주기와 연결 정책도 구분해야 합니다. 운영체제가 앱을 종료하거나 백그라운드 권한을 제한하거나 네트워크가 바뀌면 connIdle 값을 늘리는 것만으로 해결할 수 없습니다. 화면을 끈 뒤 연결이 끊긴다면 v2rayNG 백그라운드 실행 및 배터리 설정을 참고해 시스템 설정을 확인하세요. 정책 매개변수는 코어가 계속 실행 중이고 연결을 실제로 관리할 때에만 의미가 있습니다.
검증과 롤백: 최소 설정으로 문제 범위 좁히기
설정을 검증할 때는 ‘코어를 시작할 수 있는지’와 ‘대상에 접속할 수 있는지’를 나눠 확인하세요. 전자는 JSON, 필드 호환성, 리소스, 리스닝 조건을 점검하며 후자는 앱 연결, DNS 조회, 라우팅, 후속 연결까지 포함합니다. 아래에는 로컬 직접 연결 기준 설정을 소개합니다. 원래 직접 접속할 수 있는 대상에 앱이 코어를 거쳐 접속할 수 있는지 확인하는 용도이며 원격 프록시 기능이나 GeoIP, GeoSite 리소스는 포함하지 않습니다.
로컬 직접 연결 기준 설정 전체
{
"log": {
"loglevel": "info"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "direct"
}
]
}
}
기존 클라이언트 설정을 먼저 백업한 뒤 완전한 사용자 지정 설정을 지원하는 클라이언트 기능으로 이 기준 설정을 불러오세요. 단일 노드 필드만 받는 입력란에 붙여 넣지 마세요. 클라이언트가 포트를 관리하거나 설정을 별도로 생성한다면 실제 동작 방식에 맞게 처리해 코어 두 개가 동시에 실행되며 포트를 놓고 충돌하지 않도록 하세요. 불러온 다음 수동 프록시를 지원하는 앱에서 해당 로컬 인바운드를 지정하고 직접 접속할 수 있다고 알려진 대상으로 접속하세요.
한 번에 여러 값을 바꾸지 말고 단계별로 검증하세요
기준 설정으로 시작할 수 없다면 가장 먼저 나타난 오류부터 확인하세요. 구문 오류라면 괄호, 쉼표, 큰따옴표를 점검합니다. 포트 충돌이라면 다른 프로세스를 확인하고, 필드를 인식하지 못한다면 코어 종류와 설정 형식을 확인하세요. 이 단계에서는 DNS, 스니핑, 추가 아웃바운드를 넣지 마세요. 오류 원인만 늘어납니다. 최소 설정은 서로 얽힌 문제를 따로 확인할 수 있는 단계로 나누는 데 의미가 있습니다.
시작에는 성공했지만 앱에서 접속할 수 없다면 먼저 로그에 해당 요청이 있는지 확인하세요. 요청이 없다면 앱의 프록시 프로토콜, 주소, 포트를 점검합니다. 요청은 있지만 DNS 조회에 실패한다면 시스템 DNS와 대상 도메인을 확인하세요. 주소는 받았지만 연결에 실패한다면 로컬 네트워크와 대상 서비스를 점검합니다. 아직 원격 아웃바운드가 없으므로 원격 인증이나 전송 매개변수를 살펴볼 필요는 없습니다. 기준 설정부터 정상인지 확인해야 이후 비교가 의미 있습니다.
기준 설정이 작동하면 기존 원격 아웃바운드를 복원하고 명확한 라우팅 규칙 하나로 연결하세요. 원격 연결 하나를 먼저 확인한 다음 도메인 분류, DNS 객체, 기타 정책을 차례로 추가합니다. 설정을 한 묶음 추가할 때마다 같은 방식으로 접속해 결과를 기록하세요. 특정 설정을 추가한 뒤 실패하기 시작했다면 해당 설정만 되돌려 범위를 좁힐 수 있습니다. 이미 검증된 인바운드를 다시 구성할 필요는 없습니다.
| 확인된 현상 | 먼저 확인할 항목 | 우선순위가 낮은 항목 |
|---|---|---|
| 코어가 바로 종료됨 | 구문, 필드, 리소스, 포트 | 브라우저 캐시 |
| 시작은 정상이나 요청이 없음 | 앱 진입점과 프록시 적용 범위 | 원격 인증 매개변수 |
| 요청은 들어오지만 출구가 예상과 다름 | 불러온 설정, 규칙 순서, 태그 | 연결 시간 초과 늘리기 |
| 출구는 맞지만 핸드셰이크 실패 | 프로토콜, 전송, 시간, 원격 설정 | 도메인 분류 순서 변경 |
설정 다시 불러오기와 기존 연결
설정을 수정한 뒤에는 클라이언트에서 지원하는 방식으로 설정을 다시 불러오거나 코어를 재시작해야 합니다. 이미 연결된 장시간 연결, 브라우저 연결 풀, 앱 캐시는 이전 상태를 계속 사용할 수 있습니다. 계속 재생 중인 페이지 하나만 보고 새 규칙이 적용되지 않았다고 판단하지 마세요. 새 연결을 만들어 확인하고 필요한 경우 해당 앱을 닫았다가 다시 시도하세요. 필드를 바꿀 때마다 기기를 재시작할 필요는 없습니다. 작은 범위의 동작으로 설정 변경을 확인하는 편이 효율적입니다.
시스템 프록시와 TUN도 각각 따로 검증하세요. 먼저 한 가지 접속 방식으로 테스트를 완료한 뒤 다른 방식으로 전환해야 합니다. 두 가지 트래픽 처리 방식이 겹치면 연결이 어디로 들어오는지 알기 어려워집니다. 데스크톱과 Android의 시스템 연동 방식은 다르지만 점검 순서는 같습니다. 진입점, DNS 조회, 라우팅, 출구 순으로 확인하세요. 특정 앱 하나에만 영향이 없다면 코어 전체가 작동하지 않는다고 결론 내리기 전에 해당 앱에 프록시가 적용되는 범위를 확인하세요.
롤백할 때는 서로 연관된 필드를 한 묶음으로 복원하세요
유효한 백업은 JSON 파일 하나만을 뜻하지 않습니다. 설정 출처, 현재 코어, 필요한 리소스, 클라이언트 관련 설정도 함께 보관해야 합니다. 라우팅을 되돌릴 때는 규칙 순서를 통째로 복원하고, 아웃바운드를 되돌릴 때는 프로토콜과 관련 전송 필드를 함께 복원하세요. DNS를 되돌릴 때는 앱 자체의 DNS 설정도 확인해야 합니다. 눈에 보이는 마지막 값 하나만 취소하고 삭제된 태그를 가리키는 라우팅 규칙을 남겨두지 마세요. 연관 필드가 빠지면 새 오류가 발생할 수 있습니다.
마지막으로 변경 목적, 관련 필드, 검증 방법, 결과를 짧게 기록해 두세요. 계정 정보를 적거나 매번 전체 로그를 저장할 필요는 없습니다. 다음에 비슷한 문제가 생기면 검증된 기준 설정을 먼저 재사용하고 추가된 부분을 비교하세요. 처음 사용한다면 튜토리얼로 돌아가고, 자주 발생하는 연결 문제는 연결 문제 FAQ에서 확인하세요. 이 페이지는 필드와 실행 관계를 찾아보는 참고 자료이므로 실제 문제에 맞는 장으로 돌아가 확인하면 됩니다.