스크립트 한 번 호출보다 Codex CLI가 «한 번에» 맞추기 어려운 이유
IDE나 CI에서는 api.openai.com만 신경 쓰면 되는 경우가 많습니다. 페이로드, 키, 요청 타임아웃 숫자만 잡혀 있으면 흐름이 예측 가능하죠. 그런데 OpenAI Codex CLI는 로컬에서 업데이트 확인을 하고, 설명 문서를 받아 오고, 브라우저로 넘어가 계정 세션을 마친 뒤 다시 터미널로 돌아오는 식의 «반은 CLI, 반은 웹» 경험에 가깝습니다. REST나 스트리밍 API 외에 정적 쉘·스크립트가 다른 도메인에서 내려오기도 하므로, 어느 한 호스트만 엉뚱한 국가·ASN으로 나가도 명령줄에는 긴 침묵이나 중간 단절로 드러납니다. 브라우저라면 점진 로딩으로 눈에 덜 띄는 증상이 CLI에서는 곧바로 «전부 실패」처럼 보일 수 있습니다.
그래서 «openai라는 글자가 들어간 건 전부 프록시» 수준의 느슨한 규칙만으로는 부족할 때가 많습니다. chatgpt.com이나 oaistatic.com 계열을 빠뜨리면 정적 자원만 직행하고 본체 요청만 우회하는 식의 갈라짐이 생기며, 기업 환경에서는 Azure 쪽 엔드포인트를 별도 접미사로 빼야 하는 경우도 있습니다. 또 규칙은 맞는데도 터미널 프로세스가 Clash가 노출한 로컬 포트를 전혀 타지 않는다면 아무 의미가 없습니다. 이 글에서는 먼저 «누가 맞았고 어디로 나갔는지」를 로그로 확정한 다음에야 클라이언트 측 읽기 타임아웃을 늘릴지 판단하는 순서를 권합니다. API만 길게 붙잡는 패턴의 심화 논의는 OpenAI GPT API 타임아웃·재시도 분기와 이어서 읽으면 경계가 분명해집니다.
증상부터 맞추기: 총 타임아웃, TLS, 403, «가져오기 실패」
총 타임아웃은 대개 두 갈래입니다. 연결 타임아웃은 TCP나 TLS 핸드셰이크가 제한 시간 안에 끝나지 않을 때로, DNS, 방화벽, 노드 경로, 혹은 규칙 미적중이 흔한 원인입니다. 읽기 타임아웃은 연결은 됐는데 다음 덩어리 데이터가 오래 안 올 때인데, 큐잉이 긴 모델 응답이나 큰 아티팩트를 받는 중이면 후자가 더 잦습니다. 이 경우 Clash만 의심하면 애플리케이션 타임아웃을 올려야 할 상황을 놓칠 수 있습니다.
TLS 오류 메시지는 사용자에게는 «오래 걸리다가 실패」로만 보일 수 있습니다. 인증서 검증 실패, SNI 간섭, 중간에 끼어든 보안 소프트웨어가 만든 유사 디코드 문제가 대표적입니다. 브라우저는 같은 브랜드 사이트가 정상인데 Codex만 깨질 때도, 터미널이 동일한 프록시와 DNS를 쓰는지를 먼저 의심해야 합니다. 403은 HTTP 응답이 이미 돌아온 경우로, 엣지 봇 차단·지역 정책·계정 한도와 섞이기 쉽습니다. 이럴 때 노드를 무작정 바꾸기보다 상태 코드와 응답 본문 힌트를 함께 보는 편이 낫습니다.
| 터미널에서 보이는 현상 | 가능성이 큰 원인 | 우선 확인 |
|---|---|---|
| 오래 멈췄다가 실패, 로그에 connect 표현 | 규칙 누락, DNS, 노드 품질 | Clash 연결 기록의 호스트명·적중 정책 그룹 |
| 연결 후 한동안 무응답 | 읽기 타임아웃·서버 대기·CDN 직행 | 스트리밍·대용량 작업의 read timeout, CDN 접미사 규칙 |
| TLS alert·certificate류 메시지 | 보안 스택, 신뢰 저장소, 코어·OS 조합 | 가입 스캐너 일시 중지, Meta 버전·문서 확인 |
| 빠르게 403 | 계정·지역·자동화 클라이언트 정책 | API 권한·CLI 버전·공지, 프록시는 부차적 |
API와 CDN: DOMAIN-SUFFIX를 어떻게 쌓아야 빈틈이 안 생기나
유지 보수 관점에서 DOMAIN-SUFFIX,openai.com 한 줄은 api.openai.com, platform.openai.com, auth.openai.com 류를 넓게 덮는 기준선입니다. 다만 Codex와 ChatGPT 생태는 2026년 현재 여러 최상위 브랜드 도메인이 같이 돌아갑니다. 웹 세션이 chatgpt.com으로 열리는데 규칙에는 openai.com만 있다면, 정작 중요한 호스트 절반이 직행하고 나머지만 우회하는 이결합이 생깁니다. 터미널에서는 이런 편향이 UI 없이 바로 오류로 이어집니다.
실무에서는 다음 층을 함께 두는 편이 안전합니다. 첫째, 가장 중요한 호스트는 DOMAIN,api.openai.com처럼 한 줄로 앞당겨 MATCH나 지나치게 넓은 GEOIP에 잡히지 않게 합니다. 둘째, DOMAIN-SUFFIX로 openai.com과 제품에 따라 필요한 chatgpt.com, 로그에서 반복되는 정적 자원 접미사를 묶습니다. 셋째, Azure OpenAI를 쓰는 팀은 openai.azure.com 같은 Azure 전용 접미사를 별도 줄로 빼야 합니다. 자세한 공존 패턴은 기본 분기 글의 Azure 절을 함께 보세요. CLI가 업데이트될 때마다 새 호스트가 튀어나오면, 미리 완벽한 표를 상상하기보다 로그에 찍힌 실제 이름을 기준으로 접미사를 보강하는 게 가장 빠릅니다.
rules: - DOMAIN,api.openai.com,OpenAI-Dev - DOMAIN-SUFFIX,openai.com,OpenAI-Dev - DOMAIN-SUFFIX,chatgpt.com,OpenAI-Dev # Append CDN/static host suffixes you observe in connection logs (examples vary by release) - DOMAIN-SUFFIX,oaistatic.com,OpenAI-Dev - DOMAIN-SUFFIX,openai.azure.com,OpenAI-Dev
DOMAIN 줄을 넓은 DOMAIN-SUFFIX보다 위에 두고, 전체 흐름은 Clash YAML 규칙 분기 가이드에서 설명하는 일반 순서와 맞춥니다. 그렇지 않으면 OpenAI 묶음 전에 MATCH가 먼저 잡아먹어 «분기를 넣었는데도 DIRECT로 간다»는 상황이 반복됩니다.
정책 그룹: «명령줄용 출구」는 지연이 아니라 지터가 문제
API 호출과 정적 자원이 같은 그룹을 쓴다면, 그 그룹이 추구해야 할 값은 단순히 ping이 가장 짧은 노드가 아니라 지터가 낮게 유지되는 노드에 가깝습니다. Codex 한 작업이 여러 왕복을 거치기 때문에 노드가 자주 바뀌면 겉으로는 간헐 실패처럼, 길게는 총 소요 시간만 늘어난 것처럼 보입니다. url-test와 fallback 모두 쓸 수 있지만, 탐침 URL은 실제 HTTPS 경로와 너무 동떨어지지 않게 잡는 편이 오탐을 줄입니다. 탐침 주기도 지나치게 짧으면 탐침 트래픽 자체가 구독을 흔들 수 있습니다.
비교 실험이 필요하면 잠시 select로 한 노드를 고정하고 동일 세션에서 로그를 보면, 패킷 드롭이나 reset이 재현되는지가 분명해집니다. 이는 GUI에서 노드를 수동으로 찍는 것과 같은 디버깅입니다. Node·npm 등 다른 개발 도구와 함께 프록시를 쓰는 패턴은 Cursor와 npm 개발자 프록시 글과 교차해 보면, 어떤 바이너리는 환경 변수를 보고 어떤 건 시스템 프록시만 보는지 한눈에 정리하기 쉽습니다.
터미널 환경 변수와 TUN: 무엇을 병행해야 하나
많은 개발자가 시스템 설정에서 프록시를 켠 뒤 브라우저만 정상이라고 착각합니다. 터미널 프로세스는 GUI 프록시를 자동 상속하지 않습니다. 그래서 셸 설정에 HTTPS_PROXY=http://127.0.0.1:7890처럼 Clash 혼합 포트나 HTTP 리스너에 맞춰 export하는 방식이 일반적입니다. 필요하면 ALL_PROXY와 사내 네트워크 예외도 함께 둡니다. VS Code 통합 터미널이라면 해당 세션이 동일한 rc 파일을 읽었는지까지 확인해야 합니다.
환경 변수를 믿기 어려운 바이너리가 있으면 TUN 모드로 OS 전체 트래픽을 끌어당기는 방법도 있습니다. 대신 라우팅 표와 DNS 상호작용 부담이 커집니다. 어느 쪽을 택하든 검증 기준은 하나입니다. Codex를 재현하는 동안 Clash 연결 패널에 기대한 호스트명이 뜨는지, 그리고 정책 그룹이 설계와 같은지입니다. 연결 자체가 안 보이면 먼 원인을 찾기 전에 로컬 경로부터 고쳐야 합니다.
DNS와 fake-ip: API 장애로 착각하기 쉬운 해석 문제
fake-ip를 쓰는 프로필에서 규칙·DNS·redir-host 조합이 어긋나면 간헐적으로만 연결이 깨집니다. 자동화 CLI는 재시도 비용이 커서 이런 드문 실패가 특히 거슬립니다. fake-ip·redir-host DNS 문제 해결에서 제시하는 필터 순서와 실제 해석 결과를 Codex 재현 직전에 다시 맞춰 보세요. 로컬 DoH나 개인 hosts가 있으면 Codex 프로세스가 보는 결과가 코어 내부 매칭과 달라질 수 있습니다. TLS 버전이 낮거나 체인이 깨진 환경에서는 프록시를 끄고도 같은 증상이 반복되는지 먼저 확인해 운영체제·코어 버전 점검으로 방향을 트는 것이 YAML 전체 재작성보다 빠른 경우가 많습니다.
실측 루틴: 이십 분 안에 돌릴 최소 루프
여러 설정을 동시에 바꾸면 어디가 효과였는지 기억하기 어렵습니다. 고정 순서를 추천합니다. 첫째, Clash 연결 로그를 비우거나 필터를 걸고 같은 터미널 세션에서 Codex 최소 재현 커맨드를 실행합니다. 둘째, 로그에 나온 모든 외부 호스트를 적어 현재 DOMAIN-SUFFIX 목록과 diff를 내고, 빠진 접미사는 전부 동일 정책 그룹으로 즉시 추가합니다. 셋째, 낯선 도메인 두세 개만 curl -v로 짧게 때려 규칙 적중을 확인한 뒤 Codex로 되돌아옵니다. 넷째, 여전히 실패하면 환경 변수를 출력해 빈 셸에서 같은 export로 재시험해 rc 로딩 순서 문제를 배제합니다. 다섯째, HTTP는 통과하는데 TLS만 의심되면 보안 소프트웨어를 잠시 끄고 대조하고, 가능한 범위에서 Meta 코어를 최신 권장선으로 올립니다.
이 루프를 한 번 돌고 나면 대부분의 «터미널에만 나타나는」 장애는 접미사 누락, 환경 변수, DNS 오판, 혹은 계정·쿼터 측 하드 오류 중 하나로 좁혀집니다. 매번 규칙 전체를 갈아엎기보다 범주를 나눠 처리하는 편이 시간 대비 효과가 큽니다.
맺으며
2026년 명령줄 개발 도구는 API 한 줄이라기보다 세션·정적 자원·브라우저 리다이렉트가 한 덩어리로 움직이는 경우가 많습니다. Codex류 CLI는 그 전형에 가깝기 때문에 단일 호스트만 보던 습관으로는 규칙이 자주 어긋납니다. 반대로 말하면 연결 로그만 제대로 보면 원인은 대부분 특정할 수 있습니다. DOMAIN-SUFFIX와 정책 그룹으로 출구를 안정화하고, HTTPS_PROXY나 TUN으로 터미널까지 동일한 경로에 올려 놓으면 겉으로는 총 타임아웃 같아 보이던 증상도 상당 부분 원인별로 분해됩니다. 전체 규칙 설계의 뼈대는 YAML 규칙 분기 가이드를, 주제별 모음은 기술 칼럼에서 이어서 보시면 됩니다.
일부 «원클릭 해외 접속» 앱이나 범용 VPN 클라이언트는 닫힌 규칙표나 전역 터널에 의존해 세밀한 도메인 분리가 어렵고, CLI처럼 여러 호스트가 동시에 열리는 작업에서는 전 기기를 무차별 우회하거나 내부망과 개발 트래픽을 구분하지 못하는 한계가 있습니다. 업데이트가 느리면 신규 엔드포인트가 생길 때마다 통째로 끊기기도 합니다. Clash 계열은 Codex, 브라우저, 사내 자원을 한 YAML 안에서 공존시키는 쪽에 강하고, Verge류 GUI는 정책 그룹을 시각적으로 묶어 유지 보수 부담을 덜어 줍니다. ClashNote는 플랫폼별 설치 패키지와 검증된 무료 구독 진입점을 한곳에 모아, 터미널에서 반복되는 환경 변수·우선순위 실수를 줄이도록 돕습니다. 장기적으로 Codex 같은 터미널 AI를 쓸 계획이라면 다운로드 허브에서 클라이언트와 구독 출발점을 먼저 정리해 두고 네트보다 코드에 시간을 쓰는 편이 이득입니다.