V2Ray 설정 파일 구조 완벽 해설: inbounds·outbounds·routing의 역할 구분

간결한 JSON 설정을 예로 들어 inbounds의 로컬 트래픽 수신, outbounds의 출구 정의, routing의 매칭·전달 과정을 설명하고 log와 dns가 전체 구조에서 맡는 위치를 살펴봅니다.

이 글 한눈에 보기

이 글은 서버 설정을 가져오는 데 익숙하고 V2Ray 설정을 더 깊이 이해하려는 사용자를 위한 내용입니다. 모든 필드를 외우기보다 “트래픽이 인바운드로 들어와 라우팅 판단을 거친 뒤 아웃바운드로 전송된다”는 구조를 익히고, tag·로그·설정 경계를 활용해 문제를 좁혀 가는 데 초점을 둡니다.

먼저 설정 파일의 트래픽 경로부터 이해하기

V2Ray 설정 파일은 JSON 객체이며, 최상위 필드는 로그, 도메인 확인, 인바운드, 아웃바운드, 라우팅을 각각 제어합니다. 핵심은 파일을 위에서 아래로 한 줄씩 실행하지 않습니다. 시작할 때 전체 설정을 읽고 수신 포트, 아웃바운드 처리기, 라우팅 규칙을 구성합니다. 설정은 텍스트 줄 번호가 아니라 데이터 흐름을 따라 읽어야 합니다.

애플리케이션은 먼저 로컬 SOCKS 또는 HTTP 프록시 포트로 요청을 전달하며, 이는 설정의 inbounds에 해당합니다. 인바운드가 대상 주소를 확인하면 연결을 라우팅 모듈로 넘기고, routing은 규칙 순서에 따라 아웃바운드 태그를 선택합니다. 마지막으로 outbounds에서 해당 태그의 처리기가 원격 연결을 만들거나 대상에 직접 접속합니다. dns는 확인이 필요한 도메인에 결과를 제공하고, log는 이 과정의 경고와 오류를 기록합니다.

애플리케이션 요청 인바운드 수신 스니핑 보완 라우팅 매칭 아웃바운드 전송

아래 예시는 로컬 SOCKS 포트 10808을 사용하고, VMess 프록시 아웃바운드와 freedom 직접 연결 아웃바운드를 정의합니다. 사설 주소는 먼저 직접 연결로 보내고, 나머지 TCP 및 UDP 트래픽은 프록시 아웃바운드로 전달합니다. 예시 도메인인 example.com은 구조를 보여 주기 위한 예약 도메인일 뿐이므로 실제 서버 설정으로 바로 사용할 수 없습니다.

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "localhost",
      "1.1.1.1"
    ]
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-4333-8444-555555555555",
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "none"
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

inbounds: 트래픽을 핵심에 전달할 주체 정의

설정 핵심

inbounds는 인바운드 배열이며, 각 항목은 하나의 수신 진입점을 나타냅니다. 예시에서는 주소를 127.0.0.1로 제한하고 포트를 10808, 프로토콜을 socks로 설정합니다. 따라서 로컬 프로그램만 이 포트에 연결할 수 있고, 같은 네트워크의 다른 기기는 이 진입점을 직접 사용할 수 없습니다.

listenport는 핵심이 연결을 기다릴 위치를 정하고, protocol은 포트로 들어오는 데이터를 해석하는 방식을 결정합니다. 포트 자체에 특별한 기능이 있는 것은 아닙니다. 유효한 범위에 있고 다른 프로그램이 사용하지 않으며 애플리케이션에 입력한 프록시 포트와 일치하면 됩니다. 브라우저가 127.0.0.1:10808로 설정되어 있는데 설정 파일이 10809에서 수신 중이면 요청은 핵심에 도달하지 않습니다.

10808
로컬 SOCKS 포트
127.0.0.1
로컬에서만 수신
1개
예시 인바운드
UDP 활성화
SOCKS 인바운드 기능

settings와 sniffing은 각각 무엇을 제어할까

설정 핵심

인바운드의 settings는 선택한 프로토콜에 따라 달라집니다. SOCKS 인바운드에서는 authudp가 의미가 있지만, 이 필드를 다른 프로토콜의 인바운드에 그대로 넣어도 반드시 유효한 것은 아닙니다. 문서를 읽을 때는 이름이 비슷하다는 이유로 설정을 옮기지 말고, 먼저 해당 필드가 어느 프로토콜에 속하는지 확인해야 합니다.

sniffing은 연결 초기에 전달되는 데이터에서 대상 도메인을 보완하는 기능입니다. 애플리케이션이 먼저 도메인을 IP로 확인한 뒤 IP만 프록시에 전달하는 경우가 있는데, 스니핑을 활성화하면 핵심이 HTTP 호스트 필드나 TLS 핸드셰이크 정보에서 도메인을 복원할 수 있어 도메인 기반 routing 규칙이 적용될 가능성이 생깁니다. 스니핑은 도메인 확인기가 아니며 dns를 대신하지도 않습니다.

outbounds: 트래픽이 빠져나갈 경로 정의

설정 핵심

outbounds도 배열이지만 인바운드와 반대 역할을 합니다. 핵심이 최종 대상에 연결하는 방식을 설명합니다. 프록시 아웃바운드에는 일반적으로 서버 주소, 서버 포트, 사용자 식별자, 프로토콜 매개변수, 전송 설정이 포함됩니다. 직접 연결 아웃바운드는 freedom을 사용해 현재 기기에서 대상에 직접 접속하며, 명확한 차단이 필요하면 전용 거부 아웃바운드를 사용하고 태그로 참조할 수도 있습니다.

예시의 proxydirect는 모두 tag입니다. routing은 아웃바운드 내용을 복사하지 않고 어느 tag에 넘길지만 기록합니다. 태그를 변경할 때는 라우팅 규칙도 함께 확인해야 합니다. 예를 들어 directlocal-direct로 바꿨다면 기존 이름을 참조하는 outboundTag는 의도한 아웃바운드를 가리키지 못합니다.

proxy 아웃바운드

프로토콜
VMess
원격 포트
443
전송 방식
TCP
사용자 식별자
UUID 형식

서버 주소, 사용자 식별자, 전송 매개변수는 서버 설정과 일치해야 합니다.

direct 아웃바운드

프로토콜
freedom
원격 서버
필요 없음
참조 태그
direct
일반적인 용도
로컬 네트워크 직접 연결

현재 기기의 네트워크에서 직접 연결을 설정하며, 로컬 DNS·라우팅·방화벽의 영향을 받습니다.

프로토콜 매개변수와 전송 매개변수는 서로 다른 계층입니다

VMess를 예로 들면 settingsvnext는 원격 서버와 사용자를 설명하고, streamSettings는 하위 네트워크와 보안 방식을 설명합니다. 서버 포트는 올바르지만 전송 방식이 다르면 TCP 연결이 이미 성립했더라도 프로토콜 핸드셰이크는 실패할 수 있습니다. 따라서 연결 문제를 점검할 때 주소, 포트, 사용자 식별자만 확인해서는 안 됩니다.

필드 위치 담당 내용 흔한 오류
settings.vnext 서버 주소, 포트, 사용자 매개변수 주소 만료, 포트 오류, 사용자 식별자 불일치
streamSettings.network TCP, WebSocket 등의 전송 유형 클라이언트와 서버의 전송 방식 불일치
streamSettings.security 전송 계층의 보안 방식 보안 방식이 서버와 일치하지 않음
tag routing에서 참조하는 내부 이름 이름 변경 후 규칙을 함께 수정하지 않음

결론: 먼저 계층을 확인한 뒤 필드 값을 비교하기

주소와 포트는 프로토콜 설정에 속하고, 네트워크 유형과 전송 보안은 streamSettings에 속합니다. 매개변수를 잘못된 계층에 배치하면 값 자체가 올바르더라도 핵심이 예상대로 해석하지 못합니다.

routing: 규칙에 따라 인바운드 연결을 아웃바운드로 전달

설정 핵심

routing.rules는 순서가 있는 규칙 배열입니다. 핵심은 첫 번째 규칙부터 확인하며, 처음으로 일치하는 규칙을 발견하면 해당 규칙의 outboundTag를 사용합니다. 따라서 더 구체적인 규칙은 앞에, 범위가 넓은 기본 규칙은 뒤에 배치하는 것이 일반적입니다. 모든 TCP와 UDP를 덮는 규칙을 맨 앞에 두면 이후의 로컬 네트워크 직접 연결 규칙은 일치할 기회를 잃습니다.

예시의 첫 번째 규칙은 geoip:private로 사설 주소를 매칭해 direct로 전달합니다. 대표적인 사설 대역은 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16입니다. 두 번째 규칙은 TCP와 UDP를 매칭해 나머지 트래픽의 프록시 출구로 사용합니다. 규칙 수는 많지 않지만 “구체적인 규칙을 먼저, 포괄적인 규칙을 나중에”라는 기본 원칙을 보여 줍니다.

  1. 규칙의 type이 핵심에서 지원하는 유형인지 확인하고, 일반적인 필드 매칭 규칙에는 field를 사용합니다.
  2. 조건이 도메인, IP, 포트, 네트워크 유형, 인바운드 태그 중 어느 범주에 속하는지 확인하세요.
  3. 위에서 아래로 확인하며 처음으로 일치할 가능성이 있는 규칙을 찾으세요. 예상한 규칙만 살펴봐서는 안 됩니다.
  4. outboundTag가 outbounds의 tag 중 하나와 대소문자까지 완전히 일치하는지 확인하세요.
  5. 일시적으로 로그 수준을 높이고 핵심을 다시 시작한 뒤, 로그에서 실제 대상과 오류가 발생한 단계를 확인하세요.

domainStrategy는 라우팅을 위해 도메인을 확인할 시점을 결정합니다

설정 핵심

예시에서는 IPIfNonMatch를 사용합니다. 대상이 도메인으로 들어오고 도메인 규칙과 일치하지 않으면 라우팅 모듈이 해당 도메인을 확인한 뒤 IP 규칙과 다시 비교할 수 있습니다. 이를 통해 주소 목록 기반 규칙이 도메인 대상을 처리할 수 있지만, 추가 확인 과정이 발생합니다.

domainStrategy는 “모든 DNS 요청을 어느 아웃바운드로 보낼지”를 정하는 스위치가 아니며 시스템 DNS 설정과도 다릅니다. 주로 routing이 매칭 과정에서 도메인을 IP로 확인할지, 확인한다면 언제 할지를 결정합니다. DNS 서버 선택, 조회 트래픽 경로, 최종 연결 대상 주소는 dns, 라우팅 규칙, 아웃바운드 설정을 함께 살펴봐야 판단할 수 있습니다.

매칭 조건 예시 해결에 적합한 문제
도메인 domain 전체 도메인, 하위 도메인 범위 또는 미리 정의된 도메인 분류에 따라 트래픽 분기
IP ip CIDR, 개별 주소 또는 주소 분류에 따라 트래픽 분기
포트 port 지정한 대상 포트를 특정 출구로 전달
인바운드 태그 inboundTag 로컬 진입점별로 서로 다른 출구 정책 적용
네트워크 유형 network TCP와 UDP 트래픽 구분

결론: 트래픽 분기 이상은 먼저 규칙 순서 확인

대상이 항상 같은 출구로 향한다면 먼저 앞의 포괄적인 규칙에 의해 선점되었는지 확인한 다음, 도메인이 IP로 변환되었는지와 아웃바운드 태그가 존재하는지 점검하세요.

dns와 log: 도메인 확인 및 장애 진단 보조

dns는 핵심이 사용할 DNS 서버와 관련 확인 정책을 정의합니다. 예시에는 localhost1.1.1.1을 차례로 작성해 서버 목록 구조를 보여 줍니다. 실제 설정에서는 네트워크 환경과 라우팅 대상에 맞는 확인 방식을 선택하고, 조회가 의도한 아웃바운드로 처리되는지도 살펴봐야 합니다.

애플리케이션 자체의 도메인 확인, 운영체제의 도메인 확인, V2Ray 내장 DNS를 구분해야 합니다. 애플리케이션이 먼저 도메인을 확인하고 SOCKS 인바운드에 IP만 전달하면 핵심이 같은 도메인 조회를 다시 수행하지 않을 수 있습니다. sniffing을 활성화하면 도메인을 복원할 가능성이 있지만, 성공 여부는 프로토콜 트래픽에서 해당 정보를 추출할 수 있는지에 달려 있습니다. 도메인 분기 문제를 점검할 때는 먼저 핵심이 실제로 받은 값이 도메인인지 IP인지 확인하세요.

dns 섹션

예시 서버
localhost
보조 주소
1.1.1.1
주요 역할
도메인 확인 제공
관련 모듈
routing

확인 결과가 IP 규칙 매칭에 사용될 수 있지만, dns 자체가 최종 출구를 결정하지는 않습니다.

log 섹션

예시 수준
warning
진단 수준
info 또는 debug
주요 역할
실행 상태 기록
중점 정보
수신 및 연결 오류

상세 로그는 임시 진단에 적합하며, 점검이 끝나면 더 간결한 수준으로 되돌리는 것이 좋습니다.

loglevel은 출력 상세도를 제어합니다. 평상시에는 warning을 사용해 경고와 오류를 남길 수 있고, 요청 경로를 확인해야 할 때는 일시적으로 info 또는 debug로 바꿀 수 있습니다. 상세 로그는 기록량이 늘어나므로 문제가 해결된 뒤 계속 유지하지 않는 것이 좋습니다.

클라이언트에서 설정 생성부터 수동 점검까지

v2rayN, v2rayNG, v2flyNG는 그래픽 인터페이스의 서버 및 라우팅 옵션을 바탕으로 핵심 설정을 생성합니다. 구독 주소나 공유 링크는 주로 단일 서버에 필요한 프로토콜 매개변수를 제공하며, 클라이언트는 여기에 로컬 인바운드, 로그, DNS, 라우팅 내용을 추가합니다. 따라서 공유 링크의 필드 구성이 핵심에 전달되는 최종 JSON 전체와 일치하지 않는 경우가 많습니다.

그래픽 클라이언트를 사용할 때는 실행 중 생성된 파일을 장기적인 설정 원본으로 삼아 직접 수정하지 않는 것이 좋습니다. 클라이언트가 핵심을 다시 시작하거나 서버를 전환하거나 설정을 갱신하면 생성 파일이 덮어써질 수 있습니다. 더 안전한 방법은 먼저 인터페이스에서 해당 옵션을 변경한 뒤 로그나 생성 결과로 필드를 확인하는 것입니다. 독립 설정을 관리해야 한다면 별도 파일로 관리하고, 변경할 때마다 문법 검사와 시작 테스트를 수행하세요.

설정 문법은 올바른데 핵심이 왜 바로 종료되나요?

JSON이 유효하다는 것은 텍스트를 해석할 수 있다는 뜻일 뿐입니다. 시작 로그를 계속 확인하면서 알 수 없는 필드, 필드 유형 오류, 포트 사용 여부, routing이 존재하지 않는 아웃바운드 태그를 참조하는지 점검하세요.

브라우저에 10808을 입력했는데 왜 요청 로그가 없나요?

inbounds가 실제로 127.0.0.1:10808에서 수신 중인지 확인한 뒤, 브라우저가 HTTP 프록시가 아닌 SOCKS 프록시를 선택했는지 점검하세요. 양쪽의 프로토콜 유형이 일치해야 합니다.

직접 연결 규칙을 추가했는데도 트래픽이 계속 proxy로 가는 이유는?

직접 연결 규칙을 포괄적인 프록시 규칙보다 앞에 배치하고, outboundTag가 정확히 direct로 작성되었는지 확인하세요. 또한 대상이 핵심에 들어올 때 도메인인지 IP인지도 확인해야 합니다.

이 JSON을 v2rayN에 바로 가져올 수 있나요?

완전한 핵심 설정과 클라이언트 서버 항목은 구조가 다릅니다. 전체 설정을 관리해야 한다면 클라이언트가 제공하는 해당 설정 가져오기 경로를 사용하세요. 일반 서버를 가져올 때는 VMess, VLESS 공유 링크 또는 구독 주소를 사용합니다.

loglevel을 바꿨는데 왜 변화가 보이지 않나요?

파일을 저장한 뒤 핵심을 다시 시작하고, 현재 프로세스가 실제로 읽는 설정 파일을 편집 중인지 확인하세요. 그래픽 클라이언트는 시작할 때마다 실행 설정을 다시 생성할 수 있습니다.

권장하는 최소 점검 순서

  1. 먼저 JSON을 정상적으로 해석할 수 있는지 확인하고, 모든 객체·배열·쉼표·따옴표의 위치가 올바른지 점검하세요.
  2. 핵심을 시작한 뒤 127.0.0.1:10808이 이미 수신 중인지 확인하세요.
  3. 일단 명확한 프록시 아웃바운드 하나와 직접 연결 아웃바운드 하나만 남겨 변수의 수를 줄이세요.
  4. 두 개의 routing 규칙으로 사설 주소는 직접 연결되고 나머지 트래픽은 프록시로 가는지 확인하세요.
  5. 기본 연결이 성립한 뒤 도메인 분류, 포트 조건, 추가 아웃바운드를 하나씩 추가하세요.
  6. 한 번에 서로 관련된 필드 한 묶음만 변경하고, 다시 시작한 직후 해당 로그를 확인하세요.

V2Ray 설정을 이해하는 핵심은 필드를 연결 경로로 되돌려 보는 것입니다. inbounds는 수신하고, routing은 선택하며, outbounds는 전송합니다. dns는 도메인 매칭과 연결에 필요한 확인 결과를 제공하고, log는 각 단계의 진단 단서를 남깁니다. 문제가 생기면 이 다섯 경계를 따라 범위를 단계적으로 좁히는 편이 프로토콜·포트·DNS·라우팅을 동시에 수정하는 것보다 검증 가능한 결론에 더 쉽게 도달할 수 있습니다.

v2rayN 다운로드 4개 플랫폼 클라이언트 보기