설정 Clash 입문 VPN 비교 프록시 초보 가이드

Clash API로 최적 노드 자동 전환하는 고급 설정 가이드

2026년 9월 4일 업데이트: 2026년 9월 4일 약 10분 소요

서론: 왜 노드 자동 전환이 필요한가

Clash를 사용할 때 가장 불편한 작업 중 하나는 네트워크 상태가 나빠질 때마다 프록시 노드를 직접 바꾸는 일입니다. 아침에는 일본 노드가 빠르지만 저녁에는 혼잡해질 수 있고, 같은 노드라도 통신사 경로와 시간대에 따라 지연 시간과 패킷 손실률이 크게 달라질 수 있습니다. 단순히 이름에 JP, SG, US가 포함된 노드를 선택하는 것만으로는 현재 환경에 가장 적합한 경로를 보장하기 어렵습니다.

Clash API와 External Controller를 활용하면 실행 중인 Clash 인스턴스의 프록시 목록, 현재 선택된 노드, 지연 시간, 그룹 구조를 외부 스크립트에서 조회할 수 있습니다. 스크립트는 여러 노드에 테스트 요청을 보내고, 응답이 빠르며 정상적으로 연결되는 노드를 선택한 뒤 API를 통해 해당 그룹의 활성 노드를 바꿉니다. 사용자는 매번 관리 화면을 열지 않아도 되고, 정해진 시간마다 또는 장애가 감지될 때 자동으로 경로를 교체할 수 있습니다.

이 가이드의 목표

Mihomo 기반 Clash에서 External Controller를 안전하게 활성화하고, 지연 시간 측정, 최적 노드 선택, API 전환, 스케줄링과 재시도까지 하나의 자동화 흐름으로 구성합니다.

예시는 데스크톱에서 실행하는 Python 스크립트를 기준으로 설명하지만, API 구조는 Clash Verge Rev, Clash for Windows의 일부 코어 환경, Clash for Android 및 서버에서 실행되는 Mihomo 구성에도 응용할 수 있습니다. 다만 클라이언트마다 API 포트와 지원하는 코어 기능이 다르므로 먼저 실제 설정 화면과 로그를 확인해야 합니다.

1External Controller와 YAML 설정

자동화의 첫 단계는 Clash API가 외부 요청을 받을 수 있도록 external-controller와 인증용 secret을 설정하는 것입니다. 일반적으로 설정 파일의 최상위 항목에 다음 내용을 추가합니다. 포트 번호는 다른 프로그램이 사용하지 않는 값으로 바꾸어도 됩니다.

# Mihomo / Clash 설정 예시 external-controller: 127.0.0.1:9090 secret: "change-this-to-a-long-random-token" # 외부 연결이 필요한 경우에만 사용 # external-controller: 0.0.0.0:9090

127.0.0.1은 같은 컴퓨터에서 실행되는 프로그램만 API에 접근할 수 있다는 뜻입니다. 자동 전환 스크립트를 개인 PC에서 실행한다면 이 값을 우선 사용하세요. 0.0.0.0은 모든 네트워크 인터페이스에서 요청을 받을 수 있으므로 다른 기기나 원격 서버에서 제어할 때만 고려해야 합니다. 이 경우 방화벽에서 특정 IP만 허용하고, 강력한 비밀 키를 사용하며, 가능하면 VPN이나 SSH 터널 안에서만 API를 노출해야 합니다.

보안 주의

External Controller는 프록시 설정과 활성 노드를 변경할 수 있는 관리 인터페이스입니다. 공개 인터넷에 포트를 그대로 열거나 기본값처럼 짧은 secret을 사용하는 것은 피하세요. 설정 파일을 공유할 때도 secret을 반드시 삭제해야 합니다.

API 연결 확인

Clash를 다시 시작한 뒤 터미널에서 다음 명령을 실행하면 프록시 목록이 JSON 형식으로 반환되는지 확인할 수 있습니다. secret이 설정되어 있다면 반드시 Authorization 헤더에 Bearer 형식으로 전달해야 합니다.

curl -H "Authorization: Bearer change-this-to-a-long-random-token" \ http://127.0.0.1:9090/proxies

응답에 proxies 객체와 함께 GLOBAL, DIRECT, 노드 그룹 이름이 표시되면 기본 연결은 완료된 것입니다. API가 응답하지 않으면 Clash가 실행 중인지, 포트가 정확한지, 해당 클라이언트가 Mihomo 코어를 사용하고 있는지 확인하세요. 클라이언트의 API 주소가 127.0.0.1:9097처럼 다르게 지정되어 있을 수도 있습니다.

2지연 시간 측정과 최적 노드 선택 로직

노드를 자동으로 선택할 때는 단순히 가장 작은 숫자 하나만 비교하지 않는 것이 좋습니다. 테스트 요청이 성공했는지 먼저 확인하고, 일정한 시간 안에 응답하지 않는 노드는 제외해야 합니다. 또한 지연 시간이 낮더라도 접속이 자주 끊기거나 특정 서비스가 열리지 않는 노드라면 실제 사용에는 적합하지 않습니다.

  • 후보 그룹 제한: 모든 노드를 무작정 테스트하지 말고 Auto, Proxy, GLOBAL처럼 실제 트래픽에 사용하는 그룹의 구성원만 대상으로 삼습니다.
  • 허용 범위 지정: 이름에 剩余, 过期, 流量 같은 상태 문구가 붙은 노드는 제외하고, 필요하다면 국가 코드나 서비스 등급으로 후보를 제한합니다.
  • 타임아웃 적용: 3~5초 안에 응답하지 않는 노드는 실패로 처리하여 한 개의 불량 노드 때문에 전체 작업이 멈추지 않게 합니다.
  • 평균값 사용: 한 번의 측정값은 순간적인 네트워크 변동에 영향을 받으므로 동일 노드를 2~3회 측정하거나 최근 결과를 기록하는 편이 안정적입니다.

Mihomo API에서는 보통 프록시 지연 시간을 확인할 때 다음과 같은 형태의 엔드포인트를 사용할 수 있습니다. 실제 지원 여부와 매개변수는 코어 버전에 따라 다를 수 있으므로 먼저 수동 호출로 확인하세요.

curl -G \ -H "Authorization: Bearer change-this-to-a-long-random-token" \ --data-urlencode "url=https://www.gstatic.com/generate_204" \ --data-urlencode "timeout=5000" \ http://127.0.0.1:9090/proxies/노드이름/delay

노드 이름에 공백, 괄호, 한글 또는 특수 문자가 포함되어 있다면 URL 경로에 직접 붙이지 말고 반드시 URL 인코딩을 사용해야 합니다. Python의 urllib.parse.quote를 사용하면 이 문제를 줄일 수 있습니다.

선택 기준 예시

다음 기준은 일반적인 웹 브라우징용 자동 선택에 적합합니다. 영상 회의나 게임처럼 UDP와 지속 연결이 중요한 작업에서는 별도의 품질 기준을 추가하세요.

  1. 테스트 URL에 정상적으로 응답한 노드만 남깁니다.
  2. 지연 시간이 800ms보다 큰 노드는 우선순위에서 제외합니다.
  3. 남은 노드 중 가장 낮은 지연 시간을 가진 노드를 선택합니다.
  4. 현재 노드와 차이가 20ms 이하라면 불필요한 전환을 하지 않습니다.
  5. 최근 전환 시각을 기록하여 짧은 시간 안에 계속 바뀌는 현상을 막습니다.

안정성 향상 팁

최저 지연 시간만 고르기보다 지연 시간이 낮은 상위 3개 노드를 후보로 저장하고, 연속 측정에서 안정적으로 응답한 노드를 최종 선택하면 잦은 전환을 크게 줄일 수 있습니다.

3Python으로 노드 조회와 그룹 전환 자동화

아래 스크립트는 API에서 프록시 정보를 읽고, 지정한 그룹의 구성원 중 이름에 포함된 후보만 골라 지연 시간을 측정한 다음 가장 빠른 노드로 전환하는 기본 구조입니다. 그룹 이름과 후보 키워드는 자신의 YAML 설정에 맞게 수정해야 합니다.

import time import requests from urllib.parse import quote API = "http://127.0.0.1:9090" SECRET = "change-this-to-a-long-random-token" GROUP = "Proxy" TEST_URL = "https://www.gstatic.com/generate_204" TIMEOUT = 5000 MIN_IMPROVEMENT = 20 headers = {"Authorization": f"Bearer {SECRET}"} def get_proxies(): response = requests.get(f"{API}/proxies", headers=headers, timeout=5) response.raise_for_status() return response.json()["proxies"] def test_delay(name): encoded = quote(name, safe="") params = {"url": TEST_URL, "timeout": TIMEOUT} response = requests.get( f"{API}/proxies/{encoded}/delay", headers=headers, params=params, timeout=TIMEOUT / 1000 + 2 ) if response.ok: return response.json().get("delay", 99999) return 99999 def switch_group(name): response = requests.put( f"{API}/proxies/{quote(GROUP, safe='')}", headers=headers, json={"name": name}, timeout=5 ) response.raise_for_status() data = get_proxies() group = data.get(GROUP) if not group: raise RuntimeError(f"그룹을 찾을 수 없습니다: {GROUP}") candidates = [ name for name in group.get("all", []) if name not in {"DIRECT", "REJECT"} and "过期" not in name ] results = {} for name in candidates: try: results[name] = test_delay(name) except requests.RequestException: results[name] = 99999 time.sleep(0.2) best = min(results, key=results.get) current = group.get("now") current_delay = results.get(current, 99999) print("측정 결과:", results) print("현재 노드:", current, current_delay, "ms") print("추천 노드:", best, results[best], "ms") if results[best] + MIN_IMPROVEMENT < current_delay: switch_group(best) print("노드를 전환했습니다:", best) else: print("현재 노드를 유지합니다.")

이 예제에서 중요한 부분은 세 가지입니다. 첫째, 그룹의 all 목록을 직접 사용하므로 YAML에 정의된 실제 노드만 검사합니다. 둘째, 현재 노드보다 아주 조금 빠른 노드로 매번 전환하지 않도록 MIN_IMPROVEMENT 기준을 둡니다. 셋째, API 오류나 타임아웃을 예외로 처리하여 하나의 실패 노드가 전체 스크립트를 종료시키지 않도록 합니다.

그룹 이름과 노드 이름 확인

대시보드에 보이는 이름과 YAML에 정의된 그룹 이름이 항상 같은 것은 아닙니다. /proxies 응답에서 최상위 키를 출력하여 정확한 그룹 이름을 확인하세요. 그룹이 중첩되어 있거나 다른 그룹을 또 다른 그룹의 구성원으로 사용하는 경우, 실제 최종 노드를 선택하는 방식으로 로직을 조정해야 합니다.

클라이언트별 차이

일부 GUI 클라이언트는 자체 API 프록시 이름이나 포트를 사용하고, 일부 모바일 환경은 백그라운드 실행을 제한합니다. 스크립트가 작동하지 않으면 API 경로, 포트, 코어 버전, 인증 헤더를 순서대로 점검하세요.

4스케줄링, 장애 재시도와 운영 관리

자동 전환 스크립트는 필요할 때 직접 실행하는 것만으로도 유용하지만, 정기 실행과 장애 감지를 함께 구성하면 훨씬 편리합니다. 다만 너무 짧은 간격으로 테스트하면 API와 프록시 서버에 불필요한 요청이 발생하고, 정상적인 노드까지 계속 바뀌는 문제가 생길 수 있습니다.

운영체제별 실행 방법

  • Windows: 작업 스케줄러에서 Python 실행 파일을 프로그램으로 지정하고, 10~30분 간격으로 실행합니다. 시작 위치는 스크립트가 저장된 폴더로 지정해야 로그 파일 경로가 꼬이지 않습니다.
  • macOS / Linux: crontab에 실행 주기를 등록할 수 있습니다. 예를 들어 15분마다 실행하려면 */15 * * * * /usr/bin/python3 /path/auto_switch.py >> /path/clash-switch.log 2>&1처럼 설정합니다.
  • 서버 환경: 장시간 실행되는 서비스라면 무한 루프보다 systemd timer나 컨테이너 스케줄러를 사용해 프로세스가 비정상 종료되어도 다시 실행되게 구성하는 편이 안전합니다.

장애 재시도는 한 번의 실패와 실제 장애를 구분하도록 설계해야 합니다. 첫 번째 테스트가 실패했다고 즉시 노드를 바꾸기보다 같은 노드를 한 번 더 확인하고, 두 번 연속 실패하면 다음 후보로 넘어가는 방식이 좋습니다. 전환 후에는 10~30초 정도 기다린 뒤 동일한 테스트 URL로 연결이 회복되었는지 검증하세요.

권장 재시도 흐름
  1. API 응답 여부를 확인하고 응답이 없으면 5초 후 다시 시도합니다.
  2. 현재 노드의 지연 시간을 2회 측정하여 일시적 오류인지 확인합니다.
  3. 연속 실패 시 후보 노드의 지연 시간을 비교합니다.
  4. 새 노드로 전환한 뒤 실제 테스트 URL을 다시 요청합니다.
  5. 모든 후보가 실패하면 마지막으로 정상 확인된 노드를 유지하고 로그에 오류를 남깁니다.

로그에는 실행 시각, 현재 노드, 측정된 지연 시간, 선택된 노드, 전환 사유를 기록하세요. 비밀 키와 전체 설정 파일은 로그에 남기지 않아야 합니다. 또한 노드 변경이 너무 자주 발생하면 MIN_IMPROVEMENT 값을 높이거나 최소 유지 시간을 추가하고, 특정 서비스만 문제가 있다면 전체 그룹을 바꾸기보다 해당 도메인 전용 그룹을 분리하는 것이 좋습니다.

최종 점검 목록

API 포트가 로컬 또는 방화벽에서 안전하게 보호되는지, secret이 충분히 긴지, 테스트 URL이 정상 응답하는지, 그룹 이름이 정확한지, 전환 후 로그가 남는지를 차례대로 확인하면 안정적인 자동 전환 환경을 만들 수 있습니다.

Clash API 자동화의 핵심은 가장 빠른 노드를 무조건 선택하는 것이 아니라, 현재 환경에서 실제로 연결되는 노드를 측정하고 불필요한 전환을 억제하는 것입니다. 처음에는 한 개의 그룹과 짧은 후보 목록으로 시작한 뒤, 결과 로그를 확인하면서 측정 주기와 임계값을 조정하세요. 이렇게 구성하면 수동 선택의 번거로움을 줄이면서도 네트워크 변화에 유연하게 대응할 수 있습니다.

Clash 무료 다운로드 — 원활한 인터넷 경험을 시작하세요 →