개발자를 위한 Clash TUN 모드와 터미널 프록시 실전 설정

GitHub clone, npm·pip 패키지 설치, Docker Hub 접속, Homebrew 업데이트, Cursor와 Copilot 연결 문제를 겪는 개발자를 위한 Clash 설정 가이드입니다. TUN 모드로 터미널 트래픽을 자동 라우팅하고 Git·SSH 프록시를 구성하는 방법…

개발 환경에서 프록시 적용 범위부터 구분하기

개발자가 사용하는 네트워크는 브라우저보다 훨씬 복잡합니다. 웹 브라우저는 운영 체제의 시스템 프록시를 비교적 잘 따르지만, 터미널에서 실행하는 curl, Git, npm, pip, Go 모듈 도구, Docker CLI, SSH 클라이언트와 AI 코딩 도구는 각자 다른 방식으로 연결합니다. 따라서 시스템 프록시를 켰는데도 Git clone이나 패키지 다운로드가 실패한다면 노드 자체보다 애플리케이션이 프록시 설정을 읽는지부터 확인해야 합니다.

Clash 또는 mihomo를 개발 환경에 적용하는 방법은 크게 두 가지입니다. 첫 번째는 각 프로그램에 HTTP, HTTPS 또는 SOCKS5 프록시를 직접 지정하는 방식입니다. 이 방식은 동작 범위가 명확하고 문제를 추적하기 쉽지만, 프로그램마다 별도의 설정이 필요합니다. 두 번째는 TUN 모드를 사용해 운영 체제의 네트워크 인터페이스 계층에서 트래픽을 받아 Clash 코어로 전달하는 방식입니다. TUN은 시스템 프록시를 무시하는 프로그램까지 처리할 수 있어 개발 도구를 한꺼번에 연결할 때 유용합니다.

대상 시스템 프록시 환경 변수 또는 전용 설정 TUN 모드
브라우저 대체로 적용됨 필요하지 않은 경우가 많음 적용 가능
curl, wget 구현에 따라 다름 HTTP_PROXY 등으로 적용 적용 가능
Git HTTPS 환경에 따라 다름 git config로 명시 가능 적용 가능
SSH 일반적으로 적용되지 않음 ProxyCommand 또는 전용 프록시 필요 TCP 연결에 적용 가능
Docker 데몬 CLI 설정만으로 부족함 데몬과 빌드 환경을 별도 설정 호스트 트래픽에 적용 가능하나 예외가 있을 수 있음

Clash TUN 모드의 원리와 안전한 기본 설정

TUN 모드는 가상 네트워크 인터페이스를 만들고 운영 체제가 해당 인터페이스로 전달한 IP 트래픽을 Clash 코어가 읽도록 합니다. 애플리케이션이 HTTP 프록시를 지원하지 않거나 시스템 프록시를 무시해도 TCP 및 일부 UDP 트래픽을 규칙에 따라 처리할 수 있다는 점이 핵심입니다. 다만 TUN은 프록시 주소를 단순히 입력하는 기능이 아니며, 가상 인터페이스, 라우팅 테이블, DNS 처리, 권한 및 운영 체제 방화벽의 영향을 함께 받습니다.

mihomo 기반 클라이언트에서는 설정 화면의 「설정」→「TUN」 또는 「서비스 모드」와 비슷한 메뉴에서 TUN을 활성화합니다. 클라이언트에 따라 관리자 권한, 시스템 확장 허용 또는 백그라운드 서비스 설치가 필요할 수 있습니다. 메뉴 이름이 다르더라도 다음 항목을 확인해야 합니다.

  • 활성화 상태: TUN 스위치가 켜져 있고 가상 인터페이스가 실제로 생성되었는지 확인합니다.
  • 자동 라우트: 운영 체제의 기본 경로를 TUN으로 연결할지 결정합니다. 비활성화하면 TUN이 켜져도 일부 트래픽이 우회할 수 있습니다.
  • DNS 모드: 가상 인터페이스와 DNS 처리 방식이 충돌하지 않는지 확인합니다. DNS 오류가 발생하면 웹 연결도 실패할 수 있습니다.
  • 스택 모드: system, gvisor, mixed 등 클라이언트가 제공하는 네트워크 스택을 확인합니다. 성능과 호환성은 운영 체제 및 코어 버전에 따라 달라집니다.
  • 권한: Windows의 서비스 권한, macOS의 네트워크 확장 권한, Linux의 CAP_NET_ADMIN 또는 루트 권한이 필요한지 확인합니다.
mixed-port: 7890
tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
dns:
  enable: true
  enhanced-mode: fake-ip

위 설정은 예시일 뿐이며 현재 사용하는 클라이언트가 지원하는 필드와 기본값을 먼저 확인해야 합니다. mixed-port는 HTTP와 SOCKS 요청을 동시에 받을 수 있는 로컬 포트이고, TUN의 가상 인터페이스 설정과는 별개의 항목입니다. TUN이 켜졌다고 해서 반드시 127.0.0.1:7890으로 환경 변수를 지정해야 하는 것은 아닙니다. TUN은 애플리케이션의 연결을 가상 인터페이스에서 받아 처리하므로, TUN과 명시적 프록시를 동시에 사용하면 이중 적용이나 예기치 않은 우회가 발생할 수 있습니다.

개발 중인 로컬 주소는 우회 목록에 넣기

로컬 개발 서버와 사설 네트워크는 프록시를 거치지 않는 편이 안전합니다. localhost, 127.0.0.1, ::1, 사설 IPv4 대역과 사내 도메인을 프록시로 보내면 핫 리로드 서버, 데이터베이스, Kubernetes API 또는 사내 Git 서버에 접근하지 못할 수 있습니다. 설정의 규칙에서 DIRECT 처리를 확인하고, 회사 네트워크 정책에 맞는 예외만 추가하세요.

rules:
  - DOMAIN-SUFFIX,internal.example,DIRECT
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,PROXY

터미널 도구에 HTTP와 SOCKS 프록시 연결하기

TUN을 사용하지 않고 터미널 도구만 연결하려면 먼저 Clash의 실제 수신 포트를 확인합니다. 흔히 HTTP 포트는 7890, SOCKS5 포트는 7891이지만 구성마다 다릅니다. 제어 포트인 API 주소와 트래픽을 받는 mixed-port를 혼동하지 마세요. PowerShell, Bash, Zsh에서 다음처럼 환경 변수를 지정할 수 있습니다.

# Bash, Zsh
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5://127.0.0.1:7891
export NO_PROXY=localhost,127.0.0.1,::1

# PowerShell
$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:ALL_PROXY = "socks5://127.0.0.1:7891"
$env:NO_PROXY = "localhost,127.0.0.1,::1"

모든 프로그램이 대문자와 소문자 환경 변수를 동일하게 처리하는 것은 아닙니다. 문제가 계속되면 http_proxy, https_proxy, all_proxy, no_proxy도 같은 값으로 지정해 보세요. 단, 회사 내부 주소나 로컬 저장소를 반드시 NO_PROXY에 넣어야 하는 것은 아닙니다. 실제 DNS 이름과 포트, 네트워크 정책을 기준으로 필요한 예외만 관리해야 합니다.

curl과 패키지 매니저 확인

먼저 프록시가 적용되었는지 curl로 확인합니다. 응답 코드만 보지 말고 Clash의 연결 또는 로그 화면에 대상 도메인이 나타나는지도 함께 확인하세요.

curl -I https://registry.npmjs.org/
curl -I https://pypi.org/simple/
curl -I https://proxy.golang.org/
env | grep -i proxy

npm은 환경 변수를 읽는 경우가 많지만 전역 설정을 별도로 저장할 수도 있습니다. pnpm, Yarn, pip, Maven, Gradle, Go 역시 버전과 실행 방식에 따라 환경 변수나 사용자 설정 파일의 우선순위가 달라집니다. 예를 들어 pip는 다음처럼 명시적 프록시를 사용할 수 있습니다.

python -m pip install --proxy http://127.0.0.1:7890 requests

패키지 매니저에서만 인증서 오류가 발생한다면 프록시 연결 실패와 TLS 검증 실패를 분리해야 합니다. 사내 TLS 검사 장비가 개입하는 환경에서는 회사가 제공한 신뢰할 수 있는 CA 인증서를 올바르게 설치해야 하며, 검증을 끄는 옵션을 장기간 사용하는 방식은 권장하지 않습니다.

Git, SSH, Docker와 AI 코딩 도구별 설정

Git HTTPS와 인증 문제

HTTPS 주소로 사용하는 Git 저장소는 Git 전용 프록시를 지정할 수 있습니다. 다음 설정은 모든 HTTPS 저장소에 적용되므로 공용 저장소와 사내 저장소의 연결 정책이 다르다면 호스트별 설정을 사용하는 편이 안전합니다.

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
git config --global --get-regexp 'http.*proxy'

# 설정 제거
git config --global --unset http.proxy
git config --global --unset https.proxy

Git 출력에 Could not resolve host가 표시되면 DNS 또는 규칙 문제일 가능성이 있고, Proxy CONNECT aborted407 Proxy Authentication Required가 보이면 프록시 주소, 인증 또는 포트 유형을 확인해야 합니다. 저장소 주소가 SSH 형식인 git@host:group/repo.git라면 위의 HTTPS 설정은 적용되지 않습니다.

SSH는 별도의 경로가 필요합니다

SSH는 일반적으로 HTTP 프록시 환경 변수를 자동으로 사용하지 않습니다. TUN 모드가 TCP 연결을 정상적으로 가로채면 SSH도 규칙에 따라 처리될 수 있지만, SSH만 별도로 확인하려면 Clash의 SOCKS 포트를 사용하는 ProxyCommand를 설정할 수 있습니다. OpenSSH가 지원하는 명령과 시스템에 설치된 중계 도구의 옵션은 운영 체제마다 다르므로 실제 도움말을 확인해야 합니다.

Host example-server
    HostName ssh.example.com
    User developer
    Port 22
    ProxyCommand connect -S 127.0.0.1:7891 %h %p

SSH 연결이 실패할 때는 먼저 ssh -v example-server로 DNS 확인 단계, TCP 연결 단계, 인증 단계를 구분하세요. 키 인증 실패는 프록시 문제와 무관할 수 있습니다. 또한 내부 서버는 외부 노드로 보내지 않도록 DIRECT 규칙이나 별도 호스트 설정을 적용하는 것이 좋습니다.

Docker CLI와 Docker 데몬 구분하기

docker pull 명령을 실행하는 터미널에 프록시를 설정했다고 해서 Docker 데몬이 같은 프록시를 사용하는 것은 아닙니다. Linux에서는 대개 Docker 데몬이 별도 서비스로 실행되므로 데몬의 systemd 설정에 프록시를 지정해야 합니다. Docker Desktop은 애플리케이션 설정에서 프록시를 관리할 수 있으며, 이미지 빌드 과정의 네트워크와 실행 중인 컨테이너의 네트워크도 서로 다른 설정을 사용할 수 있습니다.

  • 이미지 다운로드 실패: Docker 데몬의 레지스트리 연결과 인증을 확인합니다.
  • docker build 중 패키지 다운로드 실패: 빌드 인자 또는 BuildKit의 프록시 전달 여부를 확인합니다.
  • 컨테이너 내부에서 연결 실패: 컨테이너의 HTTP_PROXY, DNS, 라우팅을 별도로 확인합니다.
  • 사설 레지스트리 실패: 해당 레지스트리를 프록시 예외에 넣어야 하는지 네트워크 담당 정책을 확인합니다.

AI 코딩 도구도 브라우저와 같은 방식으로 동작한다고 가정하면 안 됩니다. 확장 프로그램은 편집기의 프록시 설정을 따를 수 있고, 별도 CLI는 터미널 환경 변수나 자체 설정 파일을 사용할 수 있습니다. 로그인, 모델 목록 조회, 코드 완성 요청, 확장 프로그램 업데이트가 서로 다른 도메인을 사용하기도 하므로 Clash 연결 목록에서 실제 요청 대상을 확인해야 합니다. 인증 토큰이나 API 키는 프록시 설정 파일과 셸 기록에 평문으로 남기지 않도록 주의하세요.

연결 검증과 반복 오류 해결 순서

설정이 끝난 뒤에는 한 번에 여러 도구를 실행하지 말고 계층별로 검증합니다. 먼저 Clash 로그 수준을 Info로 두고, 연결 화면을 열어 둔 상태에서 다음 순서로 테스트하세요.

  1. 코어 확인: 활성 구성, 정책 그룹, 현재 선택된 노드와 코어 실행 상태를 확인합니다.
  2. 로컬 포트 확인: curl 또는 PowerShell로 127.0.0.1의 mixed-port가 수신 중인지 확인합니다.
  3. 도메인 테스트: 공용 HTTPS 주소와 패키지 저장소 주소를 각각 요청합니다.
  4. Git 테스트: HTTPS 저장소에서 git ls-remote를 실행하고 연결 기록을 확인합니다.
  5. SSH 테스트: ssh -v로 프록시 명령이 호출되는지 확인합니다.
  6. TUN 테스트: 명시적 환경 변수를 잠시 해제한 뒤 TUN만 켜고 같은 요청을 반복합니다.
증상 가능성이 높은 원인 확인 방법
브라우저는 되지만 curl은 실패 환경 변수 미설정 또는 포트 유형 오류 env | grep -i proxy와 curl verbose 출력 확인
TUN을 켜면 모든 연결이 느려짐 DNS 처리, 잘못된 라우트 또는 과도한 프록시 적용 DNS 로그, 시스템 라우팅, DIRECT 예외 확인
Git HTTPS는 되지만 SSH는 실패 SSH가 HTTP 프록시 설정을 사용하지 않음 ssh -vProxyCommand 설정 확인
Docker pull만 실패 터미널과 Docker 데몬이 별도 네트워크를 사용함 데몬 로그와 Docker Desktop 프록시 설정 확인
AI 도구 로그인만 실패 별도 인증 도메인, 인증서 또는 앱 프록시 설정 문제 연결 목록에서 로그인 관련 도메인과 오류 코드 확인

자주 묻는 질문

TUN과 터미널 환경 변수를 함께 사용해도 되나요?

가능하지만 처음 진단할 때는 권장하지 않습니다. 환경 변수는 애플리케이션이 지정한 HTTP 또는 SOCKS 프록시로 연결하게 하고, TUN은 운영 체제의 IP 트래픽을 가상 인터페이스에서 처리합니다. 두 경로가 동시에 적용되면 프록시가 다시 프록시로 연결되거나 NO_PROXY와 TUN 규칙이 서로 다른 결과를 낼 수 있습니다. 먼저 한 방식으로 정상 작동을 확인한 뒤 다른 방식을 추가하세요.

TUN을 켜면 localhost 개발 서버에 접속할 수 없습니다. 어떻게 해야 하나요?

localhost, 127.0.0.1, ::1이 프록시 규칙으로 전달되는지 확인하고, 필요하면 DIRECT 예외를 추가하세요. Docker나 가상 머신에서 실행되는 개발 서버라면 실제 접속 주소가 사설 IP 또는 별도 브리지 주소일 수 있으므로 브라우저 주소와 연결 로그에 표시된 IP를 함께 확인해야 합니다.

Git 프록시 설정을 해제했는데도 이전 프록시를 사용합니다.

전역 설정 외에 저장소별 설정, 셸 환경 변수, 운영 체제의 자격 증명 도구가 남아 있을 수 있습니다. git config --show-origin --get-regexp 'http.*proxy'로 설정 출처를 확인하고, env | grep -i proxy 또는 PowerShell의 환경 변수를 점검하세요. 설정을 바꾼 뒤 실행 중인 IDE 터미널을 새로 열어야 할 수도 있습니다.

Docker와 AI 코딩 도구는 TUN만 켜면 항상 연결되나요?

항상 그렇지는 않습니다. Docker 데몬이 호스트와 다른 네트워크 공간에서 실행되거나, 앱이 자체 DNS와 인증서 저장소를 사용할 수 있습니다. AI 도구 역시 로그인 서버, API 서버, 확장 프로그램 저장소가 서로 다를 수 있습니다. Clash 연결 목록과 로그에서 실제 요청이 들어오는지 확인한 다음, 데몬 또는 앱 자체의 프록시와 인증서 설정을 별도로 조정하세요.

Clash 다운로드