이 글이 말하는 증상

Clash(또는 Verge·GUI 래퍼)를 실행해 시스템 프록시나 브라우저 확장을 켜 두면 Edge·Chrome은 잘 나가는데, 같은 PC에서 PowerShell·Windows Terminal·Git Bashgit clone·npm install·curl만 하면 연결이 끊기거나 매우 길게 멈춥니다. 반대로 브라우저에서만 프록시를 쓰고 OS 설정은 비어 있으면, 터미널은 당연히 직접 연결을 시도합니다. 사용자 입장에서는 “Clash는 켰는데 왜 터미널만 안 되지?”로 느껴지지만, 실제로는 애플리케이션이 어떤 경로로 프록시 주소를 읽는지가 갈라진 결과입니다.

이번 가이드는 PC 전체를 TUN으로 다시 깔지 않고, 이미 쓰고 있는 Clash의 혼합 포트에 맞춰 현재 사용자 계정 기준으로 터미널 환경변수와 Git·npm 설정을 맞추는 흐름에 초점을 둡니다. Docker나 스마트폰 LAN 프록시처럼 다른 축의 주제는 Docker 레지스트리 분기·LAN 프록시 가이드에 두고, 여기서는 로컬 개발자 터미널만 다룹니다.

시스템 프록시와 터미널 환경변수는 별개다

Windows의 “프록시 사용” 설정은 WinHTTP/WinINet 계열과 잘 맞는 앱에는 전달되지만, POSIX 스타일 도구나 일부 CLI는 HTTP_PROXY 같은 대문자·소문자 환경변수를 보지 않으면 그냥 직접 연결합니다. Git은 자체 설정(http.proxy)과 환경변수를 함께 고려하고, npm은 .npmrc와 환경변수를 섞어 쓰므로, 한 군데만 맞춰 두고 나머지는 비어 있는 상태가 흔한 원인입니다.

정리하면, 브라우저가 잘 된다는 사실은 “인터넷이 된다”는 뜻이지, “터미널도 같은 출구를 쓴다”는 뜻이 아닙니다. 개발 업무를 Clash 한 줄로 맞추려면 시스템 프록시 ON과 별도로, 사용하는 셸과 도구가 읽는 http_proxy / https_proxy / all_proxy를 명시하는 편이 가장 예측 가능합니다. 클라이언트별 UI 이름은 다르지만, “시스템 프록시 켜기” 토글이 켜져 있어도 터미널에 변수가 없으면 여전히 직결로 나갈 수 있다는 점을 기억하세요.

PowerShell에서 $env:HTTP_PROXY를 출력해 비어 있는지 먼저 확인하세요. 비어 있으면 대부분의 크로스 플랫폼 CLI는 프록시 없이 나가려 합니다.

혼합 포트(mixed-port)와 포트 번호 읽는 법

Clash Meta·mihomo 계열은 보통 mixed-port라는 하나의 TCP 포트에서 HTTP CONNECT와 SOCKS5를 동시에 받습니다. 구형 구성처럼 HTTP용 포트와 SOCKS용 포트를 나누지 않아도 되므로, 문서에서 “Mixed Port에 맞춰라”고 할 때의 숫자가 바로 그 값입니다. 클라이언트 설정 화면에 Mixed Port 또는 동일 의미의 필드가 있으면 그 숫자를 메모하고, 로컬 루프백 주소 127.0.0.1과 조합합니다.

환경변수에는 보통 http://127.0.0.1:포트 형태를 넣습니다. Git의 HTTP(S) 트래픽은 이 형태가 잘 맞고, npm 역시 동일합니다. 반면 UDP나 DNS를 프록시로 태우는 특수한 요구는 mixed 한 포트만으로 부족할 수 있어, 그때는 별도 SOCKS 포트나 TUN을 검토하게 됩니다. 이 글의 범위는 “HTTP 기반 clone·registry”에 맞춘 혼합 포트 + 환경변수 조합입니다. YAML에서 포트를 고정해 두었다면 YAML 설정 가이드와 숫자가 일치하는지도 함께 확인하세요.

PowerShell에서 현재 세션만 빠르게 걸기

먼저 mixed-port 값을 7890이라고 가정합니다(실제 값으로 바꿔 주세요). 현재 창에만 적용하려면 아래와 같이 설정할 수 있습니다. 대소문자 혼용을 피하려면 관례적으로 대문자 키를 쓰는 팀도 많고, 일부 도구는 소문자만 읽기도 하므로 둘 다 같은 값으로 맞추는 방식이 안전합니다.

$port = 7890
$proxy = "http://127.0.0.1:$port"
$env:HTTP_PROXY = $proxy
$env:HTTPS_PROXY = $proxy
$env:http_proxy = $proxy
$env:https_proxy = $proxy
# optional: route git+ssh style tools that honor ALL_PROXY
$env:ALL_PROXY = $proxy
$env:all_proxy = $proxy

이 설정은 해당 PowerShell 창을 닫으면 사라집니다. 여러 터미널을 동시에 쓰면 각 창마다 다시 넣어야 하므로, 매일 쓴다면 사용자 환경 변수로 올리거나 프로필 스크립트에 넣는 편이 낫습니다. 회사 보안 정책으로 시스템 전역 변수 변경이 금지돼 있으면, 프로젝트별 .env 로더나 셸 alias로 한정하는 방법도 있습니다.

“현재 사용자만” 영구 환경변수로 넣기

TUN을 켜지 않고도, 현재 로그온한 사용자에게만 프록시 변수를 남기려면 Windows 설정의 “환경 변수” 편집 화면에서 사용자 영역에 추가하면 됩니다. 시스템 전역과 사용자 전역이 겹치면 우선순위 규칙에 따라 덮어쓰이므로, IT 부서가 이미 프록시를 밀어 넣은 PC라면 충돌하는 값이 없는지 먼저 확인하는 것이 좋습니다.

Clash를 끄는 순간에도 변수가 남아 있으면, 그때는 터미널이 존재하지 않는 포트로 붙으려다 실패합니다. 그래서 실무에서는 “Clash 켤 때만 켜는 배치 파일”로 변수를 세팅하고, 끌 때는 창을 닫는 방식을 쓰기도 합니다. 반대로 항상 켜 두는 개발 전용 PC라면 사용자 환경 변수가 편합니다.

Git: http.proxy와 환경변수 정렬

Git은 git config --global http.proxy와 환경변수를 동시에 볼 수 있습니다. 한쪽만 오래된 값이 남아 있으면 “변수는 새 값인데 실제로는 예전 프록시로 간다”는 상황이 생깁니다. 우선 다음으로 전역 설정을 확인하세요.

git config --global --get http.proxy
git config --global --get https.proxy

mixed-port에 HTTP 스킴으로 맞출 경우 예시는 다음과 같습니다.

git config --global http.proxy  http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

SSH URL([email protected]:...)는 HTTP 프록시와 별개 계층입니다. SSH 자체를 프록시하려면 ~/.ssh/configProxyCommand 등이 필요하고, 이 글의 범위를 넘어갑니다. HTTPS 원격만 문제라면 위 설정으로 대부분 해결됩니다. 자격 증명 관리자나 회사 중간 프록시가 끼어 있으면 증상이 달라질 수 있으니, 같은 저장소에 대해 브라우저와 Git의 경로가 같은지 비교해 보세요.

npm과 pnpm: 레지스트리 트래픽만 걸기

npm은 proxy / https-proxy 항목을 .npmrc에 두거나, 환경변수를 읽습니다. 팀마다 레지스트리 미러가 다르므로, 사내 Verdaccio만 직결하고 나머지는 프록시를 타게 하려면 NO_PROXY 설계가 함께 따라와야 합니다. 기본 public registry만 쓴다면 환경변수만으로도 충분한 경우가 많습니다.

npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

명령이 끝까지 가지 않을 때는 npm ping이나 npm config get registry로 먼저 레지스트리 URL이 기대와 같은지 확인하세요. 레지스트리 자체가 내부망이라면 프록시를 태우는 순간 오히려 막힐 수 있습니다.

SOCKS가 필요할 때: 스킴과 포트를 헷갈리지 않기

혼합 포트는 한 리스너에서 HTTP와 SOCKS를 함께 다루지만, 환경변수에 넣는 URL 스킴은 도구마다 다릅니다. ALL_PROXY=socks5://127.0.0.1:7891처럼 옛 SOCKS 전용 포트를 가정한 예제를 그대로 복사하면, 실제 mixed는 7890인데 7891로 붙어 실패하는 일이 잦습니다. 문서 예제의 숫자는 항상 자신의 클라이언트 화면 값으로 바꿔야 합니다.

원격 DNS를 프록시 쪽에서 해석하게 하려면 socks5h:// 스킴을 요구하는 도구도 있습니다. Git·curl·일부 라이브러리 조합에서는 SOCKS 스킴이 맞고, 또 다른 조합에서는 HTTP가 더 안정적입니다. 증상이 재현될 때는 한 번에 여러 줄을 바꾸지 말고, HTTP 스킴 + mixed-port로 먼저 통과시킨 뒤 필요하면 SOCKS로 옮기는 순서가 디버깅에 유리합니다.

NO_PROXY: 국내·사내 주소를 빼는 이유

환경변수 프록시를 켜 두면 모든 HTTP 클라이언트가 기본적으로 그 출구를 탑니다. 그 상태에서 사내 GitLab이나 사설 IP 대역까지 프록시로 끌고 가면, 노드 쪽에서 막히거나 라우팅이 꼬여 타임아웃이 납니다. 그래서 NO_PROXYlocalhost,127.0.0.1,::1,.local,.corp.example.com,10.0.0.0/8처럼 직접 연결해야 할 접미사와 대역을 넣는 패턴이 표준에 가깝습니다.

Windows와 도구마다 NO_PROXY 문법 지원이 조금씩 다릅니다. 쉼표 구분은 공통적으로 많이 쓰이지만, 와일드카드 지원 여부는 런타임에 따라 다릅니다. 막힐 때는 우선 최소한으로 127.0.0.1,localhost만 넣고 범위를 넓혀 가며 재현을 줄이는 접근이 안전합니다.

주의

회사 단말에서는 보안 정책상 프록시 우회 변수가 금지되거나 로그 대상일 수 있습니다. 전역 변수를 추가하기 전에 내부 규정을 확인하세요.

자주 있는 함정 체크리스트

첫째, localhost 대신 127.0.0.1을 쓰면 IPv6 우선 해석 때문에 미묘하게 실패하는 사례가 줄어듭니다. 둘째, Clash를 관리자 권한이 아닌 일반 사용자로 띄우고 있다면 방화벽 규칙은 통과하지만, 다른 사용자 세션에서 연 CLI는 같은 변수를 못 읽을 수 있습니다. 셋째, WSL2는 별도 리눅스 네임스페이스라서 Windows 쪽 mixed-port에 붙을 때는 Windows 호스트 IP를 써야 할 때가 있습니다. 이 글은 네이티브 Windows PowerShell 기준이라 WSL은 별도 절차가 필요합니다.

넷째, 구형 가이드가 HTTP_PROXY=http://127.0.0.1:1080을 기본으로 인용하는 경우가 많은데, 지금 쓰는 빌드는 1080이 아닐 수 있습니다. 다섯째, Git Credential Manager가 프록시 없이 토큰 엔드포인트만 호출하다 막히는 경우도 있어, 같은 변수를 쓰는지 확인이 필요합니다. 여섯째, 바이러스 백신의 SSL 검사가 중간에 끼면 인증서 오류로 보일 수 있습니다. 이런 층까지 의심되면 잠시 예외 정책으로 분리 테스트를 하세요.

GUI에서 mixed-port를 바꾼 뒤 꼭 할 일

Clash Verge Rev 등 그래픽 클라이언트에서 포트를 바꾸면, 예전에 박아 둔 사용자 환경변수·Git 전역 설정·npmrc가 전부 옛 숫자를 가리키게 됩니다. 포트를 바꿀 때마다 “한 군데만 수정했다”가 되기 쉬우니, 포트 변경 체크리스트를 메모해 두는 것이 좋습니다. 설치·초기 배선 개념은 Clash Verge Rev Windows·macOS 가이드와 같은 흐름으로 읽으면 UI 위치를 빨리 찾을 수 있습니다.

정리

Windows에서 Clash를 켰다고 해서 터미널이 자동으로 따라오지는 않습니다. 브라우저가 시스템 프록시를 따르는 동안 CLI는 비어 있는 환경변수를 보고 직결로 나가면, 사용자는 “혼합 포트가 잘못됐다”고 오해하기 쉽지만 실제로는 주소를 읽는 층이 다르기 때문입니다. mixed-port 숫자를 기준으로 http://127.0.0.1:포트HTTP_PROXY·HTTPS_PROXY에 박고, Git·npm 설정을 같은 값으로 맞춘 뒤, 사내 주소는 NO_PROXY로 빼면 재현성이 크게 좋아집니다.

TUN을 새로 열지 않아도 개발 워크플로는 정리할 수 있고, 문제가 생겼을 때 되돌리기도 환경변수 몇 줄이라 비교적 쉽습니다. 설치 파일과 릴리스 채널은 공식 배포 페이지를 기준으로 맞추는 것이 버전 혼선을 줄입니다. 같은 맥락에서 GUI 클라이언트를 쓰면 포트·시스템 프록시 토글을 한 화면에서 관리하기 쉬워집니다. → Clash를 무료로 내려받아 Windows 터미널 환경을 한 번에 정리해 보세요.