JSON · inbounds · outbounds · routing · dns · policy
V2Ray 설정 파일 가이드
트래픽 진입점과 출구, 규칙 적용 순서에 따라 항목을 살펴보고 클라이언트 설정과 코어 실행 설정을 구분합니다.
이 페이지는 설정 파일을 이해하고 싶은 사용자를 위한 참고 가이드입니다. 처음 사용한다면 먼저 사용 가이드에 따라 설치와 구독 가져오기, 연결을 마친 뒤 필요한 항목을 찾아보세요. 데스크톱에서는 v2rayN 사용을 권장합니다. 설치 파일과 지원 플랫폼은 다운로드 센터에서 확인할 수 있습니다. 여기서는 V2Fly와 Xray에서 흔히 쓰이는 JSON 설정 구조를 다루며, 각 코어 전용 항목을 공통 형식처럼 섞어 설명하지 않습니다.
1. JSON 구조와 설정 로드 범위
최상위 객체를 요청 흐름으로 이해하기
설정 파일은 코어가 연결을 수신하고, 전달 방식을 선택하고, 부가 기능을 처리하는 방법을 정의합니다. 구독 주소를 다른 형식으로 적은 것이 아닙니다. 애플리케이션의 요청은 인바운드로 들어오고, 라우팅 모듈은 목적지와 출발지 정보를 확인한 뒤 선택된 아웃바운드로 연결을 전달합니다. DNS, 로그, 정책은 각 처리 단계에 관여합니다. 이 흐름을 이해하면 설정을 바꿀 때 관련 있어 보이는 스위치를 한꺼번에 수정하는 대신 문제의 원인이 어느 계층에 있는지 먼저 판단할 수 있습니다.
흔히 사용하는 최상위 객체로는 log, inbounds, outbounds, routing, dns, policy가 있습니다. 인바운드와 아웃바운드는 여러 리스닝 진입점과 출구를 둘 수 있어 보통 배열로 작성합니다. 라우팅도 규칙 적용 순서를 나타내는 배열을 사용합니다. 배열의 순서는 동작에 영향을 줄 수 있지만 객체 필드의 작성 순서는 대개 의미에 영향을 주지 않습니다. 들여쓰기와 정렬은 가독성을 높이지만, 보기 좋게 만들겠다고 아웃바운드나 라우팅 규칙 순서를 임의로 바꾸면 안 됩니다.
실행 가능한 로컬 기본 구성부터 만들기
아래의 완전한 예시는 로컬 루프백 주소에서 SOCKS 포트를 열고 직결 아웃바운드를 사용합니다. 코어가 파일을 읽고 포트를 바인딩해 로컬 요청을 처리하는지 확인하기 위한 구성으로, 원격 프록시 터널을 만들지는 않습니다. 실행 전에는 해당 포트를 클라이언트가 사용 중인지 확인하고, 테스트할 애플리케이션에서 이 SOCKS 진입점을 직접 지정하세요. 첫 검증을 TCP 요청으로 한정하기 위해 UDP는 활성화하지 않았습니다. 다른 기능은 다음 장에서 따로 설명합니다.
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": false
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
JSON 문자열에는 영문 큰따옴표를 사용하고, 불리언 값은 true 또는 false로 작성하며, 숫자에는 따옴표를 붙이지 않습니다. 배열이나 객체의 마지막 항목 뒤에는 쉼표를 남기지 말고 코드에 한국어 설명을 직접 넣지 마세요. 주석을 허용하는 확장 형식을 지원하는 도구도 있지만, 편집기에서 열리는 것만으로 코어가 해당 형식을 받아들인다고 볼 수는 없습니다. 도구 간에 설정을 공유할 때는 엄격한 JSON을 사용하면 문법 오류를 찾기 쉽습니다. 파일은 UTF-8 텍스트로 저장하면 됩니다.
항목이 있어도 현재 코어에서 지원하지 않을 수 있습니다
V2Fly와 Xray는 설정의 역사적 기반을 공유하지만 지원 프로토콜, 전송 옵션, 항목의 변경 방향은 완전히 같지 않습니다. 예시를 참고하기 전에 실행 중인 프로세스가 어느 코어인지 확인하고 해당 코어의 항목 정의를 대조하세요. 클라이언트 화면에 옵션이 있다는 것은 해당 클라이언트가 설정 입력란을 제공한다는 뜻일 뿐, 모든 코어가 같은 JSON을 받아들인다는 뜻은 아닙니다. sing-box는 별도의 설정 구조를 사용하므로 이 페이지의 예시를 그대로 설정 파일로 불러올 수 없습니다.
또한 ‘편집한 파일’과 ‘프로세스가 불러온 파일’을 구분해야 합니다. GUI 클라이언트는 시작할 때 임시 실행 설정을 생성할 수 있고, 사용자 지정 설정을 별도 항목으로 불러올 수도 있습니다. 특정 폴더의 JSON을 저장했는데 변화가 없다면 시작 로그나 설정 상세 정보를 확인해 실제 로드 경로와 현재 항목을 점검하세요. 프로그램 폴더에 이름이 비슷한 파일이 있다고 해서 적용 중인 파일이라고 단정하지 마세요. 클라이언트 데이터베이스와 생성 파일을 동시에 수정하며 운에 맡기는 것도 피해야 합니다.
| 객체 | 주요 역할 | 우선 점검할 항목 |
|---|---|---|
inbounds | 로컬 연결 수신 및 리스닝 | 주소, 포트, 프로토콜 |
outbounds | 연결 전달 방식 정의 | 프로토콜, 목적지, 전송 매개변수 |
routing | 순서에 따라 아웃바운드 선택 | 규칙 조건과 태그 참조 |
dns | 내장 도메인 이름 해석 설정 | 서버 및 해석 경로 |
policy | 연결 및 통계 정책 설정 | 사용자 등급 및 시스템 스위치 |
설정 파일을 유지 관리하기 쉽게 만드는 핵심은 명확한 경계입니다. 먼저 정상 작동하는 기본 구성을 보존한 뒤, 한 번에 하나의 객체만 수정하세요. 적용 여부를 확인한 다음에는 변경 이유와 예상 결과를 기록합니다. 설정 조각을 합칠 때는 최상위에 같은 이름의 필드가 중복되지 않도록 특히 주의하세요. 같은 필드는 객체나 배열 하나만 남겨야 하며 완전한 설정 두 개를 이어 붙이면 안 됩니다. 파서가 중복 키를 허용하더라도 값 하나만 남을 수 있어, 실제 결과가 읽은 내용과 달라질 수 있습니다.
이 페이지는 진입점, 출구, 라우팅, DNS, 정책 순서로 설명한 뒤 클라이언트 관리와 검증 절차를 다룹니다. 목차를 따라 필요한 곳부터 읽어도 되지만 전달 문제가 생기면 요청 흐름에 따라 점검해야 합니다. 먼저 트래픽이 대상 프로세스에 실제로 들어오는지 확인한 다음 규칙이 일치하는지 살펴보세요. 진입 트래픽이 없는 상태에서 라우팅을 바꾸면 점검 항목만 늘어날 뿐, 어떤 규칙이 맞는지 확인할 수 없습니다.
2. inbounds 인바운드 리스닝과 트래픽 진입점
리스닝 주소·포트·프로토콜의 역할 구분
inbounds의 각 객체는 하나의 진입점을 정의합니다. listen은 바인딩할 로컬 주소를, port는 리스닝 포트를, protocol은 진입점에서 받을 프로토콜을 지정합니다. 애플리케이션은 진입점과 같은 프록시 방식을 사용해야 합니다. SOCKS만 받는 포트에 HTTP 프록시 주소를 입력할 수는 없습니다. 포트 번호는 로컬에서 정한 값일 뿐 특정 기능을 보장하지 않습니다. 설정을 복사할 때는 현재 파일과 클라이언트에 표시된 실제 값을 기준으로 삼으세요.
이 기기에서만 사용할 경우 리스닝 주소를 127.0.0.1로 명확히 지정하세요. 이 주소는 IPv4 루프백 주소이므로 다른 기기에서 직접 접근할 수 없습니다. 0.0.0.0으로 바꾸면 모든 IPv4 인터페이스에 바인딩한다는 뜻이지, 다른 기기에서 접속할 대상으로 입력할 주소가 아닙니다. LAN 접근을 열려면 호스트 주소, 방화벽, 인증도 함께 고려해야 하므로 별도의 변경으로 다루세요. 로컬 연결 실패를 해결하려고 리스닝 범위를 바로 넓히면 안 됩니다.
SOCKS와 HTTP 진입점을 함께 사용하기
아래 조각은 첫 장의 SOCKS 진입점에 HTTP 진입점을 추가해 두 종류의 프록시 설정을 각각 입력해야 하는 애플리케이션에 사용할 수 있습니다. 최상위에 같은 이름의 필드를 하나 더 추가하지 말고 기존 배열 전체를 inbounds 배열로 교체하세요. 두 진입점은 서로 다른 포트를 사용하며 아웃바운드는 같은 객체를 함께 사용할 수 있습니다. 이 태그는 설정 내부에서 참조하기 위한 이름일 뿐, 시스템이 프록시를 자동으로 인식하거나 활성화해 주지는 않습니다.
{
"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 인바운드의 udp는 SOCKS UDP 전달 요청을 처리하도록 허용한다는 뜻입니다. 시스템 프록시를 사용하는 모든 프로그램이 UDP를 지원하게 되는 것은 아닙니다. 애플리케이션 자체가 해당 기능을 사용해야 하고, 아웃바운드 프로토콜과 서버, 네트워크 경로도 그 트래픽을 지원해야 합니다. HTTP 인바운드는 주로 HTTP 프록시 설정을 따르는 애플리케이션에 사용됩니다. 브라우저는 정상인데 다른 프로그램에서 문제가 생긴다면 대상 도메인만 비교하지 말고 각 프로그램의 진입 방식부터 확인하세요.
tag는 짧고 고유하며 알아보기 쉽게 작성하세요. 라우팅에서 inboundTag로 특정 진입점을 지정하면 로컬 포트마다 다른 출구를 사용할 수 있습니다. 태그 이름을 바꿔도 참조가 자동으로 수정되지는 않습니다. 이름을 변경했다면 연결된 항목도 함께 수정해야 합니다. 그렇지 않으면 문법 오류 없이 규칙이 일치하지 않을 수 있습니다. 각 진입점이 어떤 애플리케이션에 대응하는지 설정 설명에 기록해 두면, 시간이 지난 뒤 포트 번호만 보고 용도를 추측하는 일을 막을 수 있습니다.
스니핑은 대상 정보를 보완하지만 DNS를 대신하지 않습니다
일부 애플리케이션은 도메인을 IP 주소로 해석한 다음 프록시 요청을 보내므로 라우팅에 도착한 대상이 원래 도메인이 아닐 수 있습니다. sniffing은 지원되는 애플리케이션 계층 핸드셰이크에서 도메인을 식별해 이후 처리에 활용할 수 있습니다. 흔히 사용하는 destOverride 값에는 http와 tls가 있습니다. 하지만 스니핑이 모든 트래픽에서 동작하는 것은 아니며 임의의 애플리케이션 데이터를 복호화하지도 않습니다. 연결 대상이 바뀌는지는 사용 중인 코어의 실제 동작을 확인해야 합니다.
{
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
이 조각은 특정 인바운드 객체 안에 넣어야 하며 독립적인 최상위 모듈이 아닙니다. 활성화하기 전에 목적을 분명히 하세요. 도메인 라우팅 정보를 보완하려는 것인지, 대상 주소를 복원하려는 것인지 확인해야 합니다. 애플리케이션 프로토콜이 지원 범위 밖이거나 핸드셰이크에서 식별 가능한 정보를 얻지 못하면 원래 대상 정보와 IP 규칙에 의존해야 합니다. 스니핑을 모든 도메인 분기 문제를 해결하는 만능 방법으로 여기지 마세요. 설정을 변경한 뒤에는 영향을 받는 애플리케이션의 연결 결과를 다시 확인하세요.
포트 바인딩 실패를 점검할 때는 먼저 중복 실행 중인 클라이언트를 종료한 다음 같은 주소와 포트를 사용하는 다른 프로세스가 있는지 확인하세요. 포트를 연달아 바꾸다 애플리케이션 설정을 갱신하지 못하는 일이 없도록 주의해야 합니다. 리스닝은 성공했는데 애플리케이션 요청이 기록되지 않는다면 앱 자체 프록시 설정을 사용하는지, 로컬 주소를 우회하는지, 시스템 프록시가 이전 포트를 가리키는지 확인하세요. 진입점을 확인한 뒤 아웃바운드를 점검하면 ‘연결이 들어오지 않음’을 ‘원격 서버가 작동하지 않음’으로 잘못 판단하는 일을 줄일 수 있습니다.
3. outbounds 아웃바운드 프로토콜과 전송 매개변수
아웃바운드 객체가 실제 전달 방식을 정의합니다
outbounds에는 직결, 차단, 원격 프록시 등 여러 객체를 넣을 수 있습니다. protocol은 아웃바운드 프로토콜을 지정하고, settings에는 해당 프로토콜에 필요한 매개변수를 저장하며, tag는 라우팅에서 참조할 때 사용합니다. 아웃바운드 태그는 서버 주소도 클라이언트에 표시되는 별칭도 아닙니다. 한글 별칭을 바꿨을 때 생성 설정의 태그까지 바뀌는지는 클라이언트에 따라 다릅니다. 실행 설정을 확인할 때는 객체에 실제로 정의된 태그를 기준으로 삼고, 화면에 표시된 이름만으로 참조 관계를 추측하지 마세요.
라우팅 규칙에 일치하는 항목이 없으면 일반적인 구성에서는 아웃바운드 배열의 첫 번째 객체를 사용합니다. 따라서 배열 순서는 단순한 정렬 문제가 아닙니다. 직결 객체를 두 번째에서 첫 번째로 옮기면 일치하지 않은 모든 트래픽의 목적지가 달라질 수 있습니다. 동작을 쉽게 파악하려면 라우팅 마지막에 명시적인 기본 규칙을 둘 수 있지만, 첫 번째 아웃바운드의 의미도 확인해야 합니다. 특히 클라이언트 생성 설정과 직접 관리하는 설정을 전환할 때 주의하세요.
직결과 차단을 위한 최소 객체
아래에는 아웃바운드 두 개를 정의합니다. freedom은 트래픽을 로컬 네트워크에 전달해 목적지에 직접 연결하고, blackhole은 일치하는 트래픽을 버립니다. 둘 다 원격 서버 정보는 필요하지 않습니다. 이 배열은 첫 장의 인바운드와 함께 사용할 수 있지만, 라우팅 규칙을 추가하지 않으면 차단 객체가 배열에 있다는 이유만으로 적용되지는 않습니다. 설정 객체는 기능을 제공하고 라우팅은 사용할 기능을 선택하므로 두 역할을 구분해야 합니다.
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
원격 프록시 아웃바운드에는 보통 서버 주소, 포트, 인증 정보, 전송 설정이 추가로 필요합니다. 이 정보는 실제 서비스 설정에 따라야 하며 클라이언트 이름만 보고 추측할 수 없습니다. VMess, VLESS, Trojan의 인증 필드는 서로 다르고 TLS, WebSocket 등의 전송 매개변수도 잘못된 계층에 넣으면 안 됩니다. 처음부터 여러 계층을 직접 조립하는 것보다 서비스 제공자가 제공한 유효한 구독이나 링크를 가져온 뒤 클라이언트가 생성한 결과를 확인하는 편이 일관성을 유지하기 쉽습니다.
프로토콜·전송·보안 계층을 각각 확인하기
streamSettings는 하위 전송 및 보안 관련 설정을 설명하며, settings에 들어가는 프로토콜 인증 정보와 역할이 다릅니다. 서버가 사용하는 전송 방식에 맞춰 클라이언트도 해당 구조를 사용해야 합니다. 경로, 호스트 이름, 보안 매개변수는 한 세트로 맞춰야 합니다. 전송 이름만 다른 방식으로 바꾼다고 서버 설정이 자동 변환되는 것은 아닙니다. 핸드셰이크에 실패하면 드롭다운 항목을 무작정 바꿔 보기보다 먼저 서버에서 요구하는 조합을 확인하세요.
| 계층 | 담당 내용 | 흔한 오해 |
|---|---|---|
protocol | 아웃바운드 프로토콜 선택 | 이름이 비슷하면 서로 바꿔 쓸 수 있다고 생각함 |
settings | 프로토콜별 주소 및 인증 정보 | 서로 다른 프로토콜의 인증 구조를 혼용함 |
streamSettings | 전송 및 보안 설정 | 서버 설정을 확인하지 않고 네트워크 방식만 바꿈 |
tag | 내부 규칙에서 참조할 이름 | 화면에 표시된 별칭을 고정 태그로 간주함 |
연결 주소와 TLS 검증에 사용하는 서버 이름은 서로 다른 개념입니다. 전자는 연결할 대상을 정하고, 후자는 인증서의 신원을 확인하는 데 사용됩니다. 일부 환경에서는 두 값이 다를 수 있지만 실제 서비스 설정에 근거해야 합니다. 인증서 오류가 발생하면 검증을 건너뛰기보다 시스템 시간, 서버 이름, 인증서 체인을 확인하세요. 검증을 생략하면 연결 보안 조건이 달라지므로 장기적인 해결책으로 사용할 수 없으며, 다른 매개변수가 올바르다는 증거도 되지 않습니다.
REALITY 같은 전용 기능은 호환되는 코어와 일치하는 서버 매개변수가 필요합니다. JSON에 보안 관련 항목이 있다는 이유만으로 다른 코어의 설정에 예시를 그대로 옮기지 마세요. v2rayN은 여러 코어의 항목을 관리할 수 있지만 모든 항목의 실행 프로그램을 자유롭게 바꿀 수 있다는 뜻은 아닙니다. Android에서는 v2rayNG와 v2flyNG도 각 코어가 지원하는 기능에 따라 선택해야 합니다. 세 클라이언트의 역할은 클라이언트 비교에서 확인하세요.
아웃바운드 문제는 객체 하나씩 점검하세요. 테스트 요청이 목표 아웃바운드만 사용하도록 임시로 명확한 기본 규칙을 설정하고 기본 연결을 확인한 다음 복잡한 분기를 다시 적용합니다. 특정 사이트만 실패한다면 대상 해석과 규칙을 확인하고, 모든 대상의 연결이 실패한다면 원격 주소, 인증, 전송 설정을 점검하세요. 기본 오류를 감추려고 여러 연결 최적화 기능을 동시에 켜지 마세요. 계층이 늘어나면 로그의 실패 지점을 원래 요청과 연결하기 어려워집니다.
구독을 업데이트하면 서비스 제공자가 연결 매개변수를 변경하거나 클라이언트가 내부 태그를 다시 생성할 수 있습니다. 직접 관리하는 사용자 지정 라우팅에서 이전 태그를 참조한다면 다시 확인해야 합니다. 원격 매개변수는 구독 항목에서 관리하고, 장기간 유지할 분기 설정은 라우팅에 두는 편이 좋습니다. 아웃바운드를 완전히 직접 관리해야 한다면 매개변수 출처와 코어 요구 사항을 기록하세요. 문제 해결 정보를 공유하기 전에는 인증 정보와 비공개 구독 주소를 삭제해야 합니다.
4. routing 라우팅 규칙과 적용 순서
먼저 일치하는 규칙이 출구를 결정합니다
routing.rules는 순서가 있는 규칙 배열입니다. 일반적인 필드 규칙에서는 같은 배열 필드에 지정된 여러 후보 중 하나만 일치해도 조건을 만족합니다. 반면 서로 다른 조건 필드가 있으면 모든 조건을 만족해야 합니다. 예를 들어 인바운드 태그와 도메인을 함께 지정한 규칙은 지정된 진입점으로 들어오고 대상 도메인까지 조건에 맞는 연결만 처리합니다. 앞에 있는 규칙이 먼저 적용되므로 예외 규칙은 범위가 넓은 규칙보다 앞에, 기본 규칙은 마지막에 두세요.
아래 예시는 먼저 문서용 예시 도메인을 차단하고, 그다음 사설 주소를 직결로 보내며, 마지막으로 나머지 TCP와 UDP 트래픽도 직결로 전달합니다. 규칙 순서와 태그 참조를 설명하기 위한 예시이지 원격 프록시 분기 구성이 아닙니다. 사용하려면 direct와 block 태그가 지정된 아웃바운드가 있어야 하며, 현재 코어가 읽을 수 있는 GeoIP 데이터 파일도 설치해야 합니다. 데이터베이스가 없다면 기본 구성을 검증하는 동안 해당 규칙을 먼저 제거하세요.
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": [
"full:example.org"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "direct"
}
]
}
}
도메인 표기는 정확한 일치 의도를 나타내야 합니다
full:example.org는 해당 도메인만 정확히 일치시키고, domain:example.org는 해당 도메인과 하위 도메인을 일치시킵니다. 정규식은 더 넓은 조건을 표현할 수 있지만 지나치게 많은 대상을 일치시킬 위험도 큽니다. 일반적인 경우에는 명확한 전체 도메인이나 접미사 규칙을 사용하세요. 웹페이지 전체 주소를 도메인 목록에 넣지 마세요. 경로, 쿼리 매개변수, 프래그먼트는 도메인 조건이 아니므로 경로가 포함된 주소를 사용하면 규칙이 있어도 일치하지 않을 수 있습니다.
IP 조건에는 단일 주소, 네트워크 대역, 데이터베이스 참조를 사용할 수 있습니다. 도메인 규칙과 IP 규칙은 서로 다른 정보를 다루므로, 특정 도메인이 어떤 분류에 일치했다고 해서 그 도메인의 모든 해석 주소도 같은 분류에 속한다고 볼 수 없습니다. CDN을 사용하는 사이트는 여러 사이트가 같은 주소를 공유할 수 있고, 하나의 사이트가 지역에 따라 다른 주소를 반환할 수도 있습니다. 정밀한 제어가 필요한 경우 도메인과 IP 중 어떤 기준으로 일치시킬지 먼저 정하고, 소수의 명확한 도메인 대신 넓은 네트워크 대역을 사용하지 마세요.
domainStrategy는 라우팅 중 DNS 해석 시점을 제어합니다
AsIs는 연결에서 받은 기존 대상 정보로 라우팅하며 IP 규칙에 맞추려고 별도로 해석하지 않습니다. IPIfNonMatch는 기존 조건에 일치하지 않을 때 도메인을 해석해 추가로 일치 여부를 확인합니다. IPOnDemand는 일치 여부를 판단하는 데 IP 정보가 필요할 때 해석합니다. 뒤의 두 방식을 선택하면 라우팅 결과가 DNS 응답에 따라 달라질 수 있습니다. 해석 실패나 주소 변경도 판단에 영향을 주므로 5장과 함께 살펴보세요.
여기서 설명하는 라우팅 해석 정책은 모든 아웃바운드의 주소 처리 정책이나 운영체제 DNS 설정과 같지 않습니다. 이름이 비슷한 필드라도 서로 다른 모듈에 있어 작동 시점과 적용 범위가 다를 수 있습니다. 변경하기 전에 설정 경로를 확인하고 예상 동작을 구체적으로 설명하세요. 예를 들어 ‘도메인으로 일치하지 않으면 해석된 주소로 규칙을 적용’하는 편이 ‘스마트 해석 켜기’보다 명확합니다. 애플리케이션이 이미 IP 주소를 대상으로 요청했다면 도메인 해석 정책으로 원래 도메인을 복원할 수 없습니다.
GeoIP와 GeoSite 데이터는 함께 관리해야 합니다. 파일을 업데이트한 뒤 실제 실행 중인 코어가 새 파일을 읽는지 확인하고, 클라이언트 안내에 따라 재시작하거나 다시 불러오세요. 다른 디렉터리에 있는 사본만 교체해도 결과는 달라지지 않습니다. 카테고리를 찾을 수 없거나 데이터를 읽지 못한다는 오류가 발생하면 규칙 문법을 바꾸기 전에 파일 출처와 경로부터 확인하세요. 자세한 업데이트 방법은 GeoIP 및 GeoSite 데이터베이스 업데이트 가이드를 참고하세요.
클라이언트의 ‘중국 본토 우회’ 같은 프리셋은 여러 규칙을 묶은 구성이지 단일 스위치와 같은 기능이 아닙니다. 프리셋을 바꾸면 도메인, IP, 기본 출구가 함께 달라질 수 있으므로 문제를 점검할 때 생성된 전체 규칙을 확인해야 합니다. 예외 하나를 추가하려면 먼저 일치할 수 있는 넓은 규칙보다 앞에 배치하고 저장 후 다시 불러왔는지 확인하세요. 조건이 너무 넓은지 판단하려면 일치해야 하는 대상과 일치하지 않아야 하는 대상을 각각 테스트해야 합니다.
여러 진입점을 사용하는 경우 inboundTag로 애플리케이션을 분리해 특정 로컬 포트에서 고정 출구를 사용하도록 설정할 수 있습니다. 직접 프록시를 지정할 수 있는 프로그램에는 시스템 프록시를 반복해서 바꾸는 방법보다 편리하지만, 앱이 해당 진입점에 실제로 연결해야 합니다. 라우팅이 기대대로 동작하지 않으면 인바운드 태그, 원래 대상, 규칙 순서, 아웃바운드 태그를 차례로 확인하세요. 결과가 예상과 다르다고 곧바로 데이터베이스를 바꾸거나 원격 프로토콜을 수정하지 마세요.
5. dns DNS 설정과 질의 경로
먼저 어느 계층에서 DNS 질의를 보내는지 확인하세요
한 번의 접속에 애플리케이션 자체의 DNS 해석, 운영체제 DNS, 코어 내장 DNS, 원격 서버의 해석이 모두 관여할 수 있습니다. 최상위 dns 설정은 코어 내장 해석기가 처리하는 부분만 관리하며 모든 프로그램의 도메인 질의를 자동으로 가로채지는 않습니다. 브라우저에서 자체 암호화 DNS를 사용하면 질의 경로가 또 달라질 수 있습니다. 문제를 점검할 때는 대상이 도메인인지 IP인지 확인하고 코어에 들어오는지 기록한 뒤, 현재 문제가 이 설정과 관련 있는지 판단하세요.
내장 DNS는 라우팅의 도메인 해석 정책이나 특정 아웃바운드 동작 등에서 호출할 수 있습니다. 서버 배열만 추가한다고 모든 프록시 요청을 로컬에서 먼저 해석하는 것은 아닙니다. 원격 프로토콜이 도메인 해석을 다른 쪽에 맡길 수도 있습니다. 반대로 애플리케이션이 요청을 보내기 전에 이미 도메인을 해석해 IP를 전달했다면 코어는 여기 설정된 서버를 사용할 기회를 얻지 못할 수 있습니다. 시스템 DNS가 정상이라는 사실은 시스템의 질의 경로가 작동한다는 뜻일 뿐, 코어의 DNS도 같다는 뜻은 아닙니다.
최소 서버와 정적 매핑 예시
아래 설정 조각은 일반 DNS 서버 하나를 사용하고 문서용 예시 도메인에 정적 매핑을 추가합니다. 매핑 주소는 문서 예시용이며 실제 사이트를 제공하지 않습니다. 검증할 때는 DNS 응답만 확인하고 웹페이지 접속 여부를 판단하는 데 사용하지 마세요. 정적 매핑은 설정 구조를 보여 주기 위한 예시입니다. 많은 사이트 주소를 설정에 장기간 고정하는 것은 권장하지 않습니다. 서비스 주소가 바뀌면 고정 기록이 알아차리기 어려운 장애 원인이 될 수 있습니다.
{
"dns": {
"hosts": {
"example.org": "192.0.2.10"
},
"servers": [
"1.1.1.1"
]
}
}
hosts는 내장 해석기에서 사용할 정적 결과를 제공하고, servers는 상위 DNS 서버를 정의합니다. 서버 주소에 연결할 수 있는지는 현재 네트워크에 따라 달라지므로 예시 주소가 모든 환경에서 작동한다고 보장할 수 없습니다. 일반 DNS와 암호화 DNS는 전송, 인증서, 초기 해석 방식이 다릅니다. 전환하기 전에 선택한 서비스에 연결할 수 있는지 확인하고 해당 코어가 지원하는 설정 형식을 살펴보세요. 웹페이지 주소를 DNS 인터페이스 주소로 바로 사용하면 안 됩니다.
도메인별 DNS 지정과 결과 제한
서버를 객체로 작성하고 domains로 우선 일치시킬 도메인 범위를 지정할 수도 있습니다. 아래 예시에서는 예시 도메인에 전용 서버를 지정하고 나머지 질의는 기본 후보에 맡깁니다. 일치하는 서버가 실패했을 때 대체 서버로 전환되는지, 어떤 서버가 후보에 포함되는지는 코어 설정에 따라서도 달라집니다. 배열 앞에 있다는 이유만으로 항상 우선된다고 단정하지 말고 도메인 일치, 후보 선택, 실패 시 대체의 각 단계를 구분해 이해하세요.
{
"dns": {
"servers": [
{
"address": "1.1.1.1",
"domains": [
"domain:example.org"
]
},
"8.8.8.8"
]
}
}
일부 설정에서는 expectIPs로 허용할 해석 결과를 추가로 제한합니다. 이 항목은 결과를 필터링할 뿐 잘못된 응답을 자동으로 올바르게 고쳐 주지 않습니다. 조건이 지나치게 엄격하면 서버가 주소를 반환해도 코어가 결과를 거부해 해석 실패처럼 보일 수 있습니다. 데이터베이스 참조로 결과를 제한하면 데이터 파일 의존성도 추가됩니다. 문제를 점검할 때는 먼저 결과 제한 없이 해석한 뒤 조건을 하나씩 복구하며 영향을 확인하세요.
라우팅의 domainStrategy와 DNS 설정은 특히 혼동하기 쉽습니다. 필요할 때 해석하는 방식을 사용하면 출구를 결정하기 전에 첫 연결에서 도메인 해석을 기다릴 수 있습니다. 상위 DNS가 아직 설정되지 않은 프록시 경로에 의존한다면 순환 의존성이 생기는지도 확인해야 합니다. 원격 서버 자체가 도메인 이름을 사용한다면 초기 해석 방법도 필요합니다. 서버 주소 해석과 일반 서비스 도메인 해석을 따로 검증하고 테스트 사이트 하나의 결과만 보지 마세요.
IPv4와 IPv6 결과도 각각 확인해야 합니다. 네트워크에서 IPv6 주소를 받는다고 해서 해당 출구가 IPv6로 완전히 연결된다는 뜻은 아닙니다. 애플리케이션이 특정 주소 유형을 먼저 시도한 뒤 대체 경로로 전환하면서 간헐적으로 지연될 수 있습니다. 연결이 느리다는 이유만으로 한 주소 체계를 영구적으로 비활성화하지 마세요. 같은 대상을 사용해 해석 결과와 연결 경로를 각각 검증한 다음 코어가 지원하는 질의 전략을 조정해야 합니다. 네트워크 경로 문제를 도메인 분류 문제로 잘못 기록하지 않도록 주의하세요.
TUN 환경에서는 시스템 DNS가 가상 네트워크 인터페이스로 들어가는 방식이나 DNS 가로채기·리디렉션 여부도 확인해야 합니다. 이런 동작은 이 페이지의 최상위 DNS 객체만으로 설명할 수 없으며 클라이언트가 생성한 TUN 설정을 함께 살펴봐야 합니다. 관련 원리는 v2rayN TUN 모드 안내를 참고하세요. DNS 관련 설정을 바꾼 뒤에는 애플리케이션 연결을 새로 만들고 캐시의 영향을 고려해 테스트하세요. 이전 해석 결과로 새 설정을 평가하지 않도록 주의해야 합니다.
6. policy 등급 정책, 시간 제한 및 통계
정책 등급은 라우팅 우선순위가 아닙니다
policy는 연결 동작과 통계 관련 정책을 정의하며 levels는 사용자 등급별로 설정을 구성합니다. 여기서 말하는 등급은 구독 그룹 번호나 라우팅 규칙의 실행 우선순위가 아닙니다. 일부 프로토콜의 사용자 설정에서 level을 지정하면 해당 정책과 연결됩니다. 별도로 지정하지 않은 경우에는 대개 기본 등급을 사용합니다. 현재 사용자가 참조하지 않는 등급을 바꿔도 연결이 달라지지 않을 수 있으므로 먼저 정책이 누구에게 적용되는지 확인하세요.
아래 설정 조각은 등급 0에 연결 단계와 유휴 처리 매개변수를 지정합니다. 값의 단위는 초이며 항목 간 관계를 보여 주기 위한 것으로 모든 네트워크에 적합한 권장 설정은 아닙니다. 최상위 policy 객체에 합쳐 사용하세요. 이미 다른 등급이나 시스템 통계 설정이 있다면 기존 항목을 유지하며 수정해야 합니다. 예시 전체를 덮어쓴 뒤 사라진 기능을 코어 동작의 변화로 오해하지 마세요.
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5
}
}
}
}
연결 수명 주기의 네 가지 시간 필드
handshake는 인바운드 연결이 핸드셰이크를 완료할 때까지 기다리는 시간을 제한합니다. 모든 원격 연결 단계에 공통으로 적용되는 시간 초과는 아닙니다. 이 값을 늘려도 인증 정보 오류나 전송 방식 불일치는 해결되지 않습니다. 연결이 성립된 뒤 멈춘다면 유휴 정책, 원격 서버 상태, 애플리케이션 동작을 확인해야 합니다. 로그에 ‘시간 초과’라는 말이 있다고 모두 이 필드가 원인인 것은 아니므로 오류가 발생한 단계를 함께 확인하세요.
connIdle은 데이터 전송이 없는 상태가 지속되는 시간을 지정합니다. 너무 짧게 설정하면 오랜 시간 연결을 유지하면서 드물게 데이터를 주고받는 세션에 영향을 줄 수 있고, 너무 길면 더 이상 필요하지 않은 연결을 늦게 해제할 수 있습니다. 메신저, 원격 터미널, 일반 웹페이지는 연결 특성이 서로 다르므로 웹페이지를 한 번 불러온 결과만으로 적절성을 판단하지 마세요. 값을 조정한 뒤에는 문제가 있었던 애플리케이션을 실제로 문제가 발생하는 대기 시간까지 관찰하세요.
uplinkOnly와 downlinkOnly는 각각 연결이 한 방향으로만 데이터를 전송하는 단계의 대기 동작에 관여합니다. 업로드·다운로드 속도 제한이나 라우팅 조건이 아닙니다. 일부 애플리케이션은 전송이 끝난 뒤에도 응답을 오래 기다리므로 단방향 단계의 처리 방식에 따라 연결 종료 시점이 달라질 수 있습니다. 응답이 일찍 끊긴다면 이 필드부터 바꾸지 말고 연결 상태와 로그를 확인하세요. 서버가 먼저 연결을 종료한 일을 클라이언트 정책 탓으로 돌리지 않도록 주의해야 합니다.
| 필드 | 대상 단계 | 대신할 수 없는 항목 |
|---|---|---|
handshake | 인바운드 핸드셰이크 대기 | 프로토콜 및 인증 오류 수정 |
connIdle | 데이터 전송이 없는 유휴 시간 | 애플리케이션 연결 유지 기능 |
uplinkOnly | 상향 전송만 남은 단계 | 업로드 속도 제한 |
downlinkOnly | 하향 전송만 남은 단계 | 다운로드 속도 제한 |
통계 스위치만으로 통계 화면이 제공되지는 않습니다
코어 통계가 필요하다면 일반적으로 최상위 stats 객체와 policy.system 아래의 통계 스위치를 함께 설정합니다. 아래 예시는 인바운드와 아웃바운드의 전체 트래픽 통계를 켜는 방법만 보여 줍니다. 그래픽 통계 화면을 자동으로 만들거나 클라이언트가 해당 카운터를 읽는다는 뜻은 아닙니다. 값을 읽으려면 클라이언트 구현이나 관련 인터페이스도 필요합니다. 조회 방법이 없다면 통계 필드만 추가해도 화면에 새 항목이 나타나지 않습니다.
{
"stats": {},
"policy": {
"system": {
"statsInboundUplink": true,
"statsInboundDownlink": true,
"statsOutboundUplink": true,
"statsOutboundDownlink": true
}
}
}
앞에서 설명한 등급 정책도 필요하다면 levels와 system을 하나의 policy 객체에 합쳐야 합니다. 이름이 같은 객체를 두 개 복사하면 안 됩니다. 사용자별 통계에는 프로토콜과 사용자 식별자 등의 연결 조건이 필요하므로 시스템 통계 스위치를 사용자 통계 설정으로 오해하지 마세요. 카운터를 비교할 때는 프로세스 재시작, 세션 종료, 클라이언트의 집계 방식을 고려해야 합니다. 화면에서 읽은 두 값의 차이가 통계 주기만 달라서 생길 수도 있습니다.
버퍼와 리소스 관련 옵션은 추가 최적화 범위에 해당합니다. 리소스 병목의 근거가 없다면 일반적인 최적화라고 알려진 설정을 그대로 복사하기보다 코어 기본값을 유지하세요. 버퍼를 늘리면 메모리 사용량이 늘 수 있고 줄이면 특정 트래픽에 영향을 줄 수 있습니다. 결과는 동시 연결 수와 애플리케이션의 읽기·쓰기 방식에 따라서도 달라집니다. 먼저 프로토콜, 라우팅, DNS가 올바른지 확인한 다음 병목 하나만 비교 테스트하면 정책을 한꺼번에 많이 추가하는 것보다 결과를 해석하기 쉽습니다.
정책 문제를 점검할 때는 안정적인 관찰 시간을 확보하세요. 문제가 발생한 애플리케이션, 유휴 시간, 연결 단계를 기록한 뒤 필드 하나만 변경하고 영향을 받는 연결을 다시 만들어 테스트합니다. 정책을 바꿔도 차이가 없다면 실제 로드 파일, 사용자 등급, 현재 실행 중인 코어를 확인하세요. 실패를 늦추기 위해 시간 제한을 계속 늘리지 마세요. 원인이 원격 서버의 거부나 연결할 수 없는 주소라면 대기 시간만 길어질 뿐 연결이 복구되지는 않습니다.
7. v2rayN 생성 설정과 사용자 지정 설정
지속 설정과 실행 결과물을 구분해 관리하기
v2rayN은 노드, 구독 그룹, 라우팅, 매개변수 설정을 클라이언트에서 관리할 수 있는 데이터로 저장한 뒤 선택된 코어에 맞춰 실행 설정을 생성합니다. 생성된 파일은 실행 결과물에 가까우며 장기적인 편집 위치가 아닐 수 있습니다. 생성 결과를 직접 수정하면 서버를 전환하거나 다시 불러오거나 재시작할 때 변경 사항이 덮어써질 수 있습니다. 오래 유지할 설정은 해당 화면에서 수정하는 것이 우선입니다. JSON을 직접 완전히 관리해야 한다면 사용자 지정 설정 항목을 어떻게 관리할지 확인하세요.
사용하기 전에 현재 작업 모드를 확인하세요. 일반 노드 항목은 보통 클라이언트가 인바운드, 아웃바운드, 공통 설정을 조합합니다. 사용자 지정 설정 항목은 파일 내용을 더 많이 그대로 유지할 수 있습니다. 두 모드에서 메뉴 작업이 적용되는 계층은 같지 않을 수 있습니다. 화면에서 라우팅 프리셋을 바꾸면 임의의 사용자 지정 JSON까지 다시 작성된다고 가정하지 마세요. 설정이 적용되는지 확인하려면 화면 버튼의 선택 상태만 볼 것이 아니라 다시 불러온 뒤 실제 실행 설정을 확인해야 합니다.
공통 매개변수·노드 매개변수·구독 출처
로컬 리스닝 포트와 코어 선택 같은 공통 매개변수는 관련 설정 화면에서 찾을 수 있습니다. 구체적인 메뉴 이름은 클라이언트 화면에 따라 달라집니다. 원격 주소, 인증, 전송 방식은 노드 매개변수이고 구독 주소와 업데이트 주기는 구독 그룹에 속합니다. 문제를 올바른 설정 위치에서 다루는 것이 중요합니다. 업데이트 주기는 핸드셰이크 프로토콜을 바꾸지 않고, 시스템 프록시 설정은 원격 서버를 수정하지 않으며, 라우팅 프리셋을 바꾼다고 구독 내용이 다시 다운로드되는 것도 아닙니다.
구독을 업데이트하면 원본 항목의 연결 정보가 덮어써질 수 있으므로 구독 노드를 장기간 직접 수정할 때는 다음 업데이트의 영향을 고려해야 합니다. 임시 테스트라면 먼저 별도로 관리할 수 있는 항목으로 복사하고 용도를 명확히 표시하세요. 서비스 제공자가 매개변수를 변경했다면 기존 항목을 반복해서 수정하는 대신 원본 정보를 업데이트하세요. 구독을 가져올 수 없다면 주소, 네트워크, 시간 문제부터 확인하세요. 구체적인 점검 방법은 구독 업데이트 실패 문제 해결을 참고하세요.
| 변경 대상 | 우선 관리할 위치 | 검증 항목 |
|---|---|---|
| 로컬 프록시 진입점 | 클라이언트 공통 매개변수 | 실행 포트와 애플리케이션 설정 일치 여부 |
| 원격 연결 매개변수 | 노드 항목 또는 구독 출처 | 생성된 아웃바운드와 서버 설정의 일치 여부 |
| 웹사이트별 트래픽 분기 | 라우팅 규칙 설정 | 규칙 순서와 아웃바운드 태그 확인 |
| JSON 전체를 직접 제어 | 사용자 지정 설정 항목 | 실제 로드 경로와 코어의 일치 여부 |
코어 전환은 프로그램 이름만 바꾸면 끝나지 않습니다
v2rayN은 클라이언트에서 제공하는 기능으로 여러 코어를 관리할 수 있지만, 항목을 전환할 수 있는지는 사용 중인 프로토콜과 전송 기능에 따라 달라집니다. Xray 전용 설정을 V2Fly에 넘겼을 때 JSON 문법이 올바르다는 이유만으로 사용할 수 있다고 판단하지 마세요. sing-box의 설정 객체 구조는 다르므로 이 페이지의 조각을 그대로 재사용할 수 없습니다. 전환 전에 클라이언트가 호환되는 형식으로 다시 생성하는지 확인하거나 사용자 지정 설정에 맞는 별도 파일을 준비하세요.
Windows의 WPF 인터페이스와 크로스 플랫폼 데스크톱 인터페이스는 메뉴 구성, 트레이, 시스템 통합 방식이 다를 수 있지만 인바운드, 아웃바운드, 라우팅 같은 개념은 공통으로 적용할 수 있습니다. macOS와 Linux에서는 시스템 프록시와 권한 처리의 차이, 특히 TUN 관련 동작도 확인해야 합니다. 설치 파일 선택은 데스크톱 버전과 WPF 버전의 차이를 참고하세요. 현재 플랫폼에 맞지 않는 패키지를 설치해 메뉴 위치를 맞추려 하지 마세요.
Android의 v2rayNG와 v2flyNG는 각 코어와 인터페이스에 맞게 설정을 관리해야 합니다. 데스크톱 메뉴 경로를 그대로 따라 하지 마세요. 링크나 구독을 가져올 때는 클라이언트에서 지원하는 프로토콜과 매개변수를 확인하세요. 완전한 JSON을 가져오는 경우에는 해당 가져오기 형식을 클라이언트가 명시적으로 지원하는지도 확인해야 합니다. 구독 링크, 단일 노드 공유 링크, 완전한 설정 파일은 서로 다른 자료입니다. 모두 텍스트로 저장할 수 있더라도 서로 대신 사용할 수는 없습니다.
사용자 지정 설정에는 변경 항목, 예상 동작, 되돌리는 방법을 적은 간단한 변경 기록을 남기는 것이 좋습니다. 이 기록은 로컬에 보관하면 되며 비공개 설정을 공개된 곳에 올릴 필요는 없습니다. 문제 해결 자료를 공유할 때는 객체 구조, 태그, 오류 정보는 유지하되 인증 정보, 비공개 서버 주소, 구독 링크는 삭제하세요. 인증 부분만 가려서는 충분하지 않을 수 있습니다. 다른 항목에서도 서버 정보나 개인 사용 패턴이 노출될 수 있습니다.
설정은 단일 출처에서 관리해야 합니다. 인터페이스가 관리하는 내용은 인터페이스에서 수정하고, 사용자 지정 파일이 관리하는 내용은 파일에서 수정하세요. 두 설정이 계속 서로 덮어쓰게 두면 안 됩니다. 변경할 때마다 먼저 생성 결과를 확인하고, 다음으로 프로세스 로그를 살펴본 뒤 애플리케이션을 테스트하세요. 화면에 표시된 설정과 실제 동작이 다르면 설정이 로드되는 경로부터 확인해야 합니다. 연결만 필요한 사용자라면 모든 최상위 객체를 익히기보다 빠른 시작 가이드로 돌아가도 됩니다.
8. 설정 검증, 로그 확인 및 되돌리기
문법·로드·진입점·출구 순서로 점검하기
설정 문제를 해결할 때는 먼저 어느 단계에서 실패했는지 판단해야 합니다. JSON 문법 오류가 있으면 파일을 올바르게 파싱하지 못합니다. 지원하지 않는 항목이나 존재하지 않는 참조는 로드 단계에서 오류를 일으킬 수 있고, 포트가 사용 중이면 리스닝에 실패합니다. 원격 핸드셰이크 문제는 보통 요청이 들어온 뒤에 발생합니다. 단계마다 해결 방법이 다릅니다. 마지막 줄의 ‘시작 실패’만 보지 말고 실제 의미가 있는 첫 오류를 확인하세요. 뒤에 나오는 메시지는 앞선 오류의 결과인 경우가 많습니다.
편집 전에 현재 정상 작동하는 파일이나 클라이언트 설정을 백업하고 이번에 수정할 객체를 하나만 정해 기록하세요. 편집을 마치면 괄호, 쉼표, 값 유형, 중복 키를 확인한 뒤 클라이언트에서 다시 불러와 코어가 정상적으로 시작되는지 살펴봅니다. 클라이언트에 설정 보기나 로그 기능이 있다면 방금 수정한 항목이 표시되는지도 확인하세요. 실패한 뒤 새 규칙을 계속 추가하지 마세요. 가장 최근의 정상 상태로 되돌아가야 어떤 변경으로 차이가 생겼는지 확인할 수 있습니다.
명확한 로컬 요청으로 진입점을 검증하기
아래 두 명령은 필요한 옵션을 지원하는 curl을 사용해 로컬 SOCKS와 HTTP 진입점을 각각 테스트합니다. 2장에서 설명한 포트를 사용하며 해당 설정이 실제로 실행 중일 때만 사용할 수 있습니다. SOCKS 명령의 socks5-hostname은 대상 도메인 처리를 프록시 측에 맡깁니다. 로컬에서 해석하도록 바꾸면 테스트하는 DNS 경로가 달라집니다. 테스트 사이트에 연결할 수 있는지는 현재 네트워크와 출구에 따라 다르므로 명령 실행만으로 성공을 보장하지는 않습니다.
curl --proxy socks5h://127.0.0.1:10808 --head https://example.org/
curl --proxy http://127.0.0.1:10809 --head https://example.org/
로컬 포트에 연결할 수 없다는 오류가 나오면 원격 설정부터 바꾸지 말고 프로세스, 리스닝 주소, 포트를 확인하세요. 로컬 연결이 성립한 뒤 실패한다면 대상 해석, 라우팅 선택, 아웃바운드 핸드셰이크를 점검합니다. 테스트에서는 가능한 한 같은 대상과 진입점을 유지하고 한 번에 조건 하나만 바꾸세요. 브라우저 캐시, 시스템 프록시, 명령줄 직접 연결을 섞으면 서로 다른 경로를 거치므로 겉으로 같은 접속처럼 보여도 결과를 비교할 수 없습니다.
로그 상세도는 임시로 높이고 자세한 기록을 장기간 유지하지 마세요
일상적인 사용에는 기본 경고 수준이 적합합니다. 라우팅이나 연결 문제를 점검할 때는 일시적으로 info 수준까지 높일 수 있습니다. 아래 설정 조각은 파일 경로를 지정하지 않고 오류 로그의 상세도만 조정하므로 먼저 클라이언트의 로그 화면에서 확인할 수 있습니다. 파일에 기록하려면 디렉터리에 쓰기 권한이 있는지, 경로가 현재 운영체제 형식에 맞는지 확인하고 파일 용량도 살펴보세요. 로그에 대상 도메인과 연결 정보가 포함될 수 있으므로 공유하기 전에 민감한 내용을 확인하고 삭제해야 합니다.
{
"log": {
"loglevel": "info"
}
}
로그는 새로 만든 요청 하나를 기준으로 시간 순서에 따라 진입점 수신, 대상 식별, 아웃바운드 선택, 실패 위치를 확인하세요. 규칙이 일치하지 않으면 조건과 순서를 살펴보고, 태그가 없다면 참조를 확인합니다. 인증서 오류는 시간과 서버 신원을 점검하고, 데이터베이스 읽기 오류는 파일 경로와 카테고리를 확인하세요. 코어마다 오류 문구가 다를 수 있습니다. 인터넷에서 흔히 보는 오류 설명 하나만으로 판단하지 말고 해당 요청의 흐름을 함께 살펴보세요.
| 증상 | 우선 점검할 항목 | 다음 단계 |
|---|---|---|
| 설정을 불러오지 못함 | 문법, 항목 지원 여부, 태그 참조 | 최소한의 완전한 설정으로 축소 |
| 로컬 포트에 연결할 수 없음 | 프로세스, 리스닝 주소, 포트 사용 여부 | 애플리케이션의 프록시 진입점 확인 |
| 진입점은 정상이나 핸드셰이크 실패 | 아웃바운드 인증, 전송, 보안 매개변수 | 대상 아웃바운드만 따로 검증 |
| 일부 대상이 예상과 다른 출구를 사용함 | 대상 정보, 규칙 순서, 데이터베이스 | 일치하는 대상과 일치하지 않는 대상 비교 |
| 간헐적인 DNS 해석 실패 | 질의 경로, 캐시, 주소 체계 | 각 계층의 DNS 해석을 따로 테스트 |
복잡한 설정을 가장 효과적으로 되돌리는 방법은 계층별로 복원하는 것입니다. 먼저 1장의 로컬 직결 기본 구성을 확인한 다음 대상 아웃바운드를 추가하고, 소수의 라우팅 규칙을 복구한 뒤 마지막으로 DNS와 정책 변경을 적용하세요. GUI 클라이언트를 사용한다면 실행 파일 전체를 직접 교체할 필요 없이 별도 테스트 항목을 만들어 운영 항목을 그대로 유지할 수 있습니다. 복원 단계마다 새 연결을 만들고 결과를 기록해 기존 세션이 이전 출구를 계속 사용하는 바람에 판단이 흐려지지 않도록 하세요.
한 번 접속에 성공했다고 설정 전체가 올바른 것은 아닙니다. 직결되어야 하는 대상 하나, 다른 출구를 사용해야 하는 대상 하나, 장시간 유지해야 하는 애플리케이션을 최소한 테스트하세요. UDP나 TUN을 활성화했다면 해당 트래픽도 각각 검증해야 합니다. 검증 범위는 이번 변경 내용에 맞춰야 합니다. TCP 웹페이지가 정상이라고 해서 모든 트래픽이 정상이라고 판단하면 안 됩니다. 특정 애플리케이션에서만 문제가 생긴다면 자주 묻는 질문 및 문제 해결을 참고해 진입 방식에 따라 범위를 좁혀 보세요.
문제 해결을 마치면 적절한 로그 수준으로 되돌리고 임시 도메인 매핑과 테스트 규칙을 제거한 뒤 클라이언트를 다시 시작해도 같은 설정이 불러와지는지 확인하세요. 최종적으로 유효한 변경 사항은 생성 파일에만 남기지 말고 장기적으로 관리하는 원본에 반영해야 합니다. 코어의 계보와 역할을 알아보려면 Project V, V2Fly, Xray의 생태계 관계를 참고하세요. 설정을 관리하는 목적은 항목을 계속 늘리는 것이 아니라 각 동작을 설명하고 다시 검증하며 되돌릴 수 있게 하는 것입니다.