Claude Code를 터미널에서 실행할 때 로그인 페이지가 오래 멈추거나 API 요청이 간헐적으로 실패한다면, 먼저 애플리케이션 자체보다 네트워크 경로를 확인해야 합니다. Claude Code는 브라우저처럼 v2rayN의 시스템 프록시 버튼을 자동으로 따라가는 프로그램이 아닐 수 있습니다. v2rayN이 정상적으로 실행 중이어도 터미널 프로세스에 HTTP_PROXY, HTTPS_PROXY 또는 ALL_PROXY 환경 변수가 전달되지 않으면 Claude Code는 일반 네트워크로 접속합니다.
이 글에서는 Windows의 v2rayN을 기준으로 국내 네트워크에서 Claude Code의 터미널 연결을 안정화하는 방법을 설명합니다. v2rayN에서 구독을 가져오고 Xray 코어와 노드를 확인한 뒤, 로컬 HTTP 또는 SOCKS5 포트를 터미널에 연결합니다. 마지막으로 NO_PROXY, TUN 모드, DNS와 라우팅을 점검해 “v2rayN은 연결됐지만 Claude Code만 실패하는” 상황을 구분합니다. macOS, Linux에서는 같은 환경 변수 개념을 셸 문법에 맞게 적용하면 됩니다.
v2rayN에서 사용 가능한 노드를 먼저 확인하고, 터미널에는 v2rayN의 로컬 프록시 포트를 명시적으로 지정하세요. 일반적으로 HTTP 프록시는 웹 기반 CLI에 적용하기 쉽고, SOCKS5는 범용성이 높습니다. 연결 후에는 환경 변수 출력, 프록시 경유 요청, Claude Code 로그인 상태와 Xray 로그를 순서대로 확인하면 원인을 빠르게 좁힐 수 있습니다.
Claude Code와 v2rayN의 프록시 연결 구조
터미널 프록시 설정은 네 단계로 나누어 이해하는 것이 좋습니다. 첫째, v2rayN이 구독에서 가져온 노드 중 하나를 활성 서버로 설정합니다. 둘째, Xray 코어가 로컬에서 HTTP 또는 SOCKS5 인바운드 포트를 엽니다. 셋째, 현재 셸의 환경 변수에 그 포트를 등록합니다. 넷째, Claude Code가 실행될 때 해당 환경 변수를 읽고 원격 API 요청을 프록시로 보냅니다. 이 중 어느 하나라도 빠지면 브라우저는 연결되는데 터미널만 실패할 수 있습니다.
v2rayN의 “시스템 프록시” 기능과 터미널 환경 변수는 서로 다른 제어 방식입니다. 시스템 프록시는 운영체제 프록시 설정을 참조하는 프로그램에 영향을 주지만, 모든 CLI가 이 설정을 읽는 것은 아닙니다. 반대로 환경 변수는 현재 터미널에서 시작된 프로세스에 직접 전달됩니다. 따라서 Claude Code처럼 Node.js 기반 CLI를 사용하는 경우에는 시스템 프록시를 켜는 것만으로 충분하다고 가정하지 말고, 셸에 프록시 주소를 명시하는 편이 확인하기 쉽습니다.
국내 회선에서 접속이 불안정한 경우에도 프록시를 무조건 켜기보다 목적지별 라우팅을 먼저 정해야 합니다. Claude Code가 사용하는 API와 인증 관련 도메인은 프록시로 보내고, localhost, 사설 IP, 로컬 개발 서버는 직접 연결로 남기는 구성이 일반적입니다. 전체 트래픽을 TUN으로 넘기는 방식은 환경 변수 누락을 보완할 수 있지만, DNS와 라우팅 규칙까지 함께 점검해야 하므로 처음 설정할 때는 명시적인 터미널 프록시가 더 단순합니다.
v2rayN 노드와 로컬 포트 준비
먼저 v2rayN을 실행하고 구독 그룹이 최신 상태인지 확인합니다. 메인 화면의 「订阅分组」에서 대상 그룹을 선택한 다음 구독 업데이트를 실행하세요. 업데이트가 성공했다는 알림만 확인하지 말고 서버 목록의 노드 수와 마지막 갱신 시각도 함께 살펴봐야 합니다. 같은 이름의 노드가 여러 개 있으면 새로 갱신된 그룹의 항목을 선택하고, 해당 노드를 활성 서버로 설정한 뒤 Xray 코어를 다시 시작합니다.
구독 갱신
v2rayN 메인 화면에서 「订阅分组」을 열고 대상 그룹을 선택한 뒤 업데이트를 실행합니다. 비공개 구독 주소는 공개 로그나 화면 캡처에 포함하지 마세요.
노드 활성화
서버 목록에서 테스트할 노드를 선택하고 「设为活动服务器」와 같은 활성화 명령을 실행합니다. 단순히 행을 클릭한 것과 실제 활성 서버가 된 것은 다를 수 있습니다.
코어 확인
「设置」→「参数设置」에서 사용할 Core 유형을 확인합니다. VLESS와 REALITY를 사용하는 구독이라면 해당 설정을 처리할 수 있는 Xray 계열 코어가 필요합니다.
포트 기록
v2rayN의 로컬 HTTP와 SOCKS 포트 값을 기록합니다. 예시로 HTTP
127.0.0.1:10809, SOCKS5127.0.0.1:10808을 사용하되 실제 설정값과 반드시 대조하세요.기본 연결 확인
먼저 브라우저 또는 v2rayN의 연결 테스트로 활성 노드가 작동하는지 확인합니다. 노드 자체가 실패하는 상태에서 Claude Code 환경 변수만 수정하면 문제를 분리하기 어렵습니다.
HTTP 프록시
- 주소
- 127.0.0.1
- 예시 포트
- 10809
- 변수
- HTTP_PROXY, HTTPS_PROXY
HTTPS 요청을 HTTP CONNECT 방식으로 전달할 때 먼저 시도하기 좋은 방식입니다.
SOCKS5 프록시
- 주소
- 127.0.0.1
- 예시 포트
- 10808
- 변수
- ALL_PROXY
HTTP와 HTTPS 외의 연결까지 포괄할 수 있지만 클라이언트가 SOCKS 환경 변수를 지원하는지 확인해야 합니다.
HTTP와 SOCKS5 중 어떤 포트를 선택할지는 Claude Code가 실행되는 런타임과 현재 v2rayN 설정에 따라 결정합니다. 우선 HTTP 포트로 테스트하고, 요청이 전달되지 않거나 특정 도구가 SOCKS5만 요구할 때 SOCKS5를 시도하세요. 두 포트를 동시에 등록하면 프로그램별 우선순위가 달라질 수 있으므로 첫 검증에서는 한 가지 방식만 사용해야 합니다.
결론: 시스템 프록시보다 프로세스 경로를 확인하세요
브라우저가 열리는 것보다 중요한 것은 Claude Code를 실행한 동일한 터미널 프로세스가 127.0.0.1의 v2rayN 포트로 요청을 보내는지입니다. 환경 변수와 로컬 포트 테스트가 통과한 뒤에야 노드 변경이나 TUN 전환을 고려하는 것이 효율적입니다.
Windows 터미널에 프록시 적용하기
PowerShell에서는 현재 창에만 적용되는 임시 변수와 이후 새 터미널에도 남는 영구 변수를 구분해야 합니다. 먼저 임시 변수로 동작을 확인하는 것이 안전합니다. 아래 예시는 v2rayN의 HTTP 포트가 10809일 때의 설정입니다.
$env:HTTP_PROXY = "http://127.0.0.1:10809"
$env:HTTPS_PROXY = "http://127.0.0.1:10809"
$env:NO_PROXY = "localhost,127.0.0.1,::1"
claude
명령을 실행한 뒤 같은 PowerShell 창에서 Claude Code를 시작해야 합니다. 다른 창을 열면 임시 변수는 전달되지 않습니다. 현재 값이 실제로 등록되었는지 확인하려면 다음 명령을 사용하세요.
Get-ChildItem Env:HTTP_PROXY
Get-ChildItem Env:HTTPS_PROXY
Get-ChildItem Env:NO_PROXY
SOCKS5 포트를 사용하려면 지원되는 환경 변수 형식에 맞춰 다음처럼 설정할 수 있습니다.
$env:ALL_PROXY = "socks5://127.0.0.1:10808"
$env:NO_PROXY = "localhost,127.0.0.1,::1"
claude
환경 변수 이름은 도구와 라이브러리에 따라 대소문자 처리 방식이 다를 수 있습니다. 일부 프로그램은 대문자 변수만 읽고, 일부는 소문자 이름도 확인합니다. 요청이 계속 직접 연결되는 것처럼 보이면 다음 변수를 함께 설정해 비교할 수 있습니다.
$env:http_proxy = $env:HTTP_PROXY
$env:https_proxy = $env:HTTPS_PROXY
$env:no_proxy = $env:NO_PROXY
임시 설정이 확인된 뒤에만 영구 설정을 고려하세요. setx로 저장한 값은 새로 시작한 터미널에서 적용되며 현재 창에는 즉시 반영되지 않습니다. 또한 비밀번호가 포함된 프록시 주소를 환경 변수에 저장하면 다른 프로세스나 진단 화면에 노출될 수 있으므로, 이 글의 로컬 프록시처럼 인증 정보가 없는 주소를 사용하고 자격 증명은 별도의 안전한 방식으로 관리하세요.
setx HTTP_PROXY "http://127.0.0.1:10809"
setx HTTPS_PROXY "http://127.0.0.1:10809"
setx NO_PROXY "localhost,127.0.0.1,::1"
Claude Code를 실행할 때만 프록시를 적용하고 싶다면 영구 변수 대신 PowerShell 함수나 별도 스크립트를 사용하는 방법이 편리합니다. 업무용 셸 전체를 프록시로 만들지 않으므로 국내 서비스, 사내 Git 서버, 로컬 개발 서버가 불필요하게 프록시를 거치는 문제도 줄일 수 있습니다. 반대로 쉘을 닫을 때마다 설정이 사라지는 것이 불편하다면 프로필에 등록하되, 먼저 변수 이름과 포트가 정확한지 확인하세요.
macOS와 Linux 셸에서 적용하는 방법
macOS와 Linux의 Bash 또는 Zsh에서는 export 명령으로 현재 셸과 그 하위 프로세스에 환경 변수를 전달합니다. v2rayN과 동일한 로컬 HTTP 포트를 사용하는 경우 다음과 같이 입력합니다.
export HTTP_PROXY="http://127.0.0.1:10809"
export HTTPS_PROXY="http://127.0.0.1:10809"
export NO_PROXY="localhost,127.0.0.1,::1"
claude
새 터미널을 열 때마다 자동 적용하려면 사용하는 셸에 맞는 초기화 파일에 설정을 추가할 수 있습니다. Zsh는 보통 ~/.zshrc, Bash는 ~/.bashrc 또는 배포판에 따라 ~/.bash_profile을 사용합니다. 파일을 수정한 뒤 source ~/.zshrc처럼 다시 읽거나 터미널을 새로 열어야 합니다. 회사 네트워크나 로컬 저장소를 직접 연결해야 한다면 NO_PROXY에 해당 도메인과 대역을 추가하세요.
export ALL_PROXY="socks5://127.0.0.1:10808"
export NO_PROXY="localhost,127.0.0.1,::1,.local,192.168.0.0/16"
NO_PROXY의 CIDR 지원 여부는 사용하는 런타임과 라이브러리에 따라 다를 수 있습니다. 192.168.0.0/16이 예상대로 처리되지 않으면 필요한 호스트명을 쉼표로 직접 나열하세요. 로컬 개발 서버가 127.0.0.1:3000에서 실행되는 경우에는 localhost와 127.0.0.1을 포함하는 것만으로도 대부분의 불필요한 우회를 막을 수 있습니다.
연결 검증과 로그 분석 순서
Claude Code를 바로 반복 실행하기보다 프록시 경로를 작은 단계로 검증하세요. 먼저 로컬 포트가 열려 있는지 확인하고, 다음으로 프록시를 지정한 HTTP 요청이 성공하는지 살펴봅니다. 그 뒤 환경 변수를 가진 동일한 셸에서 Claude Code를 실행합니다. 인증 화면이나 API 응답이 실패하더라도, 최소한 원격 요청이 Xray까지 도달했는지는 v2rayN 로그에서 확인할 수 있습니다.
Test-NetConnection 127.0.0.1 -Port 10809
curl.exe -I -x http://127.0.0.1:10809 https://example.com
Test-NetConnection이 실패하면 Claude Code 설정이 아니라 v2rayN의 코어, 포트 충돌, 방화벽 또는 잘못된 포트 번호를 먼저 확인해야 합니다. 로컬 포트 테스트는 성공하지만 curl.exe 요청이 실패한다면 활성 노드, 원격 서버 주소, TLS 또는 REALITY 매개변수, 라우팅 정책을 점검하세요. HTTP 포트를 SOCKS5 포트처럼 사용하거나 반대로 지정한 경우에도 연결이 만들어지지 않습니다.
브라우저는 되는데 Claude Code만 실패하나요?
현재 터미널에서 Get-ChildItem Env:HTTP_PROXY로 변수를 확인하세요. 시스템 프록시와 셸 환경 변수는 별개이므로 로컬 포트 주소를 명시해야 할 수 있습니다.
로그인 창에서 계속 멈추나요?
HTTP와 HTTPS 프록시 변수가 모두 같은 HTTP 포트를 가리키는지 확인하고, v2rayN 로그에서 해당 시각에 새 연결이 발생하는지 비교하세요.
로컬 개발 서버까지 프록시로 가나요?
NO_PROXY=localhost,127.0.0.1,::1을 설정한 뒤 새 프로세스에서 다시 실행하세요. 필요한 사설 호스트명은 목록에 추가합니다.
TUN을 켜면 환경 변수가 필요 없나요?
항상 그렇지는 않습니다. TUN이 DNS와 TCP 경로를 올바르게 가로채는지 확인해야 하며, 명시적인 환경 변수 방식과 결과를 비교하는 것이 안전합니다.
v2rayN 로그에는 코어 시작 실패, 포트 점유, DNS 해석 실패, TLS 핸드셰이크 오류, 원격 연결 시간 초과가 서로 다른 형태로 나타납니다. address already in use가 보이면 다른 프로그램이 같은 로컬 포트를 사용하거나 v2rayN 코어가 중복 실행된 상태일 수 있습니다. failed to parse는 구독 데이터나 설정 형식 문제를 의미할 수 있고, i/o timeout은 원격 경로가 제한 시간 안에 응답하지 않았다는 뜻이므로 노드와 네트워크를 함께 확인해야 합니다.
TUN 모드를 사용할 때의 라우팅 점검
환경 변수 방식은 Claude Code처럼 특정 프로세스에만 프록시를 적용할 때 적합합니다. 반면 TUN 모드는 운영체제의 가상 네트워크 인터페이스를 통해 여러 애플리케이션의 트래픽을 코어로 전달합니다. 터미널 프로그램이 프록시 환경 변수를 무시하거나 하위 프로세스가 별도 네트워크 라이브러리를 사용하는 경우 TUN이 대안이 될 수 있습니다.
TUN을 켜기 전에는 관리자 권한 요구, 가상 어댑터 생성, DNS 가로채기, IPv4·IPv6 처리, 사설 주소 예외를 확인해야 합니다. 특히 127.0.0.1, LAN 관리 주소, 로컬 컨테이너 네트워크를 프록시로 다시 보내면 순환 경로가 생길 수 있습니다. v2rayN의 TUN 설정에서 직접 연결 대상과 프록시 대상의 기본 정책을 확인하고, Claude Code가 접근하는 목적지가 실제로 원하는 아웃바운드에 매칭되는지 Xray 로그로 검증하세요.
| 방식 | 적용 범위 | 장점 | 주의할 점 |
|---|---|---|---|
| HTTP 환경 변수 | 현재 셸과 하위 프로세스 | 설정 범위가 명확하고 되돌리기 쉬움 | 프로그램이 변수를 읽어야 함 |
| SOCKS5 환경 변수 | 지원하는 네트워크 라이브러리 | 여러 종류의 연결을 포괄할 수 있음 | 변수 이름과 SOCKS 지원 여부를 확인해야 함 |
| TUN 모드 | 가상 인터페이스를 통과하는 시스템 트래픽 | 환경 변수 설정이 없는 프로그램에도 적용 가능 | DNS, 예외 라우팅, 권한과 순환 경로를 점검해야 함 |
처음에는 HTTP 환경 변수로 Claude Code만 연결하고, 같은 노드에서 브라우저와 API 요청이 안정적인지 확인하는 순서를 권장합니다. 이후 여러 CLI와 개발 도구를 한꺼번에 연결해야 하거나 환경 변수를 지원하지 않는 프로그램이 있다면 TUN으로 범위를 넓히세요. 모드를 변경한 뒤에는 한 번에 여러 규칙을 바꾸지 말고, 로컬 주소 접속과 외부 HTTPS 요청을 각각 테스트해야 어느 규칙에서 문제가 생겼는지 추적할 수 있습니다.