V2Ray 설정 파일 가이드
데이터 흐름에 따라 항목을 확인하세요: 로컬 프로그램 → 인바운드 → 라우팅 → 아웃바운드. 이어서 DNS, 전송 방식, 정책을 점검합니다.
처음 사용하는 경우 사용 가이드의 빠른 시작 과정을 먼저 완료하세요. 이 페이지에서는 설정을 가져온 뒤 항목이 어디에 있는지, 어떤 설정이 서로 영향을 주는지, 변경 사항이 실제로 적용됐는지 확인하는 방법을 살펴봅니다. 데스크톱 클라이언트로는 v2rayN을 권장합니다. 설치 파일은 다운로드 센터에서 확인하세요.
1. JSON 구조와 설정 범위
클라이언트 데이터와 커널 설정 구분하기
v2rayN에 저장된 구독 그룹, 인터페이스 옵션, 서버 정보는 클라이언트 데이터입니다. 연결을 시작하면 클라이언트가 선택된 서버, 라우팅 프리셋, 매개변수 설정을 바탕으로 커널 설정 파일을 생성합니다. 커널이 읽는 것은 이 파일이지 인터페이스 데이터베이스가 아닙니다. 실행 디렉터리의 임시 설정을 직접 수정하면 서버를 바꾸거나 클라이언트를 다시 시작할 때 덮어써질 수 있습니다. 따라서 먼저 수정 대상이 인터페이스 옵션인지, 라우팅 템플릿인지, 독립형 사용자 설정인지 확인하세요.
v2rayNG도 설정 가져오기, 서버 선택, 커널 실행을 담당하며, v2flyNG는 V2Fly 커널을 사용하는 Android 대안입니다. 메뉴 이름이 비슷하다고 해서 세 클라이언트의 내보내기 설정이 완전히 같다고 가정하면 안 됩니다. 로그를 확인할 때는 실제로 실행된 커널 이름을 기록하고, 설정을 살펴볼 때는 이전에 내보낸 사본이 아니라 이번 실행에 사용된 파일인지 확인하세요. 설정 경로는 플랫폼과 클라이언트 설정에 따라 달라지므로 다른 기기의 고정 경로를 그대로 적용하지 마세요.
최상위 객체의 역할
기존 JSON 설정의 최상위 요소는 객체입니다. inbounds와 outbounds는 각각 하나 이상의 인바운드와 아웃바운드를 담는 배열이고, routing, dns, policy는 보통 객체입니다. 항목은 올바른 계층에 있어야 합니다. 특정 아웃바운드의 settings를 최상위에 둘 수는 없습니다. 중괄호는 객체, 대괄호는 배열을 나타냅니다. 키와 문자열은 영문 큰따옴표로 감싸고, 숫자와 불리언 값에는 따옴표를 붙이지 않습니다.
| 최상위 항목 | 역할 | 자주 하는 실수 |
|---|---|---|
log | 접속 기록, 오류, 로그 수준 | 로그 수준을 연결 정책으로 오해 |
inbounds | 로컬 리스닝과 인바운드 프로토콜 | 로컬 포트를 원격 포트로 착각 |
outbounds | 연결 아웃바운드와 원격 매개변수 | 태그 누락 또는 잘못된 프로토콜 구조 |
routing | 트래픽 매칭과 아웃바운드 선택 | 규칙의 적용 순서 무시 |
dns / policy | DNS 조회와 연결 동작 | 시스템 네트워크를 자동으로 제어한다고 오해 |
로컬 문제 진단용 전체 기준 설정
아래 설정은 로컬 SOCKS 트래픽만 받아 대상에 직접 연결합니다. 원격 프록시에 연결하지 않으며 시스템 프록시도 자동으로 설정하지 않습니다. 커널이 시작되는지, 로컬 포트가 요청을 받는지 먼저 확인할 때 유용합니다. 별도 파일로 저장할 경우 UTF-8 인코딩을 사용하세요. 설명, 코드 펜스, 줄 번호는 파일에 넣지 마세요. 클라이언트가 같은 포트를 사용 중이라면 기존 커널 프로세스를 먼저 종료해야 합니다.
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
이 기준 설정에는 라우팅과 원격 서버를 의도적으로 넣지 않아 한 번에 바뀌는 변수를 줄였습니다. 요청이 성공하면 로컬 리스닝과 직접 연결 경로가 대체로 정상이라는 뜻이지, 구독 서버가 작동한다는 의미는 아닙니다. 아웃바운드를 추가할 때는 기본 경로로 사용할 항목을 첫 번째에 놓고 규칙을 조금씩 추가하세요. 단계마다 작동하는 파일을 보관하고, 오류가 생기면 설정을 계속 덧붙이기보다 마지막 변경 사항을 되돌리세요.
표준 JSON에서는 끝에 붙는 쉼표와 주석을 허용하지 않습니다. 일부 커널 입력 방식에서 확장 문법을 지원하더라도 도구 간 설정을 옮길 때는 이에 의존하지 않는 편이 좋습니다. 중복 키도 제거하세요. 파서에 따라 중복 키를 처리하는 방식이 다를 수 있습니다. 편집기의 문법 검사는 괄호나 따옴표 같은 형식 오류를 찾을 뿐, 현재 커널이 프로토콜 항목을 지원하는지 또는 서버 주소에 실제로 연결할 수 있는지는 판별하지 못합니다.
2. inbounds: 로컬 리스닝과 트래픽 진입점
리스닝 주소와 포트의 역할
인바운드는 애플리케이션이 커널에 트래픽을 전달하는 방식을 정합니다. listen은 바인딩할 로컬 주소, port는 연결을 기다리는 로컬 포트, protocol은 인바운드에서 사용할 프로토콜입니다. 127.0.0.1에서 리스닝하면 로컬 프로그램만 사용할 수 있습니다. 0.0.0.0에 바인딩하면 모든 IPv4 인터페이스에서 연결을 받으므로 같은 네트워크의 기기가 접근할 수 있습니다. 접근 범위를 넓히면 방화벽, 인증, 네트워크 신뢰도도 함께 고려해야 합니다.
로컬 리스닝 포트와 서버 포트가 같아야 할 이유는 없습니다. 브라우저는 로컬 포트에 연결하고, 커널은 별도로 원격 서버 포트에 연결합니다. 포트가 이미 사용 중이면 시작 로그에 바인딩 실패가 표시되는 경우가 많습니다. 먼저 포트를 점유한 프로세스를 찾아 종료할지, 포트를 바꿀지 결정하세요. 명령에 지정된 포트만 바꾸고 클라이언트의 리스닝 설정을 그대로 두면 연결은 여전히 거부됩니다.
SOCKS와 HTTP 인바운드 선택
SOCKS 인바운드는 SOCKS 프록시를 지원하는 애플리케이션에 적합하고, HTTP 인바운드는 HTTP 프록시 주소를 입력하는 프로그램에 적합합니다. 둘은 서로 다른 프로토콜이므로 포트에 연결된다는 이유만으로 혼용할 수 없습니다. 아래 예시는 인바운드를 별도 포트에서 리스닝하고 서로 다른 태그를 붙여 라우팅과 로그에서 출처를 구별하기 쉽게 구성합니다. 별도의 2포트 구성 예시일 뿐, 현재 클라이언트가 반드시 같은 방식으로 설정을 생성한다는 뜻은 아닙니다.
{
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
},
{
"tag": "local-http",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
이 설정으로 HTTP 인바운드를 테스트하려면 http://127.0.0.1:10809를 입력하세요. SOCKS 인바운드를 테스트할 때는 해당 SOCKS 주소를 사용하면 됩니다. 일부 클라이언트는 하나의 포트에서 여러 종류의 프록시 요청을 식별하는 혼합 인바운드를 생성하지만, 지원 여부는 커널과 설정 생성 방식에 따라 다릅니다. 문제를 해결할 때는 실제 설정을 확인하고, 튜토리얼 화면만 보고 포트의 프로토콜을 추측하지 마세요.
UDP와 트래픽 탐지의 범위
SOCKS의 udp를 활성화하면 해당 인바운드에서 프로토콜에 맞는 UDP 전달 요청을 처리할 수 있습니다. 애플리케이션도 SOCKS UDP를 지원해야 하며, 이후 아웃바운드와 원격 연결 경로에서도 해당 기능을 지원해야 합니다. 시스템의 모든 UDP 데이터를 자동으로 가져오는 설정은 아닙니다. 브라우저의 일반 HTTP 프록시 요청과 일부 애플리케이션의 UDP 통신은 서로 다른 경로를 사용할 수 있으므로 따로 확인해야 합니다.
sniffing은 커널에 전달된 트래픽에서 HTTP 호스트명이나 TLS 핸드셰이크의 도메인처럼 대상 정보를 식별해 라우팅 판단에 활용합니다. 트래픽을 복호화하는 기능은 아니며 모든 요청에서 도메인을 찾아내는 것도 아닙니다. 일부 암호화 핸드셰이크, IP 주소만 사용하는 서비스, 비표준 프로토콜에서는 단서를 얻지 못할 수 있습니다. 따라서 ‘탐지 사용’을 올바른 DNS 및 라우팅 설계의 대안으로 삼지 마세요.
destOverride는 탐지 결과를 바탕으로 대상 주소를 처리하는 설정이므로 로그에 이름을 추가하는 것만으로 끝나지 않습니다. 기존 대상이 특정 IP인데 탐지된 도메인을 사용하면 이후 DNS 조회와 연결 대상이 달라질 수 있습니다. 탐지를 켰을 때만 특정 사이트에 문제가 생긴다면 같은 요청으로 설정을 켜고 끈 결과를 비교하고, 서로 다른 규칙이 적용됐는지 확인하세요. 탐지, DNS, 서버 설정을 동시에 바꾸면 원인을 파악하기 어렵습니다.
LAN 공유와 시스템 프록시 적용은 다릅니다
휴대폰이나 TV에서 컴퓨터의 프록시를 공유하려면 기기에 컴퓨터의 LAN 주소를 입력해야 합니다. 컴퓨터에서만 통하는 루프백 주소를 입력하면 안 됩니다. 해당 인바운드 연결을 허용하고 접근 가능한 출발지 네트워크도 제한하세요. 공용 네트워크에서 인증되지 않은 인바운드를 노출해서는 안 됩니다. 자세한 설정은 LAN 연결 허용 및 프록시 공유 방법을 참고하세요. 변경 후에는 같은 컴퓨터가 아니라 다른 기기에서 테스트해야 합니다.
일반 SOCKS 및 HTTP 인바운드는 애플리케이션이 프록시를 직접 사용해야 합니다. 시스템 프록시 스위치는 이를 지원하는 프로그램에 프록시 설정을 알릴 뿐입니다. TUN은 가상 네트워크 인터페이스, 라우팅, 권한이 관련되므로 일반 인바운드를 추가하는 것만으로 같은 효과를 낼 수 없습니다. 브라우저는 작동하지만 터미널에서 프록시를 사용하지 않는다면 프로그램이 시스템 설정이나 환경 변수를 읽는지 확인하세요. 인바운드 로그가 전혀 없다면 원격 프로토콜보다 먼저 트래픽 진입 경로를 점검하세요.
3. outbounds: 아웃바운드, 태그, 원격 연결
아웃바운드 객체와 기본 아웃바운드
아웃바운드는 요청을 받은 커널이 어떤 방식으로 대상에 연결할지 설명합니다. 각 객체의 protocol에 따라 settings에 허용되는 항목이 달라지므로 이름이 같다는 이유로 다른 프로토콜의 설정을 그대로 복사하면 안 됩니다. tag는 라우팅에서 참조하는 로컬 식별 태그입니다. 서버로 전송되지 않으며 구독에 표시되는 이름도 아닙니다. 짧고 안정적인 태그를 사용하고 인터페이스 메모와 설정 참조를 따로 관리하는 것이 좋습니다.
규칙이 적용되지 않으면 기존 설정에서는 보통 아웃바운드 배열의 첫 번째 항목을 사용합니다. 따라서 배열 순서를 바꾸면 명시적으로 매칭되지 않은 많은 트래픽의 경로가 달라질 수 있습니다. 프록시 아웃바운드를 첫 번째에 놓고 사설 주소는 직접 연결하는 방식과, 직접 연결을 첫 번째에 놓고 일부 도메인만 프록시로 보내는 방식은 기본 동작이 서로 다릅니다. 설정을 옮기기 전에 원하는 기본 동작부터 정하고 규칙을 확인하세요. 태그가 모두 있는지만 봐서는 안 됩니다.
직접 연결과 차단: 기본 아웃바운드 두 가지
freedom은 로컬 네트워크를 통해 대상에 연결합니다. 도메인 조회가 필요 없다는 뜻도, 대상에 반드시 연결된다는 뜻도 아닙니다. blackhole은 선택된 트래픽을 차단합니다. 이를 첫 번째에 잘못 배치하면 규칙에 맞지 않는 요청도 차단될 수 있습니다. 아래 예시는 라우팅의 기본 구성 요소로 사용할 수 있습니다. 태그 두 개는 각각 직접 연결과 차단을 나타내며, 원격 프록시 연결은 포함하지 않습니다.
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
라우팅의 outboundTag는 여기서 사용하는 태그와 철자, 대소문자, 하이픈까지 정확히 같아야 합니다. 태그를 바꾸면 참조하는 모든 위치도 함께 찾아 수정하세요. 여러 아웃바운드에 같은 태그를 붙이면 설정을 읽고 문제를 찾기 어려워지므로 분류 이름처럼 중복 사용하지 않는 것이 좋습니다. 참조 대상이 없는 경우 설정을 불러올 때 오류가 발생할 수 있고, 일부 조합은 요청을 처리할 때 문제가 드러나기도 합니다.
로컬 업스트림으로 아웃바운드 구조 이해하기
아래 아웃바운드는 요청을 로컬의 다른 SOCKS 서비스로 전달합니다. 원격 계정 없이 서버 목록의 중첩 구조를 설명하기 위한 예시이며, 127.0.0.1:2080에서 실제 서비스가 리스닝 중일 때만 작동합니다. 업스트림 포트를 현재 커널의 인바운드로 되돌리면 트래픽 루프가 생길 수 있습니다. 별도로 테스트하려면 먼저 업스트림 서비스 자체가 정상인지 확인하세요.
{
"outbounds": [
{
"tag": "upstream",
"protocol": "socks",
"settings": {
"servers": [
{
"address": "127.0.0.1",
"port": 2080
}
]
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
VMess, VLESS, Trojan, Shadowsocks는 인증 구조가 서로 다릅니다. 서버 주소, 포트, 사용자 식별자 또는 비밀번호, 암호화 방식은 서버 측에서 제공한 설정을 사용해야 합니다. protocol 이름만 바꿔서 다른 프로토콜로 변환할 수는 없습니다. 프로토콜 매개변수 외에도 전송 방식과 TLS 조건이 맞아야 할 수 있습니다. 클라이언트에서 가져오기에 성공했다는 것은 링크를 읽을 수 있다는 뜻일 뿐, 원격 인증과 전송 방식까지 일치한다는 의미는 아닙니다.
연결 실패를 단계별로 구분하기
원격 주소가 도메인이라면 프록시 연결을 시작하기 전에 먼저 해당 주소를 조회해야 하는 경우가 많습니다. 이 조회를 아직 연결되지 않은 프록시에 의존하도록 설정하면 순환 의존성이 생깁니다. 연결 로그의 DNS 조회 실패, 연결 시간 초과, 연결 거부, 인증 실패, TLS 핸드셰이크 실패는 각기 다른 단계를 가리킵니다. 여러 아웃바운드 매개변수를 연달아 바꾸기보다 오류가 발생한 단계부터 확인하세요.
다단계 전달을 구성할 때는 현재 커널에서 지원하는 아웃바운드 체인 항목과 적용 범위를 확인하고, 다른 커널의 예시를 그대로 합치지 마세요. 로컬 업스트림 리스너, 중간 아웃바운드, 최종 아웃바운드마다 실패 지점이 있습니다. 경로가 길수록 각 단계를 따로 검증해야 합니다. 일반적인 구독 사용자는 클라이언트가 생성한 단일 아웃바운드를 유지하고, 추가 단계가 필요한 이유를 명확히 알 때만 구성을 복잡하게 만드세요.
구독을 업데이트해도 서버 정보만 바뀌고 사용자 설정에 남아 있는 이전 주소, 인증 매개변수, 태그는 그대로일 수 있습니다. 인터페이스에는 업데이트된 것으로 표시되지만 연결이 이전 정보를 사용한다면 현재 선택된 설정 유형과 시작 로그를 확인하세요. 설정을 공유할 때는 인증 정보, 구독 주소, 개인 계정과 연결될 수 있는 항목을 삭제하세요. 구조 문제를 논의하는 데는 계층, 프로토콜 이름, 오류 단계만으로도 대개 충분합니다.
4. routing: 규칙 순서와 아웃바운드 선택
먼저 매칭하고, 그다음 아웃바운드를 선택합니다
라우팅은 서버 목록이 아니라 커널에 들어온 요청을 판별하는 설정입니다. 규칙은 대개 배열 순서대로 확인하며, 하나가 일치하면 해당 아웃바운드를 선택하고 뒤의 규칙은 더 확인하지 않습니다. 따라서 범위가 넓은 규칙을 앞에 두면 더 구체적인 규칙이 적용되지 않을 수 있습니다. 설정을 읽을 때는 첫 규칙부터 순서대로 결과를 따라가세요. 도메인 규칙과 IP 규칙을 따로 모두 살펴본 뒤 결과를 추측해서는 안 됩니다.
한 규칙 안에서 서로 다른 유형의 조건은 보통 모두 충족해야 합니다. 같은 유형에 여러 값을 넣으면 그중 하나와 일치하면 됩니다. 예를 들어 inboundTag와 domain을 함께 지정하면 특정 인바운드에서 들어오고 대상 도메인이 조건에 맞아야 한다는 뜻이지, 둘 중 하나만 일치하면 된다는 뜻이 아닙니다. 서로 독립적인 두 상황을 표현하려면 규칙을 나누세요. 태그 조건은 브라우저 인바운드와 다른 애플리케이션 인바운드를 구분할 때 특히 유용합니다.
읽기 쉬운 라우팅 규칙 예시
아래 예시는 3장의 direct 및 block 아웃바운드가 필요합니다. 예시 차단 도메인, 사설 주소, 문서용 예시 도메인을 차례대로 처리합니다. geoip:private를 사용하려면 실행 환경에 해당 데이터 파일이 있어야 합니다. 로그에 데이터 파일 누락이 표시되면 경로를 바로잡거나 실제 네트워크에 맞는 CIDR 목록으로 바꾸세요. 시작 오류를 무시해서는 안 됩니다.
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:blocked.example.com"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "direct"
}
]
}
}
full:은 도메인 전체가 일치하는 경우에 사용하고, domain:은 해당 도메인과 하위 도메인에 사용합니다. 둘 다 웹페이지 경로, 쿼리 매개변수, 프로토콜 접두사를 넣는 용도가 아닙니다. 웹사이트 요청을 매칭하려고 전체 URL을 도메인 배열에 넣어서는 안 됩니다. 정규식은 패턴이 꼭 필요한 경우에 적합하지만 검토하기 더 어렵습니다. 명확한 도메인으로 표현할 수 있다면 복잡한 정규식을 추가하지 마세요.
도메인 라우팅 정책은 DNS 전체를 제어하는 스위치가 아닙니다
AsIs는 라우팅 단계에서 기존 대상 정보를 가능한 한 유지하며, IP 규칙 때문에 도메인을 적극적으로 조회하지 않습니다. IPIfNonMatch는 도메인 매칭 결과가 없을 때 주소를 조회해 IP 조건을 계속 확인합니다. IPOnDemand는 IP 판단이 필요한 규칙을 만났을 때 조회합니다. 실제 동작은 요청에 도메인과 IP 중 무엇이 들어왔는지에도 영향을 받으므로 정책 이름만 보고 판단해서는 안 됩니다.
애플리케이션이 도메인을 IP로 변환한 뒤 해당 IP로 로컬 프록시에 연결하면 커널에서 원래 도메인을 확인하지 못할 수 있습니다. 트래픽 탐지가 단서를 보완하는 경우도 있지만 모든 프로토콜에서 작동하지는 않습니다. ‘도메인 규칙이 적용되지 않음’ 문제를 확인할 때는 먼저 인바운드가 어떤 형태의 대상을 받았는지 확인하고, 탐지 결과를 살펴본 다음 도메인 목록을 점검하세요. 그렇지 않으면 정보 부족을 규칙 문법 오류로 오해하기 쉽습니다.
포트, 네트워크 유형, 사설 주소
port는 대상 서비스의 포트와 매칭하며 로컬 프록시 리스닝 포트와는 다릅니다. network는 TCP와 UDP를 구분하는 데 사용할 수 있습니다. 웹 트래픽의 포트를 전부 프록시로 보내도록 설정해도 특정 브라우저의 모든 동작이 프록시를 거친다는 뜻은 아닙니다. DNS, 실시간 통신, 기타 프로토콜은 다른 대상 포트를 사용할 수 있습니다. 일반 필드 기반 라우팅만으로 프로세스별 아웃바운드 선택을 할 수 있다고 볼 수도 없습니다.
사설 주소 규칙은 라우터 관리 페이지, LAN 서비스, 로컬 리소스를 직접 연결할 때 흔히 사용합니다. 그러나 도메인이 사설 주소로 조회되더라도 라우팅에서 조회 결과를 얻어야 IP 규칙에 일치할 수 있습니다. 합성 주소 방식을 사용한다면 해당 방식의 커널 요구 사항에 따라 주소 매핑과 트래픽 처리도 설정해야 합니다. 합성 주소를 일반 사설 네트워크 주소로 취급해 올바른 복원 과정을 우회하지 마세요.
규칙을 검증할 때는 대상 하나를 정하고, 아웃바운드 태그를 확인할 수 있도록 로그를 잠시 활성화한 뒤 요청을 한 번 보내세요. 이어서 인바운드, 대상, 아웃바운드를 확인합니다. 요청 재시도로 로그가 여러 건 남거나 브라우저의 백그라운드 연결이 판단을 방해할 수 있으므로 명령줄에서 한 번만 요청하는 편이 좋습니다. 연결 테스트는 첫 연결 및 프록시 적용 확인을 참고하세요. 페이지가 빨리 열리는지만으로 라우팅을 판단해서는 안 됩니다.
5. dns: 조회 경로와 순환 의존성
먼저 세 가지 DNS 조회를 구분하세요
DNS를 설정하기 전에 애플리케이션 자체의 조회, 커널 내장 DNS 조회, 원격 서버의 조회를 구분하세요. 애플리케이션이 먼저 시스템에서 IP를 받아 프록시에 전달할 수도 있고, 도메인을 SOCKS에 전달해 이후 연결에서 처리하게 할 수도 있습니다. 커널의 dns 객체는 내장 DNS를 사용하는 경로에만 영향을 줍니다. 시스템 DNS 확인자를 자동으로 바꾸지 않으며 브라우저에서 별도로 설정한 암호화 DNS에도 영향을 주지 않습니다.
서버의 도메인도 조회해야 하며, 이는 최종적으로 방문할 웹사이트의 도메인 조회와는 별개의 작업입니다. 전자는 프록시 연결을 설정하기 위한 선행 조건이고, 후자는 프로토콜과 아웃바운드 동작에 따라 원격에서 처리될 수 있습니다. DNS 문제를 진단할 때는 두 도메인을 따로 기록하세요. 서버 주소를 조회하지 못하면 어떤 웹사이트에도 연결할 수 없을 수 있지만, 그렇다고 모든 대상 사이트의 DNS에 문제가 있다고 단정할 수는 없습니다.
기본 항목과 조건부 DNS 조회
servers에는 간단한 DNS 서버 주소나 조건이 포함된 객체를 넣을 수 있습니다. hosts는 내장 DNS 확인자에 고정 매핑을 설정하는 항목입니다. 아래 예시는 고정 매핑과 도메인 조건별 DNS 서버의 계층을 보여줍니다. 모든 네트워크에 일괄적으로 권장하는 설정은 아닙니다. 실제 서버 접근성, 네트워크 정책, 개인정보 보호 요구 사항을 검토해야 하며 공개 DNS 주소가 모든 환경에서 작동한다고 가정해서는 안 됩니다.
{
"dns": {
"hosts": {
"lab.example.com": "192.168.50.10"
},
"servers": [
{
"address": "1.1.1.1",
"port": 53,
"domains": ["domain:example.com"]
},
"8.8.8.8"
]
}
}
예시의 LAN 주소는 정적 매핑을 설명하기 위한 것으로, 로컬에 해당 서비스가 실제로 있을 때만 의미가 있습니다. 커널의 hosts는 운영체제의 hosts 파일과 같지 않습니다. 요청이 내장 DNS 확인자를 거치지 않으면 이 매핑은 전혀 적용되지 않을 수 있습니다. 도메인을 고정 주소에 매핑할 경우 서비스 주소 변경, 여러 지역의 진입점, 인증서 이름도 고려해야 합니다. 고정 IP는 일반 DNS 조회를 장기간 대체하는 범용 방법이 아닙니다.
DNS 요청 전달과 대체 동작
DNS 서버 항목의 도메인 조건은 DNS 서버를 선택하기 위한 것이며, 애플리케이션 트래픽의 프록시 아웃바운드를 선택하는 조건이 아닙니다. 애플리케이션 트래픽은 계속 routing에서 처리합니다. 조건부 서버가 실패한 뒤 다른 서버를 사용할지, 동시에 조회할지, 응답 주소를 허용할지는 현재 커널의 관련 항목을 확인해야 합니다. 커널마다 대체 동작 매개변수가 다르므로 다른 커널 설정을 그대로 적용하지 말고, 수정 전에 항목 이름과 실제 의미를 확인하세요.
내장 DNS가 보내는 요청에도 네트워크 경로가 있습니다. 일부 조회는 커널 라우팅을 거치고, 로컬 처리 의미를 지닌 일부 조회는 로컬 네트워크 스택을 사용합니다. 따라서 암호화 DNS를 사용한다는 사실만으로 조회가 어떤 아웃바운드를 거치는지 판단할 수 없습니다. DNS 서버 주소를 도메인으로 지정하면 해당 서버 도메인을 먼저 조회하는 과정이 필요합니다. 이 과정이 같은 DNS 서버에 다시 의존하면 순환이 생길 수 있습니다.
대표적인 순환 의존성은 서버 도메인을 조회해야 프록시를 연결할 수 있는데, DNS 요청은 아직 연결되지 않은 그 프록시를 통해야 하는 경우입니다. 해결하려면 의존 순서를 먼저 그려 보세요. 연결을 시작하는 데 필요한 주소는 작동하는 DNS 부트스트랩 경로로 조회하고, 그다음 애플리케이션 도메인을 처리해야 합니다. 모든 DNS 요청을 같은 프록시 아웃바운드로 보내면 규칙은 단순해 보여도 시작 단계에서 연결을 완료하지 못할 수 있습니다.
IPv4, IPv6, DNS 캐시
AAAA 레코드가 조회된다고 현재 네트워크에서 IPv6 경로가 안정적으로 작동한다는 뜻은 아닙니다. IPv4로만 연결된다고 해서 해당 도메인에 IPv6 서비스가 없다는 의미도 아닙니다. 조회 정책을 바꾸면 반환되는 주소 유형은 달라질 수 있지만 라우터, 통신망, 원격 서버에 IPv6 경로가 없는 문제까지 해결하지는 못합니다. 일부 대상이 시간 초과된다면 DNS 응답과 실제 연결 주소를 따로 확인한 다음, 필요한 경우 주소 유형을 임시로 제한해 비교하세요.
DNS 캐시는 브라우저, 운영체제, 클라이언트, 원격 서버 등 여러 위치에 있을 수 있습니다. 설정을 바꾼 뒤에도 같은 도메인에서 이전 동작이 보인다고 해서 새 설정이 적용되지 않았다고 단정할 수 없습니다. 먼저 실제 조회를 담당하는 구성 요소를 다시 시작하거나 분명히 구분되는 테스트 도메인을 사용해 로그를 확인하세요. 캐시를 지우려고 클라이언트 데이터를 모두 삭제하면 구독, 라우팅, 서버 선택 등 새로운 변수가 생길 수 있습니다.
명령을 비교할 때 curl의 socks5://와 socks5h://는 도메인 처리 방식이 다릅니다. 후자는 대상 도메인을 SOCKS 프록시 쪽으로 전달합니다. 이 차이를 이용해 로컬 DNS 조회가 관여하는지 확인할 수 있지만, 요청이 성공해도 해당 경로만 작동한다는 뜻입니다. 구독 업데이트 중 DNS 오류가 발생하는 문제는 구독 업데이트 실패 문제 해결을 참고하세요. 구독 다운로드가 현재 프록시 경로를 사용하지 않을 수도 있습니다.
6. policy: 시간 초과, 사용자 등급, 통계
정책은 동작을 제어하지만 아웃바운드를 선택하지 않습니다
policy는 핸드셰이크 대기 시간, 유휴 시간 초과, 통계 활성화 등 연결 처리 정책을 설정합니다. 라우팅 규칙이 아니며 도메인이 직접 연결과 프록시 중 어느 경로를 사용할지도 결정하지 않습니다. 연결 실패가 발생하면 먼저 어느 단계에서 실패했는지 확인하세요. 로그에서 대기 시간이나 유휴 연결 종료가 실제 원인으로 드러날 때만 정책을 조정해야 합니다. 모든 시간 초과를 늘리면 오류가 늦게 나타날 뿐인 경우가 많습니다.
levels의 키는 사용자 등급이며 JSON에서는 문자열로 작성합니다. 속도 단계나 구독 요금제 등급이 아니라 프로토콜 사용자 설정에서 참조하는 정책 인덱스입니다. 참조할 사용자 등급이 있는지는 해당 인바운드와 프로토콜에 따라 달라집니다. 전용 등급을 설정하지 않았다면 기본 동작을 확인하세요. 등급 객체를 하나 추가한다고 모든 트래픽에 자동 적용되는 것은 아닙니다.
연결 시간 관련 항목의 의미
아래 예시는 0등급과 시스템 통계 스위치의 구조를 보여줍니다. 시간 항목의 단위는 초이며, 숫자는 전체 설정 형식을 설명하기 위한 값이지 모든 네트워크에 맞는 최적화 권장값이 아닙니다. 현재 커널의 기본값을 유지하려면 해당 항목을 생략할 수 있습니다. 값을 바꿀 때는 기존 동작을 기록하고 한 번에 한 항목만 변경해 비교하세요. 특히 연결을 오래 유지하는 애플리케이션의 결과를 확인해야 합니다.
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": true,
"statsInboundDownlink": true
}
},
"stats": {}
}
handshake는 해당 정책이 제어하는 프로토콜 핸드셰이크의 대기 시간입니다. 모든 원격 연결, TLS 협상, 웹페이지 응답에 공통으로 적용되는 시간 제한은 아닙니다. connIdle은 유효한 데이터 활동이 없는 연결의 유휴 시간을 관리합니다. 실시간 통신, 원격 세션, 푸시 알림은 업무 데이터 없이 오랫동안 연결을 유지할 수 있습니다. 시간을 너무 짧게 설정하면 재연결이 늘고, 너무 길게 설정하면 끊어진 연결이 더 오래 자원을 점유할 수 있습니다.
uplinkOnly와 downlinkOnly는 연결의 한쪽이 종료된 뒤 다른 쪽이 계속 전송할 수 있는 대기 단계와 관련된 항목입니다. 업로드 및 다운로드 속도 제한이 아닙니다. 값을 낮추면 연결을 빨리 정리할 수 있지만, 아직 전송할 데이터가 남은 반종료 세션을 끊을 수도 있습니다. 대용량 다운로드, 스트리밍 응답, 장시간 유지되는 요청을 테스트할 때는 짧은 웹페이지 하나만 확인하지 말고 연결 종료 동작도 살펴보세요.
통계 설정과 인터페이스 표시의 관계
통계를 활성화하려면 보통 stats 객체와 해당 통계 정책을 함께 설정해야 합니다. 시스템 통계는 인바운드 등의 객체를 대상으로 하고, 사용자 통계는 프로토콜 사용자를 식별할 수 있도록 설정해야 합니다. 사용자 통계 스위치를 켜도 익명 SOCKS 요청마다 별도 사용자 보고서가 자동으로 생성되는 것은 아닙니다. 통계 이름과 조회 방식은 커널 서비스 인터페이스 및 클라이언트 구현에도 영향을 받습니다.
설정에서 통계 누적을 허용하더라도 그래픽 인터페이스에 수치가 표시된다는 보장은 없습니다. 통계를 읽는 프로그램에는 적절한 인터페이스와 호출 방식이 필요하며, 인터페이스 리스닝 범위도 신뢰할 수 있는 네트워크로 제한해야 합니다. 일반적인 사용 환경에서는 v2rayN 자체 통계 기능을 우선 사용하세요. 화면에 특정 수치를 표시하려고 제어 인터페이스를 추가로 노출할 필요는 없습니다. 통계가 기록되지 않는다면 먼저 트래픽이 해당 객체를 통과했는지 확인하세요.
로그 수준과 리소스 사용
일상적으로 사용할 때는 warning처럼 비교적 간결한 로그 수준을 유지할 수 있습니다. 문제를 해결할 때는 잠시 더 자세한 수준으로 바꾸고 한 번 재현한 뒤 바로 원래대로 돌리세요. 접속 로그는 요청의 흐름을 확인하는 데, 오류 로그는 연결이 어느 단계에서 실패했는지 파악하는 데 사용합니다. 로그 파일 경로에는 쓰기 권한이 있어야 합니다. 경로가 잘못되면 로그가 남지 않을 수 있으므로 기록이 없다는 이유만으로 요청이 없었다고 단정하지 마세요.
파일 로그를 사용하는 경우 데스크톱 클라이언트를 일반 사용자 권한으로 실행하면서 관리자만 쓸 수 있는 시스템 디렉터리에 로그를 저장하지 마세요. 디스크 공간 부족, 읽기 전용 디렉터리, 보안 정책 제한도 로그 확인에 영향을 줄 수 있습니다. 클라이언트가 실행 직후 종료된다면 연결 정책보다 먼저 프로세스 시작 과정과 디렉터리 권한을 확인하세요. 자세한 절차는 v2rayN 시작 직후 종료 문제 해결을 참고하세요.
정책 항목은 운영체제 수준의 프로세스 우선순위, 전체 대역폭 제한, 전원 관리 기능을 제어하지 않습니다. Android 백그라운드 제한, Linux 절전 후 복귀, 네트워크 인터페이스 전환은 기존 연결을 끊을 수 있으며, 유휴 시간을 늘리는 것만으로 해결되지 않습니다. 절전 후 연결이 복구되지 않는다면 먼저 백그라운드와 포그라운드 상태 및 네트워크 변화를 비교하고, 클라이언트의 백그라운드 실행 조건, 시스템 프록시 복구, 커널 로그를 각각 확인하세요.
7. 프로토콜, 전송 방식, 커널 호환성
연결을 세 계층으로 나눠 살펴보기
서버 설정에서는 프록시 프로토콜, 연결 전송 방식, 보안 계층을 구분해야 합니다. VMess, VLESS, Trojan, Shadowsocks는 프록시 데이터와 인증을 처리합니다. TCP, WebSocket 등은 연결을 전달하는 방식을 나타내고, TLS나 다른 보안 메커니즘은 해당 연결을 보호합니다. 세 계층의 설정이 서버 측과 일치해야 합니다. 도메인과 포트가 맞더라도 전송 유형, 경로, 인증서 이름을 확인해야 합니다.
설정에서 settings는 프록시 프로토콜에 속하고 streamSettings는 연결 전송 방식에 속합니다. WebSocket 경로를 프로토콜 사용자 객체에 넣어도 보통 원하는 동작을 얻을 수 없습니다. 인증 항목을 전송 객체에 넣어도 프로토콜 인증이 되지 않습니다. 같은 오류가 있는 링크를 계속 가져오기보다 먼저 항목의 계층을 확인한 뒤 값이 올바른지 점검하세요.
WebSocket 및 TLS 설정 조각 확인
아래 내용은 호환되는 아웃바운드 객체 내부의 전송 설정 예시일 뿐, 단독으로 실행할 수 없습니다. 실제 서버의 프로토콜 설정과 합쳐야 합니다. 예시 도메인과 경로는 항목의 위치를 설명하기 위한 것이며 연결 가능한 서버 정보가 아닙니다. 클라이언트가 생성한 항목 이름이 다르다면 현재 선택한 커널이 지원하는 구조를 기준으로 하세요. 특히 세대가 다른 전송 방식의 이름을 임의로 같은 뜻이라고 보고 바꾸지 마세요.
{
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "edge.example.com",
"allowInsecure": false
},
"wsSettings": {
"path": "/proxy",
"headers": {
"Host": "edge.example.com"
}
}
}
}
아웃바운드 서버 주소는 최초 연결 대상이 됩니다. TLS의 serverName은 서버 이름 표시와 인증서 검증에 사용됩니다. WebSocket의 Host는 HTTP 업그레이드 요청에 들어가는 호스트 정보입니다. 이 값들은 서로 같을 수도 있고, 정상적인 리버스 프록시 구성에서는 다를 수도 있지만 추측해서 입력해서는 안 됩니다. 올바른 IP에 연결했더라도 이름이 맞지 않으면 앞단 서비스가 연결을 거부할 수 있습니다.
WebSocket 경로는 서버 측 라우팅과 일치해야 합니다. 앞에 붙는 슬래시, 대소문자, 끝의 슬래시, 쿼리 부분이 모두 요청 처리에 영향을 줄 수 있습니다. 예상하지 못한 HTTP 응답을 받으면 리버스 프록시가 요청을 올바른 백엔드로 전달하는지 확인하세요. 브라우저에서 도메인 홈페이지가 열린다는 사실은 사이트 진입점이 작동한다는 뜻일 뿐, 해당 업그레이드 경로와 프록시 프로토콜 백엔드가 정상이라는 뜻은 아닙니다.
인증서 오류를 검증 비활성화로 덮지 마세요
allowInsecure는 비활성 상태로 유지하세요. 인증서 오류가 발생하면 시스템 시간, 인증서 유효 기간, 이름 일치 여부, 인증서 체인 완전성, 시스템 신뢰 저장소를 각각 확인해야 합니다. 기업 네트워크에서 승인된 내부 인증서를 사용하는 경우 조직의 규칙에 따라 신뢰를 관리하세요. 모든 연결의 검증을 건너뛰어서는 안 됩니다. 검증을 끄면 잘못된 서버를 구별하기 어려워지고 실제 설정 문제도 가려질 수 있습니다.
TLS 핸드셰이크 실패는 보안 계층이 일치하지 않을 때도 발생합니다. 클라이언트는 TLS를 시작하지만 서버의 해당 포트가 일반 TCP만 받거나, 그 반대일 수 있습니다. 일부 오류는 인증 전에 발생하므로 사용자 식별자를 바꿔도 해결되지 않습니다. 먼저 포트에서 실제로 실행 중인 서비스를 확인하고, 보안 계층, 전송 업그레이드, 프록시 인증 순서로 점검하면 불필요한 시행착오를 줄일 수 있습니다.
V2Fly, Xray, 클라이언트의 역할
Project V는 관련 모듈형 프록시 설계의 배경을 제공합니다. V2Fly와 Xray는 서로 다른 커널 계열입니다. 기본 JSON 구조에는 공통점이 있지만 신규 프로토콜 기능, 보안 계층 항목, 일부 라우팅 동작은 달라질 수 있습니다. REALITY는 커널이 지원하는지 확인해야 하는 기능이며, 관련 설정을 임의의 V2Ray 설정에 추가할 수는 없습니다. 구체적인 매개변수는 서버와 일치하는 설정 출처를 사용하세요.
데스크톱에서 v2rayN을 사용할 때는 현재 설정이 실제로 어떤 커널을 호출하는지 확인하세요. Android에서 v2rayNG를 사용한다면 Xray 설정 기능을 확인하고, v2flyNG를 사용한다면 V2Fly 지원 범위에 맞춰 점검하세요. 클라이언트 이름만으로 특정 항목 모음을 단정할 수 없으며, 화면이 비슷하다고 호환되는 것도 아닙니다. 선택에 관한 자세한 내용은 세 클라이언트와 커널 비교를 참고한 뒤 설정 이전 여부를 결정하세요.
설정을 이전할 때는 프로토콜, 인증, 보안 계층, 전송 방식, 라우팅, DNS를 계층별로 확인하세요. 먼저 작동하는 서버 하나를 유지하고 추가 규칙을 옮기는 것이 좋습니다. 모르는 항목이 있다고 바로 삭제한 뒤 계속 사용하지 마세요. 연결에 필요한 설정일 수 있습니다. 설정을 불러올 수 있다는 것과 설정이 원래 의도를 제대로 구현한다는 것은 별개입니다. 실제 동작은 명확한 요청과 로그로 검증해야 합니다.
8. 설정 합치기, 검증, 단계별 문제 해결
실제로 사용되는 설정 원본을 수정하세요
수정하기 전에 클라이언트의 기존 데이터를 내보내거나 백업하고, 작동 중인 사용자 설정은 별도 파일로 저장하세요. 일반 서버 정보는 v2rayN 인터페이스에서 편집하고, 라우팅 프리셋은 라우팅 관리 화면에서 수정하며, 전체 사용자 설정은 따로 관리하는 것이 좋습니다. 클라이언트가 생성한 임시 파일을 편집하는 동시에 인터페이스에서 서버를 바꾸면 마지막으로 실행된 설정이 무엇인지 파악하기 어렵습니다.
이 문서의 조각을 합치기 전에 항목 목록을 만드세요. 최상위 객체에는 같은 이름의 키를 하나만 두고, 인바운드 포트가 기존 리스너와 충돌하지 않도록 합니다. 아웃바운드 태그는 고유하게 유지하고, 규칙에서 참조하는 태그가 실제로 있는지 확인하세요. 필요한 데이터 리소스도 존재해야 합니다. 예시의 사설 주소와 문서용 도메인은 사용 목적에 맞게 처리하고, 필요하지 않은 규칙은 제거하세요. 설명용 설정을 장기간 남겨 두면 안 됩니다.
먼저 인바운드, 다음에 아웃바운드를 테스트하세요
첫 번째 장의 전체 기준 설정을 복원해 실행한 다음 아래 SOCKS 테스트를 수행할 수 있습니다. 로컬의 10808 포트가 SOCKS 요청을 받고 있어야 합니다. 여기서 사용하는 대상은 공개된 문서용 예시 도메인이므로 개인 서버 정보가 필요하지 않습니다. 현재 네트워크에서 해당 사이트에 연결할 수 없다면 접근 가능한 HTTPS 주소로 바꾸되, 비교 테스트를 하는 동안에는 대상을 동일하게 유지하세요.
curl -I --connect-timeout 10 --max-time 20 \
--proxy socks5h://127.0.0.1:10808 \
https://example.com
두 번째 장의 2개 인바운드 설정을 사용한다면 HTTP 인바운드도 별도로 테스트할 수 있습니다. 해당 포트를 실제로 활성화한 경우에만 아래 명령이 의미가 있습니다. 서버는 성공, 리디렉션 또는 기타 유효한 HTTP 상태를 반환할 수 있습니다. 응답을 받으면 요청이 HTTP 서비스에 도달했다는 뜻이지만 원격 프록시를 거쳤다는 증거는 아닙니다. 기준 설정은 직접 연결 아웃바운드를 사용하므로 결과를 서버 연결 확인으로 간주해서는 안 됩니다.
curl -I --connect-timeout 10 --max-time 20 \
--proxy http://127.0.0.1:10809 \
https://example.com
시스템 프록시에만 의존하는 것보다 프록시 주소를 명시하면 환경 변수, 데스크톱 설정, 애플리케이션 호환성의 영향을 줄여 문제를 찾기 쉽습니다. 시스템 프록시를 확인하려면 실제 애플리케이션에서 요청을 보내고 인바운드 로그를 살펴보세요. 명령줄에서는 되지만 브라우저에서는 안 된다면 브라우저 설정이 원인일 수 있습니다. 브라우저에서는 되지만 특정 프로그램에서 안 된다면 해당 프로그램의 프록시 지원이나 DNS 동작을 확인하세요.
오류가 발생한 단계부터 범위 좁히기
| 확인된 증상 | 먼저 확인할 항목 | 다음 조치 |
|---|---|---|
| 커널을 시작할 수 없음 | JSON 계층, 항목 지원 여부, 리소스 파일 | 최소 기준 설정으로 되돌린 뒤 구성을 한 부분씩 추가 |
| 로컬 연결 거부 | 리스닝 주소, 포트, 프로세스 상태 | 요청 프로토콜이 인바운드와 일치하는지 확인 |
| DNS 조회 실패 | 서버 도메인과 DNS 부트스트랩 경로 | 서버 도메인 조회와 대상 도메인 조회 구분 |
| 원격 연결 시간 초과 | 주소, 포트, 네트워크 연결 상태 | 원격 서비스가 작동하는지 먼저 확인한 뒤 전송 방식 점검 |
| TLS 또는 인증 실패 | 이름, 시간, 전송 방식, 인증 항목 | 서버 설정과 계층별로 비교 |
| 일부 대상에서만 발생하는 문제 | 적용된 규칙, 주소 유형, 아웃바운드 태그 | 대상 하나를 정해 반복 비교 |
커널은 시작됐지만 요청 기록이 없다면 원격 서버부터 의심하지 말고 애플리케이션이 프록시에 연결되는지 확인하세요. 요청 기록은 있지만 예상한 태그가 아웃바운드에 표시되지 않는다면 규칙 순서와 기본 아웃바운드를 점검합니다. 아웃바운드가 맞는데 연결에 실패하면 서버 도메인 조회, 네트워크 연결, TLS, 인증 순서로 확인하세요. 확인된 증거를 바탕으로 한 번에 한 단계씩 살펴보세요.
ping 결과를 프록시 프로토콜 테스트로 간주하지 마세요. 대상이 ICMP를 거부해도 일반 서비스 연결은 받아들일 수 있고, 반대로 ICMP 응답이 있어도 지정한 포트가 열려 있지 않을 수 있습니다. TCP 연결에 성공하더라도 서비스를 제공하는 포트라는 뜻일 뿐, 예상한 프로토콜을 사용한다는 의미는 아닙니다. 인바운드 테스트, 포트 연결, 프로토콜 핸드셰이크, 실제 요청 결과를 각각 기록해 하나의 결과로 전체 경로를 판단하지 않도록 하세요.
복구 및 재확인
변경 사항이 검증되면 클라이언트를 다시 시작하고 같은 테스트를 반복해 새로 생성된 설정이 변경 내용을 덮어쓰지 않았는지 확인하세요. 이어서 LAN 리소스, 프록시가 필요한 대상, 장시간 연결 애플리케이션도 테스트해 한 경로를 고치면서 다른 경로를 손상하지 않았는지 살펴보세요. 네트워크 전환이나 절전 후 복구 동작도 따로 확인하는 것이 좋습니다. 특히 데스크톱에서 시스템 프록시나 TUN을 활성화한 경우에 주의하세요.
문제를 문의할 때는 커널 이름, 운영체제, 오류 발생 단계, 민감 정보를 삭제한 관련 설정 조각을 남기세요. 구독 링크, 전체 인증 정보, 계정 매개변수가 포함된 로그를 공개하지 마세요. 수정 후에도 원인을 찾지 못하면 백업을 복원하고 이 장의 순서에 따라 최소 테스트부터 다시 진행하세요. 흔한 증상은 자주 묻는 질문에서 확인할 수 있습니다. 설정 가져오기와 연결 절차를 다시 확인하려면 사용 가이드로 돌아가세요. 원인 분석 대신 반복해서 재설치하지 마세요.