1. 왜 PyPI와 files.pythonhosted를 같이 봐야 하나
사용자가 검색창에 pip 타임아웃을 칠 때 기대하는 답은 보통 「한 줄짜리 명령」이 아니라 재현 가능한 출구 정리입니다. pip는 PEP 503 Simple 레포지토리에서 링크를 읽고, 그다음 https://files.pythonhosted.org/... 같은 URL로 GET을 이어갑니다. 중간에 pypi.io 리다이렉트를 보는 경우도 있어, 도메인 후보를 한 번에 묶어 두는 습관이 안전합니다. 반대로 레지스트리 규칙에 pypi.org만 넣고 CDN 줄을 GEOIP 기본 흐름에 맡기면, 인덱스 요청은 빠른 노드로 갔다가 파일 요청만 느린 노드로 새는 비대칭 지연이 생길 수 있습니다. 이는 mihomo 대시보드에서 연결 행을 hostname별로 정렬해 보면 한눈에 드러납니다.
또한 Python 패키지 관리는 팀마다 --index-url·사내 Artifactory·공용 미러를 섞습니다. 미러 앞단만 맞추고 아티팩트가 여전히 공인 PyPI를 가리키면 Clash 입장에서는 「미러 호스트는 DIRECT인데 실제 다운로드는 막힌 출구로 간다」가 됩니다. 그래서 이 글은 공식 축을 기준으로 규칙을 제시하고, NO_PROXY로 사내 호스트를 빼는 패턴만 덧붙입니다.
2. 증상 구분: 메타 성공 vs 아티팩트 실패
먼저 pip install -v 패키지명로 어느 URL에서 멈추는지 확인하세요. 로그 앞부분은 pypi.org에 대한 JSON·simple 응답이고, 뒤쪽은 대용량 GET이 files.pythonhosted.org로 이동합니다. 앞만 빠르고 뒤만 Read timed out·Connection aborted라면 본문의 분기·DNS 절차가 정확히 겨냥해야 할 부분입니다. 반면 처음부터 TLS 핸드셰이크가 길다면 노드 자체·회선·SNI 정책을 의심하고, 구독·TLS·DNS 로그 글과 같이 봅니다.
한 줄 정리
wheel/sdist 단계만 실패한다면 files.pythonhosted.org 줄을 pypi.org와 같은 정책 그룹으로 올려 두는 것이 첫 번째 수정 후보입니다.
3. 터미널·pip 쪽: HTTP_PROXY와 pip.conf
pip는 Requests 계열 스택을 쓰므로 HTTP_PROXY·HTTPS_PROXY를 일반적으로 따릅니다. npm 글에서 설명한 것처럼 Clash mixed-port(예: 7890)를 http://127.0.0.1:7890로 가리키면 CONNECT가 한 경로로 모입니다. PowerShell에서는 아래와 같이 세션 단위로 넣을 수 있습니다.
# PowerShell: current session (port from your Clash client) $env:HTTP_PROXY = "http://127.0.0.1:7890" $env:HTTPS_PROXY = "http://127.0.0.1:7890" python -m pip install -U pip
팀 표준으로 pip config set global.proxy를 쓸 수도 있지만, 포트가 사람마다 다르면 환경 변수 스크립트가 유지보수에 유리합니다. 사내 미러·localhost는 NO_PROXY에 넣어 이중 홉을 피하세요. Docker 컨테이너 안에서 pip를 돌리면 호스트와 주소 체계가 달라지므로, 컨테이너용 프록시 게이트웨이를 별도로 적어야 합니다.
WSL2는 127.0.0.1이 Linux 커널 루프백이라 Windows 쪽 Clash에 그대로 붙지 못하는 경우가 많습니다. WSL2·호스트 IP 글의 절차로 미러링된 주소를 먼저 확정한 뒤 같은 변수를 넣으면 재시도 횟수가 줄어듭니다.
4. Clash 규칙 예시: pypi 축 도메인 묶기
프로필에서 rules: 상단(우선 매칭)에 PyPI 관련 줄을 모읍니다. 정책 그룹 이름은 본인 YAML의 PROXY·节点选择 등 실제 이름으로 바꿉니다. 핵심은 메타와 바이너리 호스트를 같은 그룹에 두는 것입니다.
# Example rules — replace PROXY with your policy group name rules: - DOMAIN-SUFFIX,pypi.org,PROXY - DOMAIN-SUFFIX,pythonhosted.org,PROXY - DOMAIN-SUFFIX,pypi.io,PROXY
DOMAIN-KEYWORD,pythonhosted처럼 넓게 잡는 방법도 있지만 오탐이 걱정되면 DOMAIN-SUFFIX,files.pythonhosted.org처럼 더 좁혀도 됩니다. 규칙·정책 그룹 가이드와 함께 읽으면 GEOIP나 광고 차단 규칙 뒤에 숨은 예외를 줄일 수 있습니다. rule-provider를 쓰는 경우에도 PyPI 전용 줄은 로컬 rules 앞에 두는 편이 안전합니다.
보안: TLS 검증 오류를 무시하려고 trusted-host를 남용하지 마세요. 프록시·회사 장비가 인증서를 바꾸는 환경이라면 신뢰 저장소와 정책 쪽을 먼저 확인하는 것이 맞습니다.
5. DNS·fake-ip를 pip 프로세스와 맞추기
규칙은 이름 해석 결과와 세트로 작동합니다. mihomo에서 fake-ip를 쓰는데 OS나 IDE 내장 터미널만 시스템 리졸버로 직접 묻고 있으면, 브라우저와 pip가 서로 다른 IP를 본 것처럼 행동합니다. DNS·fake-ip·redir-host 글의 흐름을 PyPI 시나리오에 맞게 단축해 적용하세요. Windows에서는 Chrome·Edge의 보안 DNS(DoH)가 켜져 Clash와 충돌하기도 하니 브라우저 DoH 끄기 글과 교차 점검합니다.
TUN 모드를 켠 상태라면 이론상 전역 라우팅이 잡히지만, UWP·관리자 권한·듀얼 스택 IPv6 조합에 따라 예외가 생깁니다. IPv6·DNS 누수 글에서 환경별 체크리스트를 가져와 병행하면 「간헐적 실패」 원인이 줄어듭니다.
6. 미러·사내 index와의 조합
공용 미러를 쓰면 지리적으로 가까운 경로로 단일화되는 경우가 많지만, 미러 메타가 여전히 공인 files.pythonhosted.org 링크를 내보내면 Clash 규칙은 그대로 필요합니다. 사내 --index-url만 쓰는 팀이라면 해당 호스트는 DIRECT 또는 사내망 전용 그룹을 앞에 두고, 외부 폴백이 남아 있으면 이번 글의 공인 축 규칙을 유지하세요. 미러 제공자 문서에서 허용 도메인·동기화 지연·대체 엔드포인트를 확인하는 것도 운영 리스크를 줄입니다.
대용량 wheel을 자주 받는 CI에서는 PIP_NO_CACHE_DIR·캐시 볼륨 정책과 함께 네트워크 출구를 고정하는 편이 재현성에 유리합니다. 노드 자동 선택 대신 url-test·fallback으로 안정 레인을 묶어 두면 장시간 다운로드 중 끊김이 줄어듭니다.
7. 로그·curl로 호스트 단위 역추적
첫째, 프록시를 켠 동일 셸에서 curl -vI https://pypi.org/simple/pip/와 curl -vI https://files.pythonhosted.org/를 나란히 실행해 TLS·HTTP 단계 지연을 비교합니다. 둘째, mihomo 로그에서 해당 시각의 호스트·정책·노드를 찍습니다. 셋째, pip install을 한 번 더 돌리며 로그의 hostname 순서가 기대와 같은지 확인합니다. 넷째, 문제가 남으면 Clash를 잠시 끄거나 해당 도메인만 DIRECT/다른 그룹으로 바꿔 대조 실험을 합니다.
로그에 호스트가 안 찍힐 때
DNS가 Clash 밖으로 새거나 앱이 프록시를 안 타는 경우입니다. 환경 변수·IDE 터미널 상속·pip config list -v를 함께 보세요.
HTTP/2·중간 장비
특정 회선에서만 느리면 중간 프록시·SSL 검사 장비와의 조합을 의심합니다. 이 경우 노드 교체만으로는 한계가 있을 수 있습니다.
8. 자주 묻는 질문
아래 요약은 본문 흐름을 읽은 뒤 남는 짧은 질문용입니다. 구조화 데이터 FAQPage에도 동일 주제가 실려 검색 결과에 도움이 될 수 있습니다.
pip가 패키지 목록은 보이는데 파일 받기에서만 타임아웃이 날 수 있나요?
가능합니다. PyPI는 메타데이터용 pypi.org와 아티팩트용 files.pythonhosted.org 등으로 트래픽이 나뉩니다. 한쪽만 프록시·DNS 경로가 맞으면 증상이 전형적으로 나타납니다.
국내 PyPI 미러만 쓰면 Clash 분기가 필요 없나요?
미러가 모든 아티팩트 URL을 동일 출처로 바꾸지 않으면 여전히 공인 호스트로 나가는 링크가 남습니다. 팀의 index-url·폐쇄망 정책을 확인하고, 필요한 도메인을 규칙에 포함하세요.
WSL2나 Docker 안의 pip는 왜 호스트와 다르게 실패하나요?
가상 환경의 루프백·게이트웨이·리졸버가 호스트와 다릅니다. 호스트 Clash를 쓸 때는 컨테이너·WSL용 프록시 주소와 DNS를 별도 절차로 맞춰야 합니다.
정리하면, pip install 반복 타임아웃은 단일 스위치 문제가 아니라 PyPI 메타와 files.pythonhosted.org 아티팩트, 그리고 터미널·DNS 경로가 동시에 맞아야 풀리는 사례가 많습니다. Clash·mihomo는 그 호스트 묶음을 정책 그룹으로 고정하고 로그로 검증하기 쉬워, 패키지 의존성을 자주 받는 개발자 워크플로에 잘 맞습니다. 반대로 일괄 토글형 상용 VPN은 앱 내부 설정만으로는 호스트별 출구를 세밀히 맞추기 어렵고, 장애 시 원인 로그를 남기기도 제한적인 경우가 많습니다. 규칙 파일과 대시보드를 직접 다룰 수 있다는 점에서 Clash 계열이 이런 Python 패키지 관리·CI 네트워크 디버깅에 유리합니다.
→ Clash를 무료로 내려받아 mixed-port와 프로필을 정리한 뒤, 위 순서대로 PyPI 축 도메인과 DNS를 맞춰 보세요.
관련 읽기 · 같은 주제
주제 관련도가 높은 읽을거리 — 같은 카테고리의 Clash 실전 가이드.
macOS에서 Homebrew(brew)가 병·GHCR에서 타임아웃 날 때: formula·Bottle CDN·ghcr.io를 Clash(mihomo)로 분기·DNS를 맞추는 실측 (2026)
macOS Homebrew 타임아웃 줄이기: GHCR·formula CDN을 Clash 규칙·DNS로 맞추는 실무(2026).
자세히 보기Intel Mac에 ClashX Pro 설치부터 구독·시스템 프록시·향상 모드(Enhanced) 첫 설정까지 (2026)
인텔 Mac ClashX Pro 설치부터 구독·시스템 프록시·향상 모드 권한까지 첫 설정 순서(2026).
자세히 보기Mihomo Party(mihomo)에서 프록시 모드 바꾸기: 규칙·전역·직통과 시스템 프록시·TUN까지 한 줄기 분기 안내 (2026)
구독 반영 후 규칙·전역·직통 전환 순서와 시스템 프록시·TUN 레이어를 나누는 실무 분기법(Windows・macOS).
자세히 보기