Xray 고급 라우팅과 DNS 누출 방지 JSON 설정 실전 가이드

라우팅과 DNS를 따로 보지 말아야 하는 이유

Xray에서 접속 문제가 발생하면 많은 사용자가 먼저 outbound나 서버 노드만 의심합니다. 그러나 실제 목적지는 도메인 이름을 어떻게 해석했는지, 어떤 규칙이 먼저 일치했는지, DNS 요청 자체가 어느 경로로 나갔는지에 따라 달라집니다. 라우팅은 단순히 “국내 주소는 직행, 해외 주소는 프록시”라고 나누는 기능이 아닙니다. 클라이언트가 요청에서 도메인을 확인하고, 필요한 경우 DNS를 조회한 뒤, 규칙의 우선순위에 따라 outbound를 선택하는 연속 과정입니다.

예를 들어 브라우저가 example.com에 접속했는데 DNS 조회는 운영체제 기본 서버로 보내고 실제 TCP 연결만 프록시로 보내면, 웹 요청은 정상적으로 열려도 DNS 누출이 발생할 수 있습니다. 반대로 모든 DNS를 무조건 원격으로 보내면 특정 국내 서비스가 느려지거나 지역별 응답이 달라질 수 있습니다. 따라서 목표를 먼저 정해야 합니다. 필요한 것은 모든 트래픽을 복잡하게 감싸는 설정이 아니라, 도메인 판정 기준과 DNS 경로가 서로 모순되지 않는 설정입니다.

JSON을 수정하기 전에는 현재 설정을 별도 파일로 복사하고, 한 번에 한 부분만 바꾸세요. 라우팅 규칙, DNS 서버, sniffing, FakeDNS를 동시에 수정하면 문제가 생겼을 때 원인을 찾기 어렵습니다. 변경 전 노드 하나로 브라우저 접속, DNS 확인, 국내외 도메인 테스트를 기록해 두면 이후 비교가 훨씬 쉬워집니다.

도메인 해석과 라우팅 판정 순서 이해하기

일반적인 요청 흐름은 대략 다음과 같습니다. 애플리케이션이 연결을 만들고, Xray가 요청의 목적지 주소와 포트를 확인합니다. 목적지가 도메인으로 전달되면 라우팅 규칙이 도메인, IP, 포트, 네트워크 유형 등의 조건을 비교합니다. 조건에 맞는 규칙이 있으면 지정된 outbound로 보내고, 아무 규칙도 맞지 않으면 기본 outbound가 사용됩니다. 규칙은 보통 위에서 아래로 평가되므로, 더 구체적인 예외를 넓은 규칙보다 앞에 배치해야 합니다.

DNS 설정은 이 과정에 두 가지 방식으로 관여합니다. 첫째, Xray가 라우팅에 사용할 IP를 얻기 위해 DNS 서버에 질의할 수 있습니다. 둘째, 애플리케이션이 직접 보낸 DNS 요청이 별도의 트래픽으로 Xray에 들어올 수 있습니다. 첫 번째만 통제하고 두 번째를 방치하면 브라우저는 프록시를 사용하면서도 운영체제의 DNS 서버에는 직접 질의하는 상황이 생깁니다. 이 때문에 DNS 누출 방지는 DNS 서버 주소 하나를 바꾸는 작업이 아니라, DNS 요청과 실제 연결을 같은 정책 안에서 다루는 작업입니다.

라우팅 규칙을 만들 때는 “도메인 기반 분기”와 “IP 기반 분기”의 차이도 기억하세요. 도메인 정보가 남아 있으면 도메인 규칙이 비교적 정확하게 작동하지만, 먼저 IP로 변환되어 도메인 정보가 사라지면 예상한 규칙이 맞지 않을 수 있습니다. 특히 CDN이나 여러 주소를 사용하는 서비스는 DNS 응답에 따라 결과가 달라지므로, 단순히 한 IP를 차단 목록에 넣는 방식은 유지 관리가 어렵습니다.

sniffing과 routeOnly를 함께 설정하는 방법

sniffing은 연결 내부의 HTTP Host나 TLS SNI 같은 정보를 읽어 실제 목적지 도메인을 확인하는 기능입니다. 애플리케이션이 IP 주소로 연결했더라도 TLS 요청 안에 도메인이 남아 있다면, Xray가 그 정보를 라우팅 판단에 활용할 수 있습니다. 도메인 기반 규칙을 중요하게 사용하는 환경에서는 유용하지만, 모든 트래픽에서 무조건 켜는 것이 항상 좋은 것은 아닙니다. 지원하지 않는 프로토콜이나 특수한 애플리케이션에서는 예상하지 못한 판정이 생길 수 있기 때문입니다.

일반적인 JSON에서는 inbound의 sniffing 관련 항목에서 enabled를 활성화하고, 필요한 경우 destOverridehttp, tls, quic 등을 지정합니다. 다만 실제 필드명과 지원 범위는 사용하는 Xray-core 및 클라이언트 버전에 따라 다를 수 있으므로, 현재 버전의 문서와 기본 생성 설정을 먼저 확인하세요. 설정을 복사할 때 예전 버전의 전체 inbound를 그대로 가져오는 것보다, 필요한 항목만 현재 JSON에 추가하는 편이 안전합니다.

routeOnly는 sniffing으로 확인한 도메인을 라우팅 판단에만 사용하고, 실제 연결 대상 자체를 바꾸지 않도록 할 때 고려하는 옵션입니다. 애플리케이션이 의도한 IP 연결을 보존하면서 도메인 규칙만 적용하고 싶다면 유용할 수 있습니다. 반대로 목적지 도메인으로 연결 대상을 다시 선택해야 하는 환경에서는 routeOnly의 의미를 정확히 이해하지 않고 켜면 접속이 실패할 수 있습니다. 설정 후에는 IP로 직접 연결하는 서비스, HTTPS 사이트, QUIC을 사용하는 앱을 각각 확인해야 합니다.

sniffing을 켠 뒤 특정 사이트가 갑자기 다른 outbound로 가거나 접속이 끊기면 먼저 규칙 순서를 확인하세요. sniffing 자체가 고장 났다고 단정하기보다, 새로 발견된 도메인이 기존의 넓은 규칙에 걸렸는지, 포트 조건과 도메인 조건이 충돌하는지 살펴보는 것이 빠릅니다.

FakeDNS를 적용할 때 확인할 점

FakeDNS는 실제 목적지 IP를 즉시 반환하는 대신, Xray가 관리하는 가상 IP를 애플리케이션에 전달하고 나중에 그 가상 IP와 원래 도메인을 연결하는 방식입니다. 이 구조는 애플리케이션이 IP만 다시 전달하더라도 원래 도메인 정보를 유지하는 데 도움이 됩니다. 특히 도메인 기반 라우팅과 DNS 누출 방지를 함께 구현하려는 환경에서 의미가 있습니다.

하지만 FakeDNS는 DNS 설정 하나만 추가한다고 끝나지 않습니다. FakeDNS 주소 범위, DNS 서버의 응답 방식, inbound에서 해당 가상 IP를 다시 해석하는 흐름, 라우팅 규칙이 서로 맞아야 합니다. 일부 애플리케이션은 가상 IP를 그대로 캐시하거나 자체 DNS를 사용하기 때문에 호환성이 떨어질 수 있습니다. 시스템 전체에 적용하기 전에 브라우저와 자주 쓰는 메신저처럼 테스트하기 쉬운 프로그램부터 확인하세요.

FakeDNS를 사용할 때는 가상 주소 범위를 사설 네트워크와 겹치지 않게 선택하고, 로컬 라우터나 다른 VPN 도구가 같은 대역을 사용하지 않는지 확인하세요. 주소 충돌이 있으면 특정 내부 사이트가 열리지 않거나, 모든 요청이 잘못된 인터페이스로 빠질 수 있습니다. 또한 FakeDNS를 끈 뒤에도 애플리케이션이나 운영체제에 이전 응답이 캐시되어 있을 수 있으므로, 테스트 사이에 DNS 캐시와 브라우저 연결을 새로 시작하는 편이 좋습니다.

FakeDNS가 모든 사용자에게 필요한 것은 아닙니다. 일반적인 도메인 기반 규칙과 안정적인 원격 DNS만으로 충분한 환경도 많습니다. 연결 구조가 단순한데 FakeDNS까지 추가하면 디버깅 지점만 늘어납니다. 목표가 분명하고 IP 연결 때문에 도메인 판정이 사라지는 문제가 확인된 경우에 단계적으로 적용하세요.

사용자 정의 규칙을 안전하게 관리하기

라우팅 규칙은 넓은 조건보다 구체적인 조건을 먼저 배치하는 것이 기본입니다. 특정 도메인만 직행해야 한다면 해당 도메인 예외를 일반적인 프록시 규칙보다 위에 두세요. 반대로 광고나 추적 도메인을 차단하는 규칙을 사용할 때는 서비스 본체와 인증·CDN 도메인까지 함께 차단하지 않는지 확인해야 합니다. 한 도메인이 여러 하위 도메인을 사용한다면 정확한 도메인 일치, 하위 도메인 일치, 키워드 일치의 범위를 구분해 선택하세요.

사용자 정의 규칙을 작성할 때는 먼저 목적별로 묶는 것이 좋습니다. 예를 들어 로컬 네트워크와 사설 IP는 직행, 업무상 특정 도메인은 직행, 외부 서비스는 프록시, 명확한 광고 도메인은 차단처럼 구분합니다. 규칙 안에 너무 많은 도메인을 한 줄로 넣으면 나중에 예외를 찾기 어렵습니다. 자주 바뀌는 목록은 별도 규칙 파일이나 클라이언트가 제공하는 분류 기능을 활용하고, 수동 JSON에는 꼭 필요한 예외만 남기는 편이 관리에 유리합니다.

outbound의 이름도 의미 있게 정하세요. 예를 들어 proxy, direct, block, dns-out처럼 역할을 분명히 하면 규칙을 읽기 쉽습니다. 이름을 바꾼 뒤에는 해당 이름을 참조하는 모든 규칙이 함께 수정되었는지 확인하세요. outboundTag가 한 글자라도 다르면 JSON 문법은 정상이어도 실제 라우팅은 예상과 다르게 동작할 수 있습니다.

기본 규칙을 크게 바꾸기 전에 필요한 예외부터 추가하고, 변경할 때마다 파일을 저장한 날짜와 목적을 기록하세요. 설정을 여러 장치에서 공유한다면 장치별 inbound, TUN, DNS 차이를 별도로 유지해야 합니다. 데스크톱의 전체 라우팅 설정을 Android 클라이언트에 그대로 붙여 넣는 방식은 권한과 네트워크 구조가 달라 실패하기 쉽습니다.

테스트 순서와 문제 해결 방법

첫 테스트는 설정을 저장한 뒤 클라이언트를 완전히 재시작하는 것부터 시작하세요. 일부 클라이언트는 JSON을 화면에서 수정해도 코어가 즉시 새 값을 읽지 않을 수 있습니다. 그다음 기본 outbound를 사용해 일반 웹사이트를 열고, 직행 대상 도메인과 프록시 대상 도메인을 각각 확인하세요. 같은 사이트를 여러 번 열기보다 서로 다른 도메인과 HTTPS 포트를 사용해야 규칙 차이를 확인하기 쉽습니다.

  1. JSON 문법 오류가 없는지 확인하고 클라이언트를 재시작합니다.
  2. 노드 자체가 연결 가능한지 단순한 프록시 설정으로 먼저 확인합니다.
  3. 직행, 프록시, 차단 대상 도메인을 각각 한 개 이상 테스트합니다.
  4. DNS 확인 사이트나 운영체제의 DNS 상태를 사용해 질의 경로를 비교합니다.
  5. 로그에서 실제 도메인, 적용된 규칙, 선택된 outbound를 확인합니다.
  6. 문제가 있으면 마지막으로 추가한 규칙이나 옵션 하나만 되돌립니다.

도메인은 열리지만 DNS 누출이 의심되면 운영체제 DNS, 브라우저의 보안 DNS, 다른 VPN 또는 보안 프로그램이 별도 질의를 만들고 있지 않은지 확인하세요. 브라우저의 자체 DNS 기능이 Xray 경로를 우회하는 환경도 있습니다. 반대로 DNS는 정상인데 연결이 안 되면 routeOnly, FakeDNS 대역 충돌, 잘못된 outboundTag, TLS 또는 QUIC 처리 문제를 의심할 수 있습니다.

모든 사이트가 프록시로만 나가면 규칙이 없는 것이 아니라, 넓은 프록시 규칙이 위에서 먼저 일치하는 경우가 많습니다. 모든 사이트가 직행하면 기본 outbound나 규칙의 tag가 잘못되었을 가능성이 있습니다. 특정 사이트만 이상하면 sniffing으로 얻은 도메인과 실제 규칙의 도메인 형식이 맞는지, IPv6 주소가 별도 규칙으로 빠지는지 살펴보세요.

최종적으로 안정적인 설정은 가장 복잡한 설정이 아닙니다. 먼저 단순한 DNS 경로와 기본 라우팅을 확인하고, 도메인 판정이 필요한 경우 sniffing을 추가한 뒤, IP 기반 애플리케이션 때문에 문제가 재현될 때 FakeDNS를 검토하세요. 변경 범위를 작게 유지하고 로그로 판정 결과를 확인하면 Xray JSON을 직접 관리하더라도 시행착오를 크게 줄일 수 있습니다.