이 글 미리보기

노드를 가져온 뒤 커널 설정을 이해하고 싶은 사용자를 위한 안내입니다. 요청 흐름에 따라 네 가지 최상위 필드를 살펴보고, VMess + WebSocket + TLS 예시를 분석한 다음 태그 참조, 규칙 순서, DNS를 점검합니다. 글을 읽고 나면 연결에 실패할 때마다 JSON 전체를 다시 작성하는 대신, 인바운드·노드 설정·라우팅 중 어디를 확인해야 하는지 판단할 수 있습니다.

1. 설정 파일과 클라이언트 설정, 먼저 구분하기

v2rayN과 v2rayNG는 노드 관리, 구독 업데이트, 커널 실행 설정 생성을 담당하는 클라이언트입니다. v2rayNG는 Xray 커널을 사용하고, v2flyNG는 v2fly 커널을 사용합니다. v2rayN은 여러 커널을 관리할 수 있지만, 이 글에서 다루는 것은 V2Ray/Xray의 기존 JSON 설정 형식입니다. 모든 커널에 공통으로 적용되는 필드 목록은 아닙니다.

여기서 config.json은 커널이 실제로 읽는 설정 파일을 뜻합니다. 클라이언트의 창 위치나 구독 그룹 등을 저장하는 설정 파일과는 다릅니다. 파일 이름도 항상 고정된 것은 아닙니다. 실행 명령에서 어떤 파일을 지정했는지, 그리고 파일에 inbounds, outbounds 같은 필드가 있는지를 확인하세요. 클라이언트가 노드를 업데이트하거나 커널을 다시 시작하면 자동 생성된 파일이 덮어써질 수 있습니다.

앱 요청로컬 인바운드라우팅 규칙 확인아웃바운드 선택대상 서버

2. 전체 JSON 예시: 인바운드 2개, 아웃바운드 3개

아래는 구조를 살펴보기 위한 전체 예시입니다. node.example.invalid은 실제로 사용할 수 없는 가상 도메인이며 UUID도 예시 값이므로 실제 노드에 연결되지 않습니다. 기존 VMess의 vnext 구조를 사용했으며, 실제 주소·포트·UUID·전송 경로·TLS 이름은 서버 설정을 따라야 합니다.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"],
        "routeOnly": true
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "node.example.invalid",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-4000-8000-000000000001",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "node.example.invalid"
        },
        "wsSettings": {
          "path": "/ws",
          "headers": {
            "Host": "node.example.invalid"
          }
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:blocked.example.invalid"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["full:localhost"],
        "outboundTag": "direct"
      }
    ]
  },
  "dns": {
    "servers": ["223.5.5.5"]
  }
}
10808
예시 SOCKS 인바운드 포트
10809
예시 HTTP 인바운드 포트
443
예시 원격 TLS 포트

여기 나온 포트는 설명을 위한 예시이며 모든 버전의 기본값은 아닙니다. JSON에서 포트는 숫자로, true는 불리언으로 작성해야 하며 따옴표를 붙인 문자열로 쓰면 안 됩니다. 마지막 항목 뒤에는 쉼표를 붙일 수 없습니다. 검증하기 쉽도록 예시에는 주석을 넣지 않았습니다.

3. inbounds: 수신 주소, 프로토콜, 스니핑

listen은 연결을 받을 로컬 주소를, port는 포트를, protocol은 앱이 사용할 프록시 프로토콜을 지정합니다. SOCKS 클라이언트는 HTTP 인바운드에 직접 연결할 수 없습니다. 포트 연결에 성공해도 프로토콜이 맞다는 뜻은 아닙니다. 앱에 수동으로 설정할 경우, 예시는 SOCKS5 127.0.0.1:10808 또는 HTTP 프록시 127.0.0.1:10809에 해당합니다.

SOCKS 인바운드

tag
socks-in
listen
127.0.0.1
port
10808
protocol
socks
settings.udp
true

로컬 기기에서만 수신합니다. UDP를 사용하려면 앱에서 SOCKS5 UDP 릴레이도 지원해야 합니다.

HTTP 인바운드

tag
http-in
listen
127.0.0.1
port
10809
protocol
http
settings
빈 객체

HTTP 프록시를 지원하는 앱에 적합합니다. HTTPS 요청은 보통 CONNECT 터널을 사용합니다.

127.0.0.1로 설정하면 로컬 기기에서만 연결을 받습니다. 0.0.0.0으로 바꾸면 모든 IPv4 네트워크 인터페이스에서 수신합니다. 예시 SOCKS 인바운드에는 auth: "noauth"도 설정되어 있으므로 그대로 복사해 네트워크에 노출해서는 안 됩니다. 프록시를 공유해야 한다면 인증, 방화벽, 접근 허용 대상을 함께 점검하세요.

sniffing은 HTTP Host 또는 TLS 핸드셰이크의 서버 이름을 확인해 대상 도메인을 식별하고, 도메인 규칙이 적용되도록 돕습니다. routeOnly: true는 스니핑한 이름을 라우팅 판단에만 사용하고 원래 연결 대상을 대체하지 않는다는 뜻입니다. HTTPS를 복호화하는 기능은 아니며, 모든 트래픽에서 도메인을 알아낼 수 있는 것도 아닙니다. 이 예시에서는 SOCKS 인바운드에만 스니핑을 설정했습니다.

4. outbounds: 노드 인증과 전송 계층 구분하기

프록시 아웃바운드에서 protocol: "vmess"는 노드 프로토콜을 뜻합니다. settings.vnext에는 서버 목록이, users에는 인증 정보가 들어갑니다. id는 사용자 UUID입니다. alterId: 0은 최신 VMess에서 일반적으로 사용하는 설정이므로, 오래된 가이드의 0이 아닌 값을 무작정 적용하지 마세요. users[].security: "auto"는 VMess 암호화 옵션이며 TLS 활성화 여부와는 별개입니다.

필드예시 값실제 역할
vnext[].addressnode.example.invalid커널이 연결할 노드 주소
vnext[].port443서버가 수신하는 포트. 로컬 인바운드 포트가 아닙니다.
streamSettings.networkwsWebSocket 전송 사용
streamSettings.securitytls전송 계층에서 TLS 활성화
tlsSettings.serverNamenode.example.invalidTLS 서버 이름. 일반적으로 SNI와 인증서 이름 검증에 사용됩니다.
wsSettings.path/ws서버 설정과 일치해야 하는 WebSocket 요청 경로
wsSettings.headers.Hostnode.example.invalidWebSocket 핸드셰이크에 사용하는 HTTP Host

예시에서는 변수를 줄이기 위해 주소, SNI, Host를 같은 값으로 설정했지만 실제 구성에서는 서로 다를 수 있습니다. IP 주소로 연결하더라도 TLS에서 도메인 이름을 요구할 수 있습니다. 경로도 정확히 일치해야 합니다. /ws와 /proxy는 서로 바꿔 쓸 수 있는 장식용 텍스트가 아닙니다.

freedom은 직접 연결 아웃바운드, blackhole은 차단 아웃바운드를 뜻합니다. direct, block, proxy는 이 글에서 정한 태그 이름이므로 바꿀 수 있지만, 모든 outboundTag 참조도 함께 수정해야 합니다. VLESS 아웃바운드의 사용자 필드는 VMess와 완전히 같지 않습니다. protocol만 vless로 바꾼다고 전환이 끝나는 것은 아닙니다.

확인: 연결에 실패하면 두 계층의 설정부터 점검

주소, 포트, UUID를 먼저 확인한 뒤 network, TLS 이름, Host, path를 비교하세요. serverName을 바로잡는 대신 인증서 검증을 끄지 마세요. 검증을 건너뛴다고 잘못된 설정이 올바른 노드로 바뀌지는 않습니다.

5. routing: 규칙 순서와 기본 아웃바운드

rules는 배열 순서대로 확인하며, 처음 일치하는 규칙이 아웃바운드를 결정합니다. 예시에서는 먼저 테스트용 도메인을 차단한 다음 사설 주소와 localhost를 직접 연결합니다. 어떤 규칙에도 일치하지 않으면 기존 V2Ray/Xray 설정은 outbounds 배열의 첫 번째 아웃바운드를 사용하므로 여기서는 기본적으로 proxy로 연결됩니다. 이 기본 동작은 태그 이름이 ‘proxy’인지와 관계없습니다.

  1. 태그 확인: outboundTag: "direct"에 해당하는 tag: "direct" 아웃바운드가 있어야 합니다.
  2. 순서 확인: 구체적인 예외 규칙은 대체로 포괄적인 규칙보다 앞에 둡니다. 마지막에 적용할 기본 규칙을 앞쪽에 놓으면 뒤의 규칙이 가려집니다.
  3. 조건 확인: 한 규칙 안의 서로 다른 필드는 대체로 모두 충족해야 합니다. 한 필드의 배열에 있는 여러 후보는 보통 하나라도 일치하면 적용됩니다.
  4. 데이터 확인: geoip:private를 사용하려면 GeoIP 데이터 파일이 있어야 합니다. geosite 항목을 쓸 때도 해당 도메인 데이터가 준비되어 있는지 확인하세요.

도메인 매칭 문법은 서로 다릅니다. full:example.com은 도메인 전체가 정확히 일치할 때만 적용되며, domain:example.com은 해당 도메인과 하위 도메인에 적용됩니다. 접두사 없는 문자열은 보통 키워드로 매칭되어 예상보다 많은 대상에 적용될 수 있습니다. 정확한 예외 규칙을 만들 때는 매칭 범위를 명시하세요.

domainStrategyDNS 조회 시점점검할 사항
AsIs라우팅 판단 과정에서 도메인을 IP로 자동 조회하지 않습니다.도메인 요청이 IP 규칙과 자동으로 일치할 것이라고 기대하면 안 됩니다.
IPIfNonMatch도메인 규칙이 일치하지 않으면 IP 조회 후 IP 규칙을 다시 적용합니다.조회 결과에 따라 최종 아웃바운드가 달라질 수 있습니다.
IPOnDemand매칭에 IP 조건이 필요한 경우 DNS 조회를 수행합니다.조회 비용과 DNS 응답 결과를 확인하세요.

이 예시의 AsIs는 판단 과정을 단순하게 유지하기 위한 설정입니다. 대상이 원래 사설 IP라면 사설 주소 규칙과 일치할 수 있지만, 사설 IP로 해석되는 도메인까지 반드시 해당 규칙에 일치하는 것은 아닙니다. 인트라넷 도메인에는 명시적인 직접 연결 도메인 규칙을 추가하거나, DNS 조회 동작을 이해한 뒤 정책을 조정하세요.

6. dns: 내장 DNS 리졸버와 시스템 DNS는 다릅니다

dns.servers는 커널 내장 DNS 리졸버에서 사용할 서버를 지정합니다. 이 예시에는 구조 설명을 위해 업스트림 서버 223.5.5.5 하나만 설정했습니다. 완전한 DNS 분할 설정을 구현한 것은 아닙니다. 앱이 요청을 보내기 전에 직접 DNS 조회를 할 수도 있으므로 시스템, 브라우저, 커널의 조회 경로를 각각 확인해야 합니다.

따라서 dns를 설정했다는 사실만으로 모든 DNS 조회가 의도한 대로 프록시를 통과한다고 단정할 수 없습니다. 앱의 자체 DNS 조회 여부, 라우팅의 domainStrategy, 아웃바운드의 DNS 처리 정책, DNS 서버 연결 상태를 함께 확인하세요. 특히 도메인 조회가 필요한 노드에 연결할 때는, 노드 연결이 아직 성립하지 않았는데 해당 노드에 의존해 노드 도메인을 조회하는 상황을 피해야 합니다.

7. 설정 내보내기부터 문제 해결까지: 한 번에 하나씩 변경

문제를 해결할 때는 먼저 실행 가능한 설정을 백업한 뒤 커널 버전과 실제로 읽는 파일을 확인하세요. v2rayN의 ‘설정’ → ‘매개변수 설정’에서 로컬 수신 관련 매개변수를 확인하거나 변경할 수 있습니다. 메뉴와 옵션 이름은 버전에 따라 다를 수 있습니다. 클라이언트 화면의 노드 설정, 라우팅 설정, 실행 중인 JSON이 서로 일치하는지 확인하세요. 클라이언트가 다시 생성하는 파일 하나만 확인해서는 안 됩니다.

  1. 문법 확인: 로컬 편집기에서 괄호, 쉼표, 값의 자료형을 확인하세요. UUID, 구독 주소, 노드 정보가 포함된 파일을 공개 온라인 포맷터에 올리지 마세요.
  2. 커널 호환성 확인: 설정을 읽는 커널이 V2Ray인지 Xray인지 확인하세요. 새 필드와 전송 방식은 현재 커널에서 지원하는 범위를 따라야 합니다.
  3. 연결 지점 확인: 프로세스가 설정된 포트에서 실제로 수신 중인지 확인하세요. address already in use 오류가 나타나면 노드 UUID를 바꾸기 전에 포트 충돌부터 해결하세요.
  4. 아웃바운드 확인: 우선 규칙 변수를 줄이고 주소, 인증, 전송 설정을 확인하세요. 시간 초과, 인증 실패, TLS 오류는 각각 다른 원인부터 점검해야 합니다.
  5. 분할 라우팅 확인: 범위가 명확한 테스트 규칙을 하나 추가해 요청이 의도한 아웃바운드를 선택하는지 확인한 뒤 전체 규칙을 복구하세요.
  6. 디버그 로그 원복: 필요한 경우 loglevel을 잠시 debug로 변경하세요. 점검을 마치면 warning으로 되돌려 연결 정보가 과도하게 기록되지 않도록 합니다.

커널을 직접 실행할 때는 해당 커널의 설정 테스트 명령을 사용할 수 있습니다. 아래 명령은 하위 명령 형식을 사용하는 현재 V2Ray/Xray 실행 파일을 기준으로 하며, 경로를 실제 파일 위치로 바꿔야 합니다. 구버전은 명령줄 인자가 다를 수 있으므로 먼저 로컬 help 출력을 확인하세요.

v2ray test -c config.json
xray run -test -config config.json

테스트에 성공했다는 것은 현재 커널이 설정을 읽고 불러올 수 있다는 뜻일 뿐, 노드가 온라인 상태이거나 인증서가 올바르거나 모든 규칙이 의도대로 작동한다는 뜻은 아닙니다. 마지막으로 프록시를 지원하는 앱에서 실제 요청을 보내 확인하세요. 로그에서는 인바운드 태그, 대상 주소, 선택된 아웃바운드를 확인하면 됩니다. 로그를 공유하기 전에는 인증 정보와 개인 접속 기록을 삭제하세요.

정리: 인바운드·아웃바운드·라우팅·DNS를 단계별로 확인

요청이 올바른 포트로 들어오는지 확인하고, 프록시 노드가 작동하는지 검증한 다음 분할 라우팅과 DNS 정책을 추가하세요. 단계마다 복구할 수 있는 설정 사본을 남겨 두면 여러 계층을 한꺼번에 바꾼 뒤 ‘여전히 연결되지 않는다’는 상황을 피할 수 있습니다.