왜 WSL2에서는 Windows Clash를 같이 쓰는 편이 편할까요?

WSL2는 가벼운 가상 머신에 가깝기 때문에, 리눅스 안의 127.0.0.1과 Windows 바탕화면의 127.0.0.1이 자동으로 같은 의미가 되지 않습니다. 그래서 개발자들은 종종 「WSL2 Clash 프록시」를 검색해 보지만, 실제로는 Windows 호스트에서 이미 켜 둔 Clash(Clash Verge Rev, Clash for Windows 계열 GUI 등)의 수신 포트로 트래픽을 보내는 구성이 가장 단순합니다. 리눅스 전용 설치 글인 Ubuntu·systemd 튜토리얼과 달리, 여기서는 「코어를 WSL 안에 두지 않고」도 패키지 매니저와 Git이 같은 규칙·노드를 쓰게 만드는 데 초점을 맞춥니다.

이미 Windows에서 Clash Verge Rev를 쓰고 있다면, WSL 쪽 작업은 대부분 포트 번호 확인환경 변수 몇 줄로 끝납니다. 반대로 LAN 공유나 휴대폰으로 퍼뜨리는 시나리오는 LAN 프록시 공유 글과 역할이 겹치므로, 이 글에서는 WSL2와 localhost 포워딩에만 집중합니다.

127.0.0.1이 안 통할 때 이해할 네트워크 모델

과거 WSL1 시절에는 Windows와 더 가깝게 붙어 있어서 상황이 달랐지만, WSL2에서는 리눅스 커널이 별도 네임스페이스를 가집니다. 그 결과 WSL 안에서 curl http://127.0.0.1:7890을 찍으면, 그것은 「리눅스 VM 자기 자신」의 7890 포트를 두드리는 셈이지, Windows의 Clash가 듣고 있는 포트와 자동으로 연결되지 않을 수 있습니다. 최신 Windows·WSL 조합에서는 localhost 전달 옵션이 켜져 있으면 예외적으로 통하는 경우도 있으나, 문서와 커뮤니티에서 가장 많이 쓰는 안정 패턴은 Windows 쪽 가상 어댑터 IP(또는 /etc/resolv.conf에 적힌 네임서버 주소)를 호스트 IP로 삼아 접속하는 방식입니다.

IPv4만 쓰는지, IPv6까지 동시에 쓰는지에 따라 경로가 달라질 수 있습니다. ping으로 호스트에 닿는지 먼저 확인하고, 안 되면 방화벽에서 해당 포트를 허용했는지, Clash가 0.0.0.0이 아니라 127.0.0.1에만 바인딩되어 있지 않은지 순서대로 점검하는 것이 좋습니다.

Clash 쪽에서 확인할 것: mixed-port와 Allow LAN

Clash Meta(Mihomo) 계열 설정에서는 mixed-port 한 줄로 HTTP와 SOCKS를 같은 포트에서 받는 구성이 흔합니다. 예를 들어 mixed-port: 7890이면, WSL에서는 http://호스트IP:7890 형태의 HTTP 프록시와, 클라이언트에 따라 같은 포트의 SOCKS 스킴을 함께 쓸 수 있습니다. 구버전 스타일로 portsocks-port를 나눠 두었다면, apt·git·curl이 주로 쓰는 것은 보통 HTTP CONNECT 또는 HTTPS이므로 port(HTTP) 쪽 번호를 기준으로 잡는 경우가 많습니다.

중요한 점은, 기본값이 루프백 전용 바인딩이면 WSL 같은 다른 인터페이스에서 들어온 연결이 거절된다는 것입니다. 그래서 GUI 클라이언트 설정에서 Allow LAN(비슷한 이름의 옵션)을 켜서 Windows 쪽에서 0.0.0.0 또는 LAN 대역으로 리슨하게 만들어야 합니다. 이 단계를 건너뛰면 호스트 IP를 아무리 정확히 넣어도 연결이 안 붙습니다.

WSL2에서 Windows 호스트 IP 구하는 실무 명령

가장 널리 알려진 방법은 기본 게이트웨이를 읽는 것입니다.

ip route show | grep -i default | awk '{ print $3}'

또 다른 흔한 방법은 Microsoft가 WSL에 넣어 주는 DNS 서버 주소를 이용하는 것입니다. 이 주소가 곧 Windows 호스트를 가리키는 경우가 많습니다.

grep -m1 nameserver /etc/resolv.conf | awk '{print $2}'

두 값이 같지 않을 수도 있으니, 실제로 curl -v --proxy http://IP:PORT https://www.google.com처럼 짧은 요청으로 검증하는 편이 안전합니다. 회사 VPN이나 방화벽 정책이 끼어 있으면 숫자가 바뀌기도 하므로, 세션을 새로 열 때마다 한 번씩 확인하는 습관을 들이면 덜 당황합니다.

bash·zsh에 넣을 환경 변수: http_proxy와 ALL_PROXY

대부분의 CLI 도구는 소문자 http_proxy·https_proxy를 읽고, 일부는 대문자 HTTP_PROXY도 함께 요구합니다. Git 최근 버전은 ALL_PROXY를 쓰는 경우가 많아서, 한 줄로 모든 스킴을 넘기고 싶다면 아래처럼 ALL_PROXY를 HTTP 프록시 URI로 맞춰 두는 방식이 간단합니다.

export HOST_IP=$(ip route show | grep -i default | awk '{ print $3}')
export PROXY_PORT=7890
export http_proxy="http://${HOST_IP}:${PROXY_PORT}"
export https_proxy="http://${HOST_IP}:${PROXY_PORT}"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
export ALL_PROXY="$http_proxy"

ALL_PROXYsocks5://...를 넣을지 http://...를 넣을지는 Clash 쪽 mixed-port 동작과 도구별 지원에 따라 조정합니다. SOCKS만 열어 둔 환경이라면 ALL_PROXY=socks5://${HOST_IP}:7891처럼 포트를 분리하는 편이 맞습니다.

내부 Git 서버나 사내망 대역은 프록시를 타면 오히려 깨지므로, NO_PROXY·no_proxylocalhost,127.0.0.1,::1,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 등 필요한 패턴을 추가해 두는 것이 운영에 편합니다.

apt만 별도로: Acquire::http::Proxy 설정

환경 변수만으로도 동작하는 경우가 있지만, Debian·Ubuntu 계열에서는 /etc/apt/apt.conf.d/ 아래에 스니펫을 두는 방식이 명확합니다.

echo 'Acquire::http::Proxy "http://'"$HOST_IP"':'"$PROXY_PORT"'/";
Acquire::https::Proxy "http://'"$HOST_IP"':'"$PROXY_PORT"'/";' | sudo tee /etc/apt/apt.conf.d/95clash-wsl-proxy

프록시를 끄고 싶을 때는 해당 파일을 삭제하거나 내용을 비우면 됩니다. 사내 미러를 쓰는 팀이라면, 미러 주소만 DIRECT로 빼고 나머지는 프록시를 타게 하는 식으로 분리하는 경우도 있습니다.

git clone·fetch: http/https 프록시와 주의할 SSH

HTTPS 원격 저장소라면 보통 위의 환경 변수만으로도 충분합니다. 명시적으로 남기고 싶다면 사용자 단위로 다음과 같이 설정할 수 있습니다.

git config --global http.proxy  "http://${HOST_IP}:${PROXY_PORT}"
git config --global https.proxy "http://${HOST_IP}:${PROXY_PORT}"

반면 [email protected]:... 형태의 SSH는 HTTP 프록시 환경 변수를 그대로 따르지 않습니다. 이 경우에는 ~/.ssh/configProxyCommand로 nc·connect-proxy 등을 지정하거나, HTTPS 원격으로 바꾸는 선택지를 검토해야 합니다. 팀 정책상 SSH만 허용된다면 네트워크 담당자와 먼저 맞추는 것이 좋습니다.

curl·wget·기타 도구

curl--proxy 옵션으로 즉석 테스트하기 좋고, 환경 변수가 잡혀 있으면 별도 옵션 없이도 동작합니다. wget 역시 대부분의 빌드에서 동일한 변수를 읽습니다. Python pip나 Node npm은 각각 자체 설정이 있으므로, 이 글 범위를 넘어서지만 원리는 같습니다. 「Windows 호스트 포트」로 나가는 트래픽이 Clash 규칙에 맞게 잡히는지만 대시보드나 로그로 확인하면 됩니다.

TUN 전역 라우팅과의 차이

Windows 쪽에서 TUN 모드를 켜 두면 브라우저나 일부 앱은 투명하게 프록시를 탈 수 있지만, WSL2 내부의 리눅스 스택까지 항상 같은 방식으로 감싸이는 것은 아닙니다. 개념 정리는 TUN 모드 상세 글을 참고하되, 본 글에서 다루는 패턴은 「리눅스 프로세스가 스스로 HTTP 프록시로 나간다」는 명시적 모델입니다. 재현성과 트러블슈팅이 쉬운 편이라, 개발용 WSL에서는 이 방식을 기본값으로 두는 팀이 많습니다.

자주 나는 오류와 점검 순서

Connection refused

Allow LAN이 꺼져 있거나, Clash가 아직 기동되지 않았거나, 포트 번호가 mixed-port와 다르게 적혀 있는 경우가 대부분입니다. Windows 방화벽에서 수신을 막고 있지 않은지도 함께 확인합니다.

TLS handshake 실패·인증서 오류

중간에 HTTPS 가로채기를 하는 보안 제품이 있으면 체인이 깨질 수 있습니다. 같은 증상이 브라우저에서도 나는지 먼저 비교해 보세요.

느리거나 간헐적으로만 된다

DNS가 WSL과 Windows에서 다르게 동작하면 첫 연결만 지연되는 패턴이 나옵니다. Clash의 DNS 섹션과, 리눅스 쪽 /etc/resolv.conf가 VPN에 의해 덮어쓰이는지도 점검합니다.

정리

WSL2 Clash 프록시라는 말은 결국 「리눅스 안에서 Windows 호스트 IP와 Clash가 연 mixed-port(또는 http/socks 포트)로 나간다」는 뜻에 가깝습니다. apt git 프록시는 환경 변수와 apt 전용 지시자를 나누어 두면 디버깅이 쉬워지고, ALL_PROXY 설정은 Git·범용 CLI를 한꺼번에 묶는 데 유리합니다. 같은 머신에서도 루프백이 아닌 별도 인터페이스를 경유한다는 점만 기억하면, 나머지는 일반적인 리눅스 프록시 구성과 크게 다르지 않습니다.

Windows 쪽 클라이언트 설치·구독 가져오기는 이미 정리된 가이드를 따라가면 되고, 리눅스 네이티브에 코어를 깔고 싶다면 앞서 인용한 Ubuntu 글을 이어 붙이면 됩니다. 설치 파일과 업데이트 경로는 Clash 공식 다운로드 페이지에서 플랫폼별로 확인할 수 있습니다. 준비가 되었다면 → Clash를 무료로 내려받아 Windows와 WSL2 작업 흐름에 맞춰 적용해 보세요.