Clash API 자동 전환이 필요한 이유
Clash의 프록시 그룹은 일반적으로 사용자가 직접 노드를 고르거나 url-test가 정해진 URL의 지연 시간을 비교해 멤버를 선택하는 방식으로 운용됩니다. 이 구조는 단순한 웹 탐색에는 충분하지만, 장시간 연결을 유지하는 API 요청, 스트리밍 응답, 다운로드, 원격 개발 세션에서는 한계가 분명합니다. 측정 시점에는 80ms였던 노드가 몇 분 뒤 패킷 손실을 일으킬 수 있고, 지연 시간은 낮아도 특정 API 도메인과의 TLS 협상이나 업스트림 응답만 실패할 수 있기 때문입니다.
이때 Clash API를 사용하면 외부 스크립트가 현재 프록시 그룹의 상태를 읽고, 테스트 결과에 따라 다른 노드를 선택하도록 만들 수 있습니다. 핵심은 “가장 빠른 노드를 무조건 선택한다”가 아니라, 응답 지연·HTTP 상태 코드·연속 실패 횟수·최근 전환 시각을 함께 판단하는 것입니다. 그래야 일시적인 CDN 지연 때문에 노드가 계속 바뀌는 플래핑을 줄이고, 정상 노드로 돌아왔을 때도 안정적으로 복귀할 수 있습니다.
이 방식은 Clash Verge Rev, Mihomo를 사용하는 환경에서 특히 유용합니다. 클라이언트의 화면에서 제공하는 자동 선택 기능만으로 부족할 때 로컬 자동화 스크립트를 추가할 수 있으며, GUI를 바꾸지 않고도 현재 프로필의 proxy-groups를 제어할 수 있습니다. 다만 모든 Clash 계열 클라이언트가 동일한 외부 컨트롤러 API를 제공하는 것은 아니므로, 먼저 실행 중인 코어가 외부 컨트롤러를 지원하는지 확인해야 합니다.
외부 컨트롤러와 토큰을 안전하게 준비하기
Clash API 호출의 기본 주소는 일반적으로 로컬 주소와 컨트롤러 포트의 조합입니다. 예를 들어 Mihomo가 127.0.0.1:9090에서 컨트롤러를 열고 있다면, 현재 설정은 /configs로 확인할 수 있고 프록시 그룹 목록은 /proxies에서 읽을 수 있습니다. 그룹을 바꾸는 요청은 해당 그룹 이름을 URL 인코딩해 /proxies/{group}에 PUT으로 전송합니다. 버전이나 클라이언트에 따라 경로와 응답 필드가 다를 수 있으므로 실제 응답을 먼저 확인하세요.
컨트롤러를 외부 네트워크에 그대로 노출하는 것은 피해야 합니다. external-controller를 모든 인터페이스에 바인딩하거나 방화벽 포트를 인터넷에 열면, 토큰을 탈취한 사람이 프록시 그룹을 임의로 바꾸고 연결 상태를 조회할 수 있습니다. 자동 전환 스크립트가 같은 컴퓨터에서 실행된다면 127.0.0.1 바인딩을 우선 선택하고, 원격 관리가 필요할 때만 인증된 사설 네트워크와 방화벽 규칙을 추가하는 편이 안전합니다.
먼저 읽기 요청으로 API를 검증하기
아래 예시는 현재 설정과 그룹 정보를 읽는 최소한의 점검입니다. secret 값은 설정 파일에 직접 넣지 말고 운영체제 환경 변수로 전달하세요. 응답에 그룹 이름이 보이면 컨트롤러와 토큰이 모두 작동하는 것입니다. 오류가 나면 자동 전환 로직을 작성하기 전에 포트, 인증 헤더, HTTP와 HTTPS 여부부터 분리해서 확인합니다.
curl -s \
-H "Authorization: Bearer ${CLASH_SECRET}" \
"http://127.0.0.1:9090/proxies"
curl -s \
-H "Authorization: Bearer ${CLASH_SECRET}" \
"http://127.0.0.1:9090/configs"
토큰은 셸 히스토리, CI 로그, 프로세스 목록에 남지 않도록 주의해야 합니다. 명령줄에 토큰을 직접 작성하면 다른 사용자가 히스토리를 읽을 수 있고, 일부 자동화 도구는 실행 인자를 로그로 저장합니다. 환경 변수나 권한이 제한된 파일에서 읽고, 로그에는 토큰 원문 대신 길이와 해시 일부만 남기는 방식이 적절합니다. 토큰을 교체할 때는 기존 스크립트가 실패하는지 확인한 뒤 새 값을 적용하세요.
YAML에서 주 그룹과 예비 그룹을 설계하기
자동화 스크립트는 아무 그룹이나 바꾸기보다 별도의 운영 그룹을 대상으로 해야 합니다. 구독이 자동 생성하는 기본 그룹을 직접 수정하면 다음 갱신 때 이름과 멤버가 바뀌어 스크립트가 잘못된 대상을 선택할 수 있습니다. 예를 들어 실제 트래픽이 PROXY 그룹을 사용한다면, 스크립트가 제어할 그룹을 AUTO-API로 만들고 규칙에서 해당 그룹을 명시적으로 참조하는 구조가 관리하기 쉽습니다.
proxy-groups:
- name: AUTO-API
type: select
proxies:
- API-NODE-A
- API-NODE-B
- API-BACKUP
- DIRECT
rules:
- DOMAIN-SUFFIX,api.example.com,AUTO-API
- DOMAIN-SUFFIX,example.com,AUTO-API
- MATCH,PROXY
실제 노드 이름은 구독 프로필의 proxies 항목과 한 글자까지 같아야 합니다. 공백, 대괄호, 지역 표시, 이모지, 대소문자가 조금만 달라도 API는 그룹 변경 요청을 거부하거나 존재하지 않는 멤버를 선택하려고 합니다. 또한 예비 노드는 메인 노드와 같은 지역에만 두지 말고, 서로 다른 제공자나 회선에 배치하는 것이 좋습니다. 같은 데이터센터 장애를 두 노드가 함께 겪는다면 목록에 예비 노드가 여러 개 있어도 실제 복구에는 도움이 되지 않습니다.
응답 검사와 전환 조건 만들기
자동 전환의 테스트 URL은 실제 사용하는 API와 가까워야 하지만, 무거운 요청을 반복해서 보내서는 안 됩니다. 인증이 필요 없는 상태 확인 엔드포인트나 작은 응답을 제공하는 전용 주소를 선택하고, 10초 이내에 응답이 오지 않으면 실패로 기록합니다. HTTP 200만 성공으로 취급할지, 204나 일부 3xx도 허용할지는 서비스의 정상 동작에 맞춰 정해야 합니다.
한 번의 실패만으로 즉시 전환하면 무선 네트워크의 순간 손실에도 그룹이 흔들립니다. 반대로 다섯 번 이상 기다리면 API 세션이 이미 사용자에게 오류를 반환할 수 있습니다. 일반적인 시작값으로는 연속 3회 실패 또는 지연 시간 2500ms 초과를 전환 조건으로 두고, 전환 뒤에는 30초에서 60초 동안 다시 평가하지 않는 쿨다운을 두는 방법이 무난합니다. 노드가 다시 정상으로 보여도 즉시 원래 노드로 돌아가지 말고, 여러 번 연속 성공했을 때 복귀시키세요.
#!/usr/bin/env python3
import os
import time
import requests
API = os.getenv("CLASH_API", "http://127.0.0.1:9090")
SECRET = os.environ["CLASH_SECRET"]
GROUP = os.getenv("CLASH_GROUP", "AUTO-API")
TARGETS = ["API-NODE-A", "API-NODE-B", "API-BACKUP"]
CHECK_URL = os.getenv("CHECK_URL", "https://api.example.com/health")
HEADERS = {"Authorization": f"Bearer {SECRET}"}
def choose_node(node):
url = f"{API}/proxies/{requests.utils.quote(GROUP, safe='')}"
response = requests.put(url, json={"name": node}, headers=HEADERS, timeout=5)
response.raise_for_status()
def check_node(node):
choose_node(node)
started = time.monotonic()
response = requests.get(CHECK_URL, headers=HEADERS, timeout=8)
elapsed = (time.monotonic() - started) * 1000
return response.status_code == 200 and elapsed < 2500, elapsed
for node in TARGETS:
try:
ok, latency = check_node(node)
print(f"{node}: ok={ok}, latency={latency:.0f}ms")
if ok:
break
except requests.RequestException as error:
print(f"{node}: failed: {error}")
위 코드는 이해를 위한 단순한 흐름이며, 실제 운영에서는 테스트할 때마다 그룹을 바꾸는 동작이 사용자 트래픽을 끊을 수 있다는 점을 고려해야 합니다. 가능하다면 노드별 직접 테스트를 지원하는 구조를 사용하고, 그렇지 않으면 업무량이 적은 시간에만 평가하거나 별도의 테스트 그룹을 두세요. 같은 그룹을 여러 프로세스가 동시에 수정하지 않도록 파일 잠금이나 전용 실행 큐를 추가하는 것도 중요합니다.
정기 실행, 예비 노드, 장애 분석
정기 실행은 운영체제에 맞춰 선택합니다. Linux와 macOS에서는 systemd timer나 cron을 사용할 수 있고, Windows에서는 작업 스케줄러로 로그인 시 실행과 일정 주기 실행을 나눌 수 있습니다. 짧은 주기로 무조건 실행하기보다는 1분에서 5분 사이의 간격을 두고, 마지막 전환 시각과 최근 결과를 파일에 저장하는 편이 좋습니다. 스크립트가 매번 모든 노드를 순서대로 시험하면 API 요청이 불필요하게 늘어나므로, 현재 노드가 정상일 때는 현재 노드만 확인하고 실패한 경우에만 예비 목록을 순회하세요.
장애가 발생했을 때는 “노드가 느리다”라고만 기록하지 말고 최소한 테스트 시각, 선택한 그룹, 노드 이름, 연결 시간, HTTP 상태 코드, 오류 종류를 남겨야 합니다. Clash 연결 로그에서 실제 요청이 어떤 정책 그룹으로 나갔는지도 확인해야 합니다. 스크립트가 AUTO-API를 바꿨는데 규칙이 더 위에서 DIRECT로 매칭되면, 노드 전환은 성공해도 애플리케이션 트래픽에는 아무 영향이 없습니다. 규칙 순서와 DNS 응답, TUN 모드의 경로까지 함께 확인해야 원인을 좁힐 수 있습니다.
예비 노드가 모두 실패하면 마지막으로 정상 작동했던 노드를 유지할지, DIRECT 또는 차단용 그룹으로 이동할지 정책을 정해야 합니다. 업무 API라면 무작정 DIRECT로 빠지는 것보다 실패를 명확히 알리고 수동 선택을 기다리는 편이 안전할 수 있습니다. 반대로 공개 상태 확인이나 중요하지 않은 다운로드라면 제한된 예비 경로를 허용할 수 있습니다. 중요한 것은 실패 시 동작을 코드에 명시하는 것입니다. “요청이 실패하면 다음 노드”만 구현하면 모든 노드가 불안정할 때 무한 재시도와 과도한 API 호출이 발생합니다.
Clash API 자동 전환은 단순히 노드 이름을 바꾸는 기능이 아니라, 측정 기준과 규칙 우선순위, 보안 경계, 장애 복구 정책을 하나의 운영 흐름으로 묶는 작업입니다. Clash for Windows처럼 오래된 클라이언트는 외부 컨트롤러나 최신 그룹 필드를 충분히 지원하지 않을 수 있고, 일부 GUI는 YAML을 저장할 때 사용자 변경 내용을 덮어쓸 수 있습니다. 반면 Clash V.CORE는 Mihomo 계열 코어와 함께 API 기반 그룹 제어, 세밀한 규칙 적용, 안정적인 로그 확인을 한 환경에서 점검하기 좋습니다. 수동 노드 선택만으로 반복되는 지연과 연결 실패를 관리하기 어렵다면, 지원 플랫폼과 코어 버전을 확인한 뒤 Clash V.CORE를 다운로드해 이 가이드의 테스트 그룹부터 안전하게 구성해 보세요.
// 에디터 추천
Clash V.CORE — API 자동 전환을 위한 안정적인 기반
컨트롤러 API, 정책 그룹, 연결 로그를 함께 확인하면서 지연과 장애에 대응하는 자동화 환경을 만들어 보세요.
- API 기반 프록시 그룹 제어
- 노드별 연결 상태와 지연 확인
- 세밀한 YAML 규칙 관리
- 예비 노드 운영과 장애 분석
- 데스크톱 환경별 간편한 프로필 관리