CONFIG / JSON REFERENCE

V2Ray 설정 파일 완벽 가이드

최상위 JSON부터 inboundsoutboundsroutingdnspolicy까지 데이터 흐름에 따라 각 설정의 역할, 매칭 순서와 문제 해결 범위를 나누어 설명합니다.

대상: V2Fly / Xray 설정 체계 형식: JSON 업데이트: 2026-08-19

READING MAP

튜토리얼은 사용 흐름을, 매뉴얼은 필드 조회를 담당합니다

사용 문서는 ‘설정 가져오기, 노드 선택, 프록시 활성화, 연결 확인’ 순서로 첫 사용을 안내합니다. 이 페이지는 인터페이스 버튼을 반복하지 않고, 클라이언트가 최종적으로 V2Fly 또는 Xray 코어에 전달하는 설정 내용을 설명합니다. 필드 의미, 규칙이 매칭되지 않는 이유, DNS 조회 경로가 예상과 다른 문제를 만났다면 이 페이지로 돌아와 모듈별로 점검하세요.

읽을 때는 먼저 데이터 흐름을 잡아두는 것이 좋습니다. 애플리케이션 트래픽이 인바운드 리스너로 들어오면 라우팅 모듈이 도메인, IP, 포트와 인바운드 태그를 읽고 아웃바운드 태그를 선택합니다. 이후 해당 아웃바운드가 연결을 설정합니다. DNS, 정책과 로그는 이 흐름을 대신하지 않고 각각 조회 결과, 실행 제약과 진단 정보를 제공합니다.

01 / ROOT OBJECT

JSON 구조 개요와 데이터 흐름의 경계

최상위 객체는 실행 순서 목록이 아닙니다

V2Ray 설정 파일의 루트 노드는 JSON 객체입니다. 일반적인 최상위 필드로는 logdnsinboundsoutboundsroutingpolicystats가 있습니다. 파일에 적힌 필드 순서는 보통 실행 순서를 결정하지 않습니다. routinginbounds보다 앞에 작성해도 라우팅이 인바운드보다 먼저 시작되지는 않습니다. 실제 실행 관계는 모듈의 역할과 태그 참조로 결정되므로, 설정을 정리할 때는 읽기 편한 순서로 배치하되 화면상의 순서를 제어 흐름으로 해석하지 마세요.

inboundsoutbounds가 배열인 이유는 하나의 코어 인스턴스가 여러 진입점을 동시에 리슨하고 여러 출구를 준비할 수 있기 때문입니다. 배열의 각 객체는 보통 tag로 고유한 이름을 얻습니다. 라우팅 규칙은 inboundTag로 출처를 제한하고 outboundTag로 목적지 출구를 가리킵니다. 태그는 설정 내부에서 사용하는 참조 키이지 프로토콜 이름이 아닙니다. 출구 태그를 proxydirect 또는 더 구체적인 역할명으로 지정해도 되지만, 모든 참조가 정확히 일치하고 유지 관리하기 쉬워야 합니다.

JSON 문법과 클라이언트 생성 설정

표준 JSON에서는 속성명과 문자열에 큰따옴표를 사용하며, 후행 쉼표와 기본 주석을 지원하지 않습니다. 불리언 값은 반드시 true 또는 false로 작성하고, 포트 같은 숫자를 따옴표가 있는 문자열로 쓰지 마세요. 중국어, 경로와 도메인은 UTF-8 파일에 바로 넣을 수 있지만 Windows 경로의 백슬래시는 이스케이프해야 합니다. 직접 편집한 뒤 ‘설정을 파싱할 수 없음’과 같은 오류가 나타나면 먼저 문법을 확인하고 프로토콜 필드를 점검하세요. 문법 분석에 실패하면 코어는 아직 네트워크 연결 단계에 도달하지 않은 것입니다.

v2rayN、v2rayNG와 v2flyNG는 인터페이스 설정에 따라 코어 설정을 생성하거나 조합합니다. 데스크톱에서는 라우팅, 시스템 프록시와 코어 로그를 확인하기 좋은 v2rayN을 우선 사용할 수 있습니다. Android의 v2rayNG는 Xray 코어를, v2flyNG는 V2Fly 코어를 사용합니다. 클라이언트가 생성한 임시 설정은 재시작, 노드 전환 또는 구독 업데이트 후 덮어써질 수 있으므로, 장기적으로 사용할 규칙은 클라이언트가 제공하는 사용자 지정 설정, 라우팅 설정 또는 지원되는 템플릿 진입점에서 관리하세요. 실행 디렉터리의 임시 파일을 직접 수정하는 방식은 권장하지 않습니다.

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "1.1.1.1",
      "8.8.8.8"
    ]
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom"
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": []
  }
}

최소 설정에는 트래픽을 받을 수 있는 인바운드 하나와 연결을 설정할 수 있는 아웃바운드 하나만 필요하지만, 실제 클라이언트는 로컬 API, 통계, DNS 또는 여러 라우팅 규칙을 추가합니다. 큰 설정을 읽을 때는 당면한 문제와 관련 없는 모듈을 먼저 제외하세요. 연결 자체가 시작되지 않으면 JSON, 인바운드와 아웃바운드를 보고, 일부 도메인만 잘못된 출구로 가면 라우팅을 확인하며, 도메인은 실패하지만 IP는 되면 DNS를 우선 점검합니다. 문제 범위를 좁혀 가는 편이 무작정 한 줄씩 수정하는 것보다 안정적입니다.

02 / INBOUND

inbounds 인바운드 리슨, 프로토콜 및 트래픽 식별

listen, port, protocol 및 tag

인바운드는 어떤 로컬 또는 네트워크 연결이 코어로 들어올 수 있는지 결정합니다. 일반적인 로컬 진입점은 SOCKS와 HTTP 프록시입니다. 브라우저, 터미널 또는 시스템 프록시가 요청을 리슨 주소로 보내면 코어가 이후 라우팅을 처리합니다. listen127.0.0.1로 설정하면 로컬 연결만 허용하므로 단일 장치용 클라이언트에 적합합니다. 모든 인터페이스에서 리슨하도록 설정하면 접근 범위가 넓어지므로, 로컬 네트워크 장치의 접속이 명확히 필요한 경우가 아니라면 함부로 공개하지 마세요. port는 다른 프로그램이 사용하지 않아야 하며, 동일한 주소와 포트 조합을 두 인바운드가 중복으로 바인딩할 수 없습니다.

protocol은 진입점 프로토콜을 지정하며, settings의 구조는 프로토콜에 따라 달라집니다. SOCKS 인바운드에서는 UDP 전달을 제어하는 udp를 자주 사용하고, HTTP 인바운드는 일반 HTTP 프록시와 CONNECT 요청을 받습니다. tag는 라우팅에서 출처를 식별하는 데 사용됩니다. 예를 들어 브라우저 전용 진입점에 browser-in을 지정하면 별도 규칙을 적용할 수 있습니다. 태그는 포트를 대신하지 않습니다. 애플리케이션이 올바른 리슨 포트에 연결해야 라우팅 모듈이 태그를 읽을 수 있습니다.

{
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

sniffing의 용도와 한계

애플리케이션이 대상 IP만 프록시에 전달하지만 라우팅 규칙은 도메인으로 판단해야 할 때, sniffing이 HTTP 요청 또는 TLS 핸드셰이크에서 대상 도메인을 식별할 수 있습니다. destOverride는 어떤 트래픽 유형을 식별할지 지정합니다. 활성화하면 라우팅 모듈이 더 완전한 도메인 정보를 얻어 도메인 기반 분류가 안정적으로 매칭되는 경우가 많습니다. 하지만 스니핑은 DNS를 대신하지 않으며 모든 암호화 트래픽에서 임의의 내용을 복원할 수도 없습니다. 연결 수립 단계에서 보이는 대상 정보만 이용합니다.

스니핑 문제를 점검할 때는 ‘애플리케이션이 제출한 원래 대상’과 ‘라우팅이 실제로 사용한 대상’을 따로 확인해야 합니다. 스니핑을 끈 뒤 규칙이 정상으로 돌아온다면 식별된 도메인이 더 앞에 있는 다른 규칙을 발동했을 수 있습니다. 켠 뒤에도 도메인 규칙이 매칭되지 않으면 트래픽이 예상한 인바운드를 통과하는지, 시스템의 다른 프록시 포트가 받은 것은 아닌지 확인하세요. 투명 프록시, 가상 네트워크 어댑터와 일반 SOCKS 진입점은 트래픽 출처가 다르며, 클라이언트에서 모드를 바꾸면 실제로 생성되는 인바운드도 달라집니다.

필드 역할 일반적인 확인 사항
listen 리슨할 로컬 주소 제한 로컬에서만 사용할 때는 루프백 주소에 우선 바인딩
port 애플리케이션 연결을 받을 포트 시스템 프록시 설정과 일치하는지 확인하고 사용 중인지 점검
protocol 진입점 프로토콜 정의 애플리케이션의 프록시 유형이 일치해야 함
tag 라우팅 및 통계 모듈에서 참조 대소문자가 규칙의 참조와 완전히 일치해야 함

인바운드 문제는 보통 애플리케이션이 로컬 프록시에 연결하지 못하거나, 포트 바인딩에 실패하거나, UDP 요청만 별도로 작동하지 않는 형태로 나타납니다. 먼저 클라이언트 로그에서 리슨이 성공했는지 확인한 뒤 시스템 프록시 주소와 포트를 점검하세요. 브라우저는 되지만 특정 애플리케이션만 안 된다면 해당 앱이 선택한 프록시 유형을 지원하는지, 시스템 프록시를 우회하는지, UDP가 필요한지를 중점적으로 확인합니다. 로컬 진입점에 도달할 수 있는지 확인하기 전에는 원격 노드를 계속 바꾸지 마세요. 트래픽이 애초에 코어로 들어오지 않았을 수 있습니다.

03 / OUTBOUND

outbounds 아웃바운드 프로토콜 객체와 출구 선택

원격 출구, 직접 연결 출구와 차단 출구

아웃바운드는 라우팅이 선택한 연결을 최종 대상 또는 원격 서비스로 전달합니다. 완전한 설정에는 보통 원격 프록시 출구와 직접 연결 출구가 하나씩 이상 포함되며, 필요에 따라 차단 출구를 추가합니다. 원격 출구의 protocol은 클라이언트와 서버가 함께 지원하는 VMess, VLESS, Trojan 등의 프로토콜이 될 수 있습니다. settings에는 서버 주소, 포트와 인증 정보가 저장되고, streamSettings는 하위 전송 방식, 보안 계층과 관련 매개변수를 설명합니다. 필드는 서버 설정과 한 쌍으로 맞아야 하며, 프로토콜명이 올바르다고 해서 전송 매개변수까지 서로 바꿔 쓸 수 있는 것은 아닙니다.

freedom은 현재 장치가 대상에 직접 접속하도록 하며, 보통 태그를 direct로 지정합니다. blackhole은 규칙에 선택된 연결을 적극적으로 종료하는 데 사용하며, 보통 태그를 block으로 지정합니다. 이들도 표준 아웃바운드이므로 라우팅 규칙에서 outboundTag만 바꾸면 되고 특수 동작 문법은 필요하지 않습니다. 규칙이 존재하지 않는 태그를 참조하면 설정 로드에 실패하거나 실행 중 대상 출구를 찾지 못할 수 있습니다. 태그를 수정한 뒤에는 모든 참조를 함께 검색해야 합니다.

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-3333-4444-555555555555",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "server.example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "response": {
          "type": "none"
        }
      }
    }
  ]
}

streamSettings는 전체를 함께 확인해야 합니다

streamSettings.network는 TCP, WebSocket 또는 gRPC 같은 하위 전송 방식을 설명하고, security는 TLS, REALITY 등의 보안 계층을 지정합니다. 특정 전송과 관련된 설정은 해당 하위 객체에 들어갑니다. 예를 들어 WebSocket은 경로와 요청 헤더를, TLS는 서버 이름 등의 매개변수를 사용합니다. 문제를 해결할 때는 원격 아웃바운드를 세 단계로 나누세요. 먼저 서버 주소와 포트에 도달할 수 있는지 확인하고, 다음으로 사용자 인증과 프로토콜이 일치하는지 확인한 뒤, 마지막으로 전송과 보안 계층의 세부 설정을 확인합니다. ‘연결이 종료됨’이라는 메시지만으로 어느 단계의 문제인지 바로 판단할 수는 없습니다.

서버 주소가 도메인이라면 코어가 먼저 이름을 해석해야 하므로 아웃바운드 실패가 DNS 때문일 수도 있습니다. 로그에 주소가 해석되었지만 핸드셰이크에 실패했다고 나오면 프로토콜, 시간, 서버 이름과 전송 매개변수를 확인하세요. 해석 결과 자체가 없다면 dns 설정과 시스템 네트워크를 먼저 점검합니다. IP로 직접 테스트하면 해석 문제와 연결 문제를 구분하는 데 도움이 되지만, TLS 환경에서는 올바른 서버 이름이 여전히 필요한 경우가 많으므로 IP 테스트 결과를 최종 설정으로 간주해서는 안 됩니다.

mux 같은 연결 다중화 설정은 기본 연결이 안정된 뒤 조정하세요. 다중화가 모든 네트워크와 프로토콜에서 항상 더 빠른 것은 아니며, 너무 일찍 최적화 매개변수를 추가하면 변수가 늘어납니다. 설정을 만들 때는 원격 출구 하나, 직접 연결 출구 하나와 최소한의 전송 필드만 남겨두고, 성공한 뒤 라우팅, 다중화와 추가 출구를 단계적으로 넣으세요. 변경 사항을 추가할 때마다 기록하면 문제가 생겼을 때 빠르게 되돌아갈 수 있습니다.

클라이언트에서 구독을 가져오면 원격 아웃바운드가 자동으로 생성되므로 직접 덮어쓰기 전에 업데이트 방식을 이해해야 합니다. 구독 업데이트로 노드 매개변수는 바뀔 수 있지만 로컬 라우팅은 보통 클라이언트가 별도로 관리합니다. 클라이언트를 다시 받으려면 클라이언트 받기로 이동하고, 공유 링크와 구독 주소의 차이는 공유 링크와 구독 가져오기 안내에서 확인하세요.

04 / ROUTING

routing 라우팅 매칭 순서와 트래픽 분류 규칙

규칙은 순서대로 매칭되며 자동으로 병합되지 않습니다

라우팅 모듈은 연결 속성을 읽고 아웃바운드를 선택합니다. rules는 순서가 있는 배열이며 보통 위에서 아래로 검사합니다. 연결이 실행 가능한 규칙 하나와 매칭되면 해당 규칙이 지정한 출구를 사용합니다. 따라서 더 구체적이고 우선 처리해야 하는 규칙은 앞에, 범위가 넓은 기본 규칙은 뒤에 배치해야 합니다. 두 규칙의 조건이 일부 겹쳐도 ‘더 구체적인 규칙 우선’으로 자동 계산되지 않습니다. 실제 우선순위는 배열 위치에서 결정됩니다.

자주 사용하는 조건에는 domainipportnetworkinboundTagprotocol이 있습니다. 같은 규칙에 서로 다른 범주의 조건을 여러 개 넣으면 연결은 보통 해당 범주를 모두 만족해야 합니다. 같은 범주의 배열에 여러 값을 넣으면 그중 하나와 매칭된다는 뜻입니다. 예를 들어 도메인과 포트를 한 규칙에 함께 쓰면 도메인 조건과 포트 범위를 모두 만족하는 연결만 처리합니다. 서로 관련 없는 조건을 한 규칙에 몰아넣으면 규칙이 완비된 것처럼 보여도 계속 매칭되지 않을 수 있습니다.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "domain:example.cn",
          "full:intranet.example"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:category-ads-all"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

도메인, IP와 domainStrategy

도메인 조건은 여러 매칭 형식을 사용할 수 있습니다. full:은 완전한 도메인 매칭으로 고정 호스트명에 적합하고, domain:은 지정한 도메인과 하위 도메인을 포함할 수 있습니다. regexp:는 정규식 매칭을 제공하지만 복잡한 표현식은 가독성을 떨어뜨리므로 일반 매칭으로 표현할 수 없을 때만 사용하세요. geosite:는 코어 데이터 파일의 도메인 집합을 참조하며, 사용 가능 여부는 클라이언트에 해당 데이터가 포함되어 있는지에 따라 달라집니다. 이름을 입력했다고 해서 현재 환경에 해당 집합이 반드시 존재하는 것은 아니므로 로드 오류나 규칙 무효화가 발생하면 로그를 확인하세요.

IP 조건은 단일 주소, CIDR 네트워크와 geoip: 집합을 지원합니다. 사설 주소는 보통 직접 연결을 우선해 로컬 네트워크 서비스가 원격 출구로 전송되지 않도록 합니다. 도메인 규칙에서 IP로 먼저 해석할지는 domainStrategy가 결정합니다. AsIs는 주로 원래 도메인으로 매칭하고, IPIfNonMatch는 도메인 규칙이 매칭되지 않을 때 해석을 시도한 뒤 IP 규칙을 계속 확인하며, IPOnDemand는 IP 규칙에 필요한 경우 더 적극적으로 해석합니다. 적극적인 해석 전략은 DNS 조회를 늘리거나 분류 결과를 바꿀 수 있으므로 이름만 보고 ‘더 고급’이라고 판단해서는 안 됩니다.

정책 주요 동작 적용 기준
AsIs 요청에 포함된 도메인 형식을 유지한 채 매칭 규칙이 주로 도메인에 의존하고 추가 해석을 원하지 않을 때
IPIfNonMatch 도메인이 매칭되지 않으면 해석 후 IP 규칙 확인 도메인 규칙과 IP 네트워크 규칙이 함께 있을 때
IPOnDemand IP 기반 판단이 필요할 때 해석 실행 해석 경로를 명확히 이해하고 IP 분류가 필요할 때

라우팅을 확인할 때 웹사이트가 열리는지만 보지 마세요. 여러 출구에서 모두 연결에 성공할 수 있습니다. 대상 도메인을 일시적으로 앞쪽의 명확한 태그 규칙에 넣고 로그에서 어떤 출구가 선택되었는지 확인하세요. 규칙이 매칭되지 않으면 트래픽이 예상한 인바운드를 통과하는지, 스니핑이 도메인을 제공하는지, 매칭 접두사가 올바른지, 앞선 규칙에 가로채이지 않았는지, 출구 태그가 존재하는지를 순서대로 점검합니다. DNS 분류와 오염 회피에 대한 전체적인 방법은 V2Ray DNS 분할 해석 가이드에서 계속 확인할 수 있습니다.

05 / DNS

DNS 설정 서버 선택, hosts와 해석 경로

내장 DNS는 해당 경로로 들어온 조회만 처리합니다

dns 모듈은 코어가 도메인을 해석하는 방식을 정의하지만, DNS 서버를 설정했다고 시스템의 모든 조회가 자동으로 코어를 통과하는 것은 아닙니다. 애플리케이션이 직접 해석할 수도 있고, 운영체제가 먼저 해석한 뒤 IP만 프록시에 전달할 수도 있습니다. 내장 DNS로 들어오는지는 클라이언트 모드, 인바운드 유형, 라우팅 정책과 애플리케이션 동작에 따라 달라집니다. 따라서 DNS 문제가 생기면 서버 주소를 계속 바꾸기보다 먼저 조회가 어느 계층에서 발생하는지 확인해야 합니다.

servers에는 단순 주소를 넣거나, 매칭 도메인을 포함한 서버 객체를 넣을 수 있습니다. 단순한 형식은 목록을 통해 일반적인 해석 경로를 제공하고, 객체 형식은 domains로 특정 도메인 유형을 지정해 특정 서버에 우선 전달할 수 있으며 expectIPs로 기대하는 주소 범위를 제한할 수 있습니다. hosts는 정적 매핑이나 별칭에 사용됩니다. 고정 결과, 내부 서비스 매핑과 테스트 규칙에는 유용하지만 자주 바뀌는 공용 도메인을 대량으로 관리하는 용도에는 적합하지 않습니다.

{
  "dns": {
    "hosts": {
      "domain:internal.example": "192.168.10.20",
      "dns-alias.example": "target.example"
    },
    "servers": [
      {
        "address": "223.5.5.5",
        "domains": [
          "geosite:cn"
        ],
        "expectIPs": [
          "geoip:cn"
        ]
      },
      {
        "address": "1.1.1.1",
        "domains": [
          "geosite:geolocation-!cn"
        ]
      },
      "localhost"
    ],
    "queryStrategy": "UseIP"
  }
}

조회 전략과 DNS 아웃바운드

queryStrategy는 IPv4와 IPv6를 모두 허용하거나 한쪽만 요청하는 등 주소 체계 선택 성향을 제어합니다. 선택하기 전에 현재 네트워크, 원격 출구와 대상 서비스가 해당 주소 체계로 실제 연결 가능한지 확인하세요. 안정적인 IPv6 경로가 없는데 IPv6 결과를 우선 받으면 해석은 성공하지만 연결이 시간 초과될 수 있습니다. 이는 DNS 서버 고장이 아니라 해석 결과와 실제 출구의 연결 능력이 맞지 않는 문제입니다.

고급 설정에서는 dns 프로토콜 아웃바운드를 추가하고 라우팅을 통해 코어가 발생시킨 DNS 트래픽을 지정된 출구로 보낼 수 있습니다. 이때 세 가지를 함께 확인해야 합니다. dns.servers는 어디에 조회할지, DNS 아웃바운드는 조회를 어떻게 보낼지, routing.rules는 해당 트래픽이 어느 출구를 사용할지를 결정합니다. 하나만 바꾸면 조회 루프가 생기거나 예상과 반대의 경로가 될 수 있습니다. 특히 원격 서버 도메인을 해석하는 DNS 요청을 아직 연결되지 않은 동일한 원격 연결에 의존하게 만들지 마세요.

{
  "outbounds": [
    {
      "tag": "dns-out",
      "protocol": "dns"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "protocol": [
          "dns"
        ],
        "outboundTag": "dns-out"
      }
    ]
  }
}

DNS 문제는 일정한 순서로 점검할 수 있습니다. 먼저 시스템 도구로 장치 자체의 네트워크 연결을 확인하고, 코어 로그에서 조회를 실행했는지, 어느 서버에 전달했는지, 어떤 유형의 주소를 반환했는지 확인합니다. 마지막으로 해당 주소가 선택한 출구를 통해 도달 가능한지 점검하세요. 도메인 접속은 실패하지만 테스트 IP로 TCP 연결이 되면 도메인 해석과 TLS 서버 이름을 계속 확인해야 합니다. 해석 결과는 있지만 모든 주소가 시간 초과되면 라우팅과 출구를 점검하세요. 캐시 삭제는 오래된 결과만 제거할 뿐 잘못된 규칙 체인을 고치지는 못합니다.

트래픽 분류 설정은 설명 가능성을 유지해야 합니다. 로컬 도메인, 로컬 주소와 명확한 내부 서비스를 로컬 해석에 맡기고 나머지 요청을 필요에 따라 원격 해석으로 보내는 것이 예외 규칙을 많이 쌓는 것보다 안정적인 출발점입니다. 변경할 때마다 변수 하나만 바꾸고 전후 조회 로그를 기록하세요. 상세 필드와 DNS 누수 방지 방법은 앞서 소개한 DNS 설정 상세 가이드와 함께 확인할 수 있습니다.

06 / POLICY

policy 정책: 연결 시간 제한, 통계와 리소스 제약

level과 정책 객체의 대응 관계

policy는 사용자별 및 시스템별 실행 정책을 설정합니다. 사용자별 정책은 levels에 있으며 키는 레벨 숫자를 문자열로 작성합니다. 프로토콜 사용자 객체의 level이 사용할 정책 그룹을 결정합니다. 이는 네트워크 품질 점수나 권한 등급이 아니라 지정된 사용자에게 연결 매개변수 묶음을 매핑하는 값입니다. 대부분의 단일 사용자 클라이언트는 레벨 0이면 충분하며, 여러 연결 동작을 실제로 구분해야 할 때만 레벨을 추가하세요.

일반적인 사용자 정책 필드에는 핸드셰이크 시간 제한, 유휴 연결 시간, 업로드 또는 다운로드만 남은 경우의 유지 시간과 사용자 업로드·다운로드 통계 활성화 여부가 포함됩니다. 시간 필드의 정확한 단위와 적용 범위는 코어 문서와 로그를 함께 확인해야 하며 모든 값을 밀리초로 간주해서는 안 됩니다. 값을 너무 짧게 설정하면 장시간 연결, 백그라운드 동기화 또는 저빈도 요청이 일찍 끊기고, 너무 길게 설정하면 활동이 없는 연결이 리소스를 계속 점유할 수 있습니다. 최적화하기 전에 실제 문제를 관찰하고, 정책 객체를 범용 속도 향상 스위치로 사용하지 마세요.

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5,
        "statsUserUplink": true,
        "statsUserDownlink": true
      }
    },
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true,
      "statsOutboundUplink": true,
      "statsOutboundDownlink": true
    }
  },
  "stats": {}
}

policy, stats와 API의 관계

정책에서 통계 스위치를 켜는 것은 해당 차원의 데이터 수집을 허용한다는 뜻일 뿐이며, 최상위에 stats 객체도 있어야 하는 경우가 많습니다. 클라이언트 인터페이스가 통계 정보를 읽으려면 로컬 API 인바운드와 관련 라우팅이 추가로 생성될 수 있습니다. 세 요소의 역할은 다릅니다. policy는 어떤 차원을 활성화할지, stats는 통계 모듈을 시작할지, API는 조회 진입점을 제공합니다. 일부만 복사하면 인터페이스에 데이터가 계속 표시되지 않을 수 있습니다.

통계는 일정한 실행 부담을 추가하므로 실제 필요 여부는 클라이언트 기능에 따라 결정됩니다. 연결 가능 여부만 확인할 때는 누적 통계보다 로그가 더 직접적일 수 있고, 인바운드와 아웃바운드 트래픽을 장기간 관찰할 때 해당 차원을 활성화하면 됩니다. ‘설정을 완전하게’ 만들겠다고 모든 스위치를 켜지 말고, 짧은 통계값만으로 프로토콜의 우열을 판단하지도 마세요. 애플리케이션 캐시, 동시 연결, 시스템 업데이트와 백그라운드 작업이 관찰 결과에 영향을 줍니다.

정책 항목 제어 범위 너무 엄격하게 설정했을 때
handshake 연결 수립 단계에 허용되는 시간 네트워크가 조금만 느려도 핸드셰이크 시간 초과가 자주 발생
connIdle 활동이 없는 연결의 유지 시간 저빈도 장시간 연결이 조기에 종료
uplinkOnly 업로드 활동만 남았을 때의 유지 시간 단방향 전송이 너무 일찍 종료
downlinkOnly 다운로드 활동만 남았을 때의 유지 시간 다운로드 마지막 구간이나 응답 스트림이 중단

정책 문제는 기본값에서 시작해 점검하세요. 특정 연결이 일정한 유휴 시간 뒤 끊긴다면 connIdle을 확인하고, 원격 네트워크가 간헐적으로 느려질 때만 실패한다면 핸드셰이크 시간이 지나치게 짧지 않은지 점검합니다. 연결은 정상인데 통계만 누락되면 아웃바운드 프로토콜이 아니라 통계 스위치, 최상위 모듈과 클라이언트 API를 확인하세요. 연결 동작과 관찰 기능을 분리하면 인터페이스의 표시 문제를 고치려다 정상 경로를 망가뜨리는 일을 피할 수 있습니다.

클라이언트는 그래픽 인터페이스에 따라 정책과 통계 항목을 자동 관리할 수 있습니다. 수동 설정과 클라이언트 설정이 함께 존재한다면 사용자 지정 조각만 보지 말고 최종 생성 파일을 먼저 확인하세요. v2rayN은 데스크톱 환경에서 생성 결과와 로그를 확인하기에 적합하고, v2rayNG와 v2flyNG의 모바일 설정은 보통 앱이 관리하므로 수동 필드는 지원되는 진입점을 통해 가져와야 합니다. 코어마다 확장 필드의 지원 범위가 다를 수 있으므로 설정을 옮길 때는 핵심 필드부터 시작해 단계별로 추가하세요.

07 / LOGGING

로그 및 모니터링: 오류 단계에서 모듈 찾기

loglevel은 정보량을 결정합니다

log는 설정 문제를 해결할 때 가장 먼저 확인할 곳입니다. 일반적인 loglevel에는 상세한 수준부터 간결한 수준까지 debug, info, warning, error와 none 등이 있습니다. 평소에는 warning을 유지하고, 복잡한 라우팅이나 DNS 문제를 재현할 때만 info 또는 debug로 잠시 높인 뒤 기록이 끝나면 되돌리세요. 상세 로그에는 대상 도메인, 주소, 태그와 연결 과정이 포함될 수 있으므로 정리하지 않은 전체 파일을 그대로 공개해서는 안 됩니다.

accesserror는 액세스 로그와 오류 로그의 출력 위치를 지정할 수 있습니다. 파일 경로를 생략하면 클라이언트가 표준 출력이나 자체 로그 창에서 내용을 수집하는 경우가 많습니다. 상대 경로는 설정 파일이 아니라 프로세스의 작업 디렉터리를 기준으로 하며, 쓰기 제한 디렉터리에서는 권한 문제로 실패할 수도 있습니다. 그래픽 클라이언트에 이미 로그 패널이 있다면 클라이언트가 관리하는 출력 방식을 우선 사용해 사용자 지정 경로가 업데이트, 권한 또는 포터블 디렉터리와 충돌하지 않도록 하세요.

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning",
    "dnsLog": false
  }
}

error만 검색하지 말고 단계별로 로그를 읽으세요

하나의 연결은 대략 설정 로드, 인바운드 수신, 대상 식별, DNS 해석, 라우팅 선택, 아웃바운드 연결 시도, 프로토콜 및 보안 계층 핸드셰이크, 데이터 전송 단계를 거칩니다. 로그의 마지막 줄은 겉으로 드러난 결과일 뿐이며 실제 원인은 앞선 줄에 있는 경우가 많습니다. 예를 들어 ‘연결 종료’는 원격의 능동적인 연결 종료, 핸드셰이크 매개변수 불일치 또는 상위 네트워크 시간 초과 때문일 수 있습니다. ‘출구를 찾을 수 없음’은 태그 참조 문제에 가깝고, ‘주소가 이미 사용 중’은 인바운드 리슨 단계의 문제로 노드 매개변수와는 관련이 없습니다.

문제 해결을 시작할 때 재현 시각과 대상을 기록한 뒤 오래된 로그를 지우거나 해당 시점 근처부터 읽으세요. 여러 번 시도하면 기록이 뒤섞이고, 여러 앱을 동시에 사용하면 어느 연결이 테스트 대상인지 판단하기 어렵습니다. 먼저 관련 없는 프로그램을 종료하고 브라우저 요청 하나만 남긴 뒤 인바운드부터 아웃바운드까지 전체 경로를 관찰하세요. 라우팅 문제는 인바운드 태그, 도메인 또는 IP 조건과 최종 아웃바운드 태그를, DNS 문제는 조회 서버, 반환 주소와 이후 연결을, 핸드셰이크 문제는 서버 이름, 전송, 보안 계층과 시스템 시간을 중점적으로 확인합니다.

클라이언트가 시작 직후 종료되면 먼저 실행 환경, 디렉터리 권한, 코어 파일과 포트 사용 여부를 확인하세요. Windows 데스크톱에서는 런타임 라이브러리와 보호된 디렉터리 쓰기 제한의 영향을 받을 수 있고, Android 클라이언트에서는 시스템의 백그라운드 실행 제한을 점검해야 합니다. 관련 절차는 v2rayN 시작 충돌 및 v2rayNG 갑작스러운 종료 문제 해결에서 확인할 수 있습니다. 이러한 문제는 설정 경로 외부나 초기 로드 단계에서 발생하므로 원격 프로토콜 탓으로 단정하지 마세요.

로그는 한 번 찍은 스크린샷보다 비교할 때 더 큰 가치가 있습니다. 정상 설정의 시작 및 연결 기록을 보관한 뒤 수정 후 기록과 비교하세요. 리스너가 사라졌는지, DNS 반환값이 달라졌는지, 같은 도메인에 선택된 아웃바운드가 달라졌는지, 핸드셰이크 실패가 해석 전인지 후인지 확인합니다. 단계별 차이를 비교하면 범위를 빠르게 좁힐 수 있습니다. 진단이 끝나면 임시 debug 설정과 테스트 규칙을 제거해 로그가 쌓이거나 높은 우선순위의 테스트 규칙이 일상적인 트래픽 분류에 계속 영향을 주지 않도록 하세요.

08 / VALIDATION

설정 검증 및 문제 해결의 고정 실행 순서

먼저 문법, 다음 참조, 마지막으로 네트워크

안정적인 검증 절차는 계층별로 진행해야 합니다. 첫 번째는 JSON 문법입니다. 괄호가 맞물리는지, 쉼표가 올바른지, 문자열이 닫혔는지, 숫자와 불리언의 유형이 정확한지 확인하세요. 두 번째는 내부 참조입니다. 모든 outboundTaginboundTag와 정책 레벨에 대응하는 객체가 존재하는지, 태그 대소문자가 일치하는지 확인합니다. 세 번째에서야 네트워크를 확인합니다. 리슨 포트, DNS, 서버 주소, 프로토콜 인증, 전송과 보안 계층을 점검하세요. 앞의 두 단계를 건너뛰고 노드부터 바꾸면 단순한 오류가 네트워크 현상에 가려집니다.

코어는 보통 설정 테스트 또는 지정한 설정으로 시작하는 기능을 제공하지만, 클라이언트의 래퍼 방식과 코어 명령 매개변수는 서로 다를 수 있습니다. 그래픽 클라이언트 사용자는 실행 디렉터리를 잘 모르는 상태에서 직접 명령을 실행하기보다 클라이언트의 설정 검사와 로그 진입점을 우선 확인하세요. 독립 코어 환경을 사용한다면 현재 실행 파일의 도움말을 먼저 확인한 뒤 지원되는 매개변수로 설정을 로드합니다. 검증 성공은 구조와 필드가 허용되었다는 뜻일 뿐 원격 서비스에 반드시 도달할 수 있다는 뜻은 아닙니다.

{
  "log": {
    "loglevel": "info"
  },
  "inbounds": [
    {
      "tag": "test-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "test-in"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

최소 설정으로 문제 범위를 나누세요

위의 최소 설정은 로컬 SOCKS 인바운드, 라우팅 태그와 직접 연결 아웃바운드만 검증합니다. 시작되지 않으면 문제는 문법, 포트와 로컬 실행 환경에 집중됩니다. 시작되어 대상에 접속할 수 있다면 실제 원격 아웃바운드로 바꿔 문제가 원격 프로토콜 계층으로 넘어가는지 판단할 수 있습니다. 그다음 DNS, 도메인 규칙, IP 규칙, 차단 규칙, 통계와 정책을 순서대로 복원하세요. 매번 한 그룹의 필드만 복원하면 문제가 발견된 즉시 방금 추가한 모듈로 범위를 좁힐 수 있습니다.

일반적인 오류는 현상별로 분류할 수 있습니다. 시작 즉시 실패하면 JSON, 알 수 없는 필드, 태그 참조, 포트 충돌 또는 파일 권한 문제인 경우가 많습니다. 로컬 프록시에 연결할 수 없으면 리슨 주소, 포트와 애플리케이션 프록시 유형의 불일치를 확인하세요. 모든 도메인이 실패하지만 일부 IP에 도달할 수 있으면 DNS 경로 문제일 가능성이 큽니다. 특정 도메인 그룹만 잘못된 출구로 가면 규칙 순서, 스니핑 또는 매칭 접두사를 확인하고, 연결 후 곧바로 끊기면 정책 시간 제한, 원격 핸드셰이크와 네트워크 안정성을 점검하세요. 분류가 최종 결론은 아니지만 먼저 읽을 로그 구간을 결정하는 데 도움이 됩니다.

현상 우선 확인할 모듈 첫 번째 확인 사항
설정을 로드할 수 없음 JSON / 필드 구조 파싱 오류가 발생한 줄과 바로 앞줄의 쉼표
로컬 포트에 연결할 수 없음 inbounds 리스닝 성공 여부와 포트 일치 여부
도메인은 실패하지만 주소에는 도달 가능 dns / routing 조회가 코어로 들어갔는지와 반환 결과
특정 규칙 그룹만 이상함 routing 규칙 순서와 최종 아웃바운드 태그
핸드셰이크 직후 연결 종료 outbounds 프로토콜, 전송과 보안 계층이 전체적으로 일치하는지

클라이언트 환경에서는 설정 덮어쓰기도 고려해야 합니다. v2rayN은 노드 전환, 구독 업데이트 또는 라우팅 모드 변경 후 실행 설정을 다시 생성할 수 있으며, v2rayNG와 v2flyNG도 앱 설정에 따라 코어 매개변수를 구성합니다. 임시 파일을 직접 수정해 잠시 작동하다가 재시작 후 사라지는 현상은 보통 코어가 설정을 무시한 것이 아니라 클라이언트가 파일을 다시 생성했기 때문입니다. 장기 설정은 클라이언트가 지원하는 사용자 지정 라우팅, 템플릿 또는 가져오기 진입점에 저장하세요.

최종 검수는 웹페이지 하나가 열리는지만으로 끝내서는 안 됩니다. 로컬 주소 직접 연결, 일반 도메인 해석, 예상한 프록시 도메인, UDP 필요 여부, 클라이언트 재시작과 구독 업데이트 후 동작을 최소한 확인하고, 로그에서 출구 태그가 설계대로 선택되었는지 검증하세요. 클라이언트를 처음 사용한다면 먼저 사용 문서에 따라 기본 경로를 완성한 뒤 이 페이지로 돌아와 규칙을 추가하세요. 설치 패키지를 다시 선택해야 한다면 클라이언트 받기에서 Windows, macOS, Android 또는 Linux용으로 다운로드하세요. 복잡한 설정의 안정성은 필드 수가 아니라 명확한 경계, 단계별 검증과 되돌릴 수 있는 기록에서 나옵니다.

NEXT STEP

정상 기준선에서 설정을 확장하세요

처음 설정할 때는 클라이언트 설치와 구독 가져오기를 먼저 완료하세요. 이미 정상적인 연결이 있다면 인바운드, 아웃바운드, 라우팅, DNS, 정책 순서로 단계별 조정합니다.