노드를 가져올 수는 있지만 config.json을 봐도 요청 흐름이 이해되지 않는 사용자를 위한 글입니다. 로컬 10808 포트에서 시작해 인바운드, 아웃바운드, 라우팅, DNS와 로그를 차례로 살펴보고, 문법 검사를 통과하는 V2Ray 5 계열 설정 뼈대도 제공합니다. 포트 충돌, 잘못된 아웃바운드 태그, 규칙 순서 오류 같은 문제를 직접 찾을 수 있습니다.
데이터 흐름부터 확인: 설정 각 부분의 작동 방식
V2Ray 설정은 서로 독립된 스위치의 모음이 아닙니다. 애플리케이션이 요청을 특정 인바운드로 전달하면 라우팅 모듈이 대상 도메인, 대상 IP, 포트와 인바운드 태그를 읽고 지정된 아웃바운드로 요청을 보냅니다. 어떤 라우팅 규칙에도 일치하지 않으면 V2Ray은 보통 아웃바운드 배열의 첫 항목을 사용하므로 outbounds의 배열 순서도 결과에 영향을 줍니다.
inbounds는 “트래픽이 어디로 들어오는가”를, outbounds는 “트래픽이 어디로 나가는가”를 결정하고, routing은 둘을 연결합니다. 설정이 실행된다는 것은 JSON 구조와 필드를 기본적으로 해석할 수 있다는 뜻일 뿐입니다. 예상대로 트래픽을 분기하려면 태그 참조, 규칙 순서와 DNS 응답 결과를 함께 확인해야 합니다.
최소 설정 뼈대: 전체 JSON부터 단계별로 읽기
아래 예시는 로컬 SOCKS 인바운드 하나, VMess 프록시 아웃바운드 하나, 직접 연결 아웃바운드 하나와 차단 아웃바운드 하나로 구성됩니다. 서버 도메인, 포트, 사용자 ID와 전송 방식은 구조를 보여 주기 위한 값일 뿐이며, 실제 사용 시에는 서버 측 매개변수와 하나씩 일치해야 합니다. JSON에는 주석을 넣을 수 없으므로 설명 문구를 실제 설정 파일에 직접 작성하면 안 됩니다.
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"1.1.1.1",
"localhost"
]
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "11111111-2222-3333-4444-555555555555",
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none"
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct"
}
]
}
}
이 설정은 규칙에 일치하지 않는 요청을 첫 번째 아웃바운드인 proxy로 보냅니다. 사설 주소, 중국 본토 도메인과 중국 본토 IP는 direct로, 특정 프로토콜은 block으로 전달합니다. direct를 아웃바운드 배열의 첫 항목에 두고 명확한 프록시 규칙을 추가하지 않으면, 일치하지 않는 트래픽은 직접 연결로 바뀝니다.
tag는 설정 내부에서 사용하는 이름입니다. 자유롭게 정할 수 있지만 참조하는 모든 곳에서 대소문자까지 완전히 같아야 합니다.listen이127.0.0.1이면 로컬 컴퓨터의 연결만 허용하므로 일반적인 데스크톱 프록시 진입점에 적합합니다.port는 숫자이므로 따옴표로 감싼 문자열로 작성하지 마세요. 같은 주소의 포트를 다른 프로그램이 사용 중이어도 안 됩니다.streamSettings는 서버 측 전송 매개변수와 일치해야 하며, 프로토콜 이름만 보고 추측해서는 안 됩니다.
inbounds 인바운드: 애플리케이션이 트래픽을 코어로 전달하는 방식
인바운드는 V2Ray이 로컬 컴퓨터에 열어 둔 수신 진입점입니다. 예시는 127.0.0.1:10808에서 SOCKS로 수신합니다. 브라우저, 다운로드 도구 또는 시스템 프록시에서 SOCKS 주소를 이 포트로 지정해야 요청이 V2Ray에 들어옵니다. 코어만 실행하고 애플리케이션이 인바운드 포트를 사용하도록 설정하지 않으면 일반 애플리케이션 트래픽을 자동으로 가로채지 않습니다.
settings.auth를 noauth로 설정하면 이 SOCKS 진입점에서 사용자 이름과 비밀번호를 요구하지 않으므로 로컬에서만 수신하는 것이 좋습니다. udp: true는 SOCKS UDP 요청의 유입을 허용하지만, 이후 아웃바운드 프로토콜과 서버, 네트워크 환경도 해당 처리를 지원해야 합니다. 이 필드 하나만 켠다고 모든 UDP 트래픽이 정상적으로 통과하는 것은 아닙니다.
SOCKS 인바운드
- 수신 주소
- 127.0.0.1
- 수신 포트
- 10808
- 프로토콜
- socks
- UDP
- true
SOCKS5 설정을 지원하는 브라우저, 명령줄 도구와 데스크톱 애플리케이션에 적합합니다.
HTTP 인바운드
- 수신 주소
- 127.0.0.1
- 권장 예시 포트
- 10809
- 프로토콜
- http
- 용도
- HTTP 프록시 진입점
두 종류의 진입점을 동시에 제공하려면 서로 다른 포트를 사용해 수신 충돌을 피해야 합니다.
여러 인바운드를 동시에 사용할 수 있습니다. 예를 들어 10808은 SOCKS로 유지하고 10809를 HTTP용으로 추가할 수 있습니다. 각 인바운드에 고유 태그를 지정하면 라우팅 규칙에서 inboundTag로 유입 경로를 구분하기 쉽습니다. v2rayN의 로컬 포트를 변경할 때는 「설정」→「매개변수 설정」에서 SOCKS와 HTTP 포트를 확인하세요. 애플리케이션의 프록시 포트도 함께 변경해야 합니다.
outbounds 아웃바운드: 프록시·직접 연결·차단의 역할
아웃바운드는 요청이 V2Ray에서 나가는 방식을 정의합니다. 프록시 아웃바운드에는 보통 서버 주소, 서버 포트, 사용자 인증 정보와 전송 설정이 포함됩니다. 직접 연결 아웃바운드는 freedom을 사용하고, 차단 아웃바운드는 blackhole을 사용합니다. 라우팅 모듈은 원격 연결을 직접 만들지 않고 규칙에 따라 아웃바운드 태그를 선택합니다.
VMess 예시의 vnext는 서버 목록이며, 각 서버에는 여러 사용자가 포함될 수 있습니다. address와 port는 서버의 수신 정보와 일치해야 하고, id는 서버가 인정하는 사용자 식별자여야 합니다. 전송 계층도 TCP, WebSocket, TLS 등의 설정을 확인해야 합니다. 클라이언트와 서버 중 하나라도 다르면 연결 직후 끊기거나 계속 시간 초과가 발생할 수 있습니다.
프록시 아웃바운드 proxy
- 프로토콜
- vmess
- 서버 포트
- 443
- 예시 전송 방식
- TCP
- 기본 용도
- 규칙에 일치하지 않는 트래픽
실제 서버 매개변수는 유효한 노드 설정에서 가져와야 하며, 주소만 바꾸고 나머지 예시 값을 그대로 사용해서는 안 됩니다.
로컬 정책 아웃바운드
- direct
- freedom
- block
- blackhole
- 서버 연결
- 필요 없음
- 선택 방식
- routing 태그
직접 연결과 차단도 아웃바운드이므로 규칙에서 참조할 고유 tag가 필요합니다.
| 필드 | 위치 | 역할 | 흔한 오류 |
|---|---|---|---|
protocol |
아웃바운드 객체 | 아웃바운드 처리기 유형 결정 | VMess 매개변수를 VLESS 아웃바운드에 입력 |
settings |
아웃바운드 객체 | 서버와 사용자 매개변수 저장 | 포트, 사용자 식별자와 서버 설정이 일치하지 않음 |
streamSettings |
아웃바운드 객체 | 하위 전송 및 보안 계층 정의 | TCP, WebSocket 또는 TLS 설정 불일치 |
tag |
아웃바운드 객체 | 라우팅 규칙에서 참조 | 규칙이 존재하지 않는 태그를 참조함 |
결론: 먼저 아웃바운드 자체를 확인한 다음 라우팅을 조정하세요
일단 프록시 아웃바운드 하나만 남겨 연결을 테스트하세요. 서버 매개변수가 정상임을 확인한 뒤 direct, block과 routing을 추가해야 합니다. 그렇지 않으면 노드 오류와 분기 오류가 동시에 발생해 로그만으로 원인을 찾기 어렵습니다.
routing 라우팅: 규칙 순서가 최종 출구를 결정합니다
routing.rules는 위에서 아래로 확인하는 규칙 배열입니다. 요청이 규칙 하나에 일치하면 해당 규칙의 outboundTag를 사용하고, 이후 규칙은 처리하지 않습니다. 따라서 범위가 좁고 우선순위가 높은 규칙을 앞에, 범위가 넓은 규칙을 뒤에 배치해야 합니다.
domainStrategy: IPIfNonMatch는 먼저 도메인 규칙으로 일치 여부를 확인하고, 도메인 규칙에 맞지 않으면 IP를 조회한 뒤 IP 규칙을 계속 검사한다는 뜻입니다. 이 설정으로 geosite:cn과 geoip:cn을 함께 사용할 수 있지만 DNS 결과가 IP 규칙의 판단에도 영향을 줍니다.
- 먼저 명확히 차단해야 하는 프로토콜이나 대상을 처리해 뒤의 포괄적인 직접 연결 규칙이 먼저 가로채지 않도록 합니다.
- 그다음
geoip:private를 처리해 로컬 네트워크 주소와 사설 주소를 직접 연결합니다. - 이후
geosite:cn을 매칭해 도메인 분류에 따라 직접 연결합니다. - 도메인 규칙에 일치하지 않으면
geoip:cn으로 조회된 대상 IP를 확인합니다. - 나머지 트래픽은 어떤 규칙에도 일치하지 않으므로 아웃바운드 배열의 첫 항목인
proxy로 전달됩니다.
| 매칭 조건 | 예시 값 | 대상 아웃바운드 | 처리 결과 |
|---|---|---|---|
protocol |
bittorrent | block | 차단 아웃바운드로 전달 |
ip |
geoip:private | direct | 로컬 네트워크 및 사설 주소 직접 연결 |
domain |
geosite:cn | direct | 분류에 포함된 도메인과 일치하면 직접 연결 |
ip |
geoip:cn | direct | 대상 IP와 일치하면 직접 연결 |
규칙의 outboundTag는 프로토콜 이름이 아니라 특정 아웃바운드 객체의 tag입니다. 아웃바운드 태그가 proxy인데 규칙에 Proxy라고 쓰면 같은 태그로 인식되지 않습니다. 아웃바운드를 삭제하거나 이름을 바꿀 때는 파일 전체를 검색해 모든 참조도 업데이트하세요.
결론: 트래픽 분기를 수정할 때는 한 번에 규칙 하나만 이동하세요
대상 도메인과 예상 출구를 먼저 기록한 다음 규칙 하나의 위치만 조정하고 로그를 확인하세요. 새로운 규칙 세트를 통째로 복사하면 도메인, IP와 기본 출구가 동시에 바뀌어 어떤 변경이 문제를 일으켰는지 찾기 어렵습니다.
DNS와 로그: 설정이 올바른데도 분기가 예상과 다른 이유
DNS는 도메인을 IP로 변환하는 역할에 그치지 않습니다. 도메인과 IP를 함께 매칭하도록 설정하면 조회 결과가 라우팅 판단에 반영됩니다. 예시에서는 서버 목록에 1.1.1.1과 localhost를 넣어 지정한 DNS를 사용하거나 로컬 리졸버에 맡길 수 있도록 했습니다. 실제 네트워크에서는 연결 가능성, 조회 결과와 분기 목표에 맞춰 방식을 선택해야 합니다.
loglevel을 warning으로 설정하면 일상적인 실행에 적합하며 경고와 오류를 확인할 수 있습니다. 규칙을 점검할 때는 잠시 info로 바꿔 더 자세한 실행 정보를 확인한 뒤, 문제가 해결되면 로그가 빠르게 쌓이지 않도록 원래대로 돌리세요. JSON 문자열은 큰따옴표를 사용해야 하며 마지막 배열 항목이나 객체 필드 뒤에 불필요한 쉼표를 남기면 안 됩니다.
{
"log": {
"access": "access.log",
"error": "error.log",
"loglevel": "info"
},
"dns": {
"hosts": {
"domain:internal.example.com": "192.168.1.20"
},
"servers": [
"1.1.1.1",
"localhost"
]
}
}
failed to listen같은 메시지가 나타나면 먼저 수신 주소와 포트 사용 여부를 확인하세요.- 아웃바운드 태그를 찾을 수 없다는 메시지가 나타나면 각
outboundTag와 아웃바운드의tag를 대조하세요. - 원격 서버 연결이 시간 초과되면 주소, 포트, 전송 방식과 현재 네트워크에서의 연결 가능성을 확인하세요.
- 도메인 직접 연결 결과가 예상과 다르면 규칙 순서,
domainStrategy와 DNS가 반환한 주소를 확인하세요.
자주 발생하는 수정 문제: 오류 위치에서 필드 추적하기
설정을 직접 수정할 때는 JSON 문법 손상, 필드 계층 오류, 태그 참조 단절이 가장 자주 발생합니다. 문법 오류는 보통 코어 실행을 막고, 필드 계층 오류는 알 수 없는 필드라는 메시지를 표시할 수 있습니다. 태그 오류는 요청이 실제 규칙에 일치할 때까지 드러나지 않을 수도 있습니다. 문제를 찾을 때는 먼저 파일을 검증하고, 다음으로 진입점을 확인한 뒤 요청 흐름을 점검하세요.
포트를 변경한 뒤 브라우저가 바로 연결되지 않으면 어떻게 해야 하나요?
config.json의 inbounds.port와 브라우저 프록시 포트를 함께 확인하세요. 예를 들어 인바운드를 10808에서 10818로 바꿨는데 브라우저가 계속 10808을 가리키면 새 진입점으로 요청을 전달할 수 없습니다.
설정 테스트는 통과했는데 왜 모든 트래픽이 직접 연결되나요?
outbounds의 첫 항목이 direct로 바뀌었는지 확인하세요. 규칙에 일치하지 않는 요청은 기본 아웃바운드를 사용합니다. 기본값을 프록시로 하려면 사용 가능한 프록시 아웃바운드를 첫 항목에 두거나 대상에 적용되는 명시적 프록시 규칙을 추가하세요.
geosite 규칙을 추가했는데도 도메인별로 분기되지 않으면 어떻게 해야 하나요?
먼저 이 규칙이 더 포괄적인 IP 규칙보다 앞에 있는지 확인한 다음 domainStrategy를 점검하세요. 애플리케이션이 도메인 없이 대상 IP만 전달한다면 도메인 규칙은 원래 도메인 정보를 얻을 수 없습니다.
로그에 proxy 아웃바운드를 찾을 수 없다고 표시되면 어떻게 해야 하나요?
outbounds에서 tag를 검색해 값이 proxy인 객체가 실제로 존재하는지 확인하세요. 태그는 대소문자를 구분하며 태그 앞뒤에 공백을 넣어도 안 됩니다.
v2rayN에서 노드를 가져온 뒤에도 JSON 전체를 직접 작성해야 하나요?
일반적으로 필요하지 않습니다. v2rayN은 노드와 매개변수 설정을 바탕으로 실행 설정을 생성합니다. 로컬 포트를 직접 지정하려면 「설정」→「매개변수 설정」으로 이동하세요. 사용자 지정 설정, 복잡한 인바운드 또는 특수 라우팅을 사용할 때만 JSON을 항목별로 관리하면 됩니다.
v2rayNG와 v2flyNG도 구독 또는 공유 링크를 통해 클라이언트 실행에 필요한 설정을 생성합니다. v2rayNG는 Xray 코어를, v2flyNG는 v2fly 코어를 사용하므로 화면의 필드 이름과 지원되는 전송 기능이 코어에 따라 달라질 수 있습니다. 한 클라이언트에서 내보낸 전체 설정을 다른 코어 환경에 그대로 덮어쓰지 말고, 최소한 프로토콜, 전송 필드와 라우팅 리소스의 호환성을 먼저 확인하세요.
- 현재 정상적으로 작동하는 config.json을 백업하고 로컬 인바운드 포트를 기록하세요.
- 한 번에 한 구역만 수정하고 저장한 뒤 먼저 설정 테스트를 실행하세요.
- 코어를 시작하고 127.0.0.1:10808이 정상적으로 수신 중인지 확인하세요.
- 단일 대상으로 프록시 아웃바운드를 테스트한 다음 직접 연결 규칙과 차단 규칙을 테스트하세요.
- 로그의 대상 주소, 매칭 결과와 연결 오류를 확인하고 문제가 없을 때 다음 수정으로 넘어가세요.