Clash external-controller API로 노드 자동 전환 구성하기
external-controller API와 지연 시간 검사를 결합해 Clash 노드 장애 조치 시스템을 구축해 보세요. 정책 그룹 제어, 인증 설정, 스크립트 자동화와 문제 해결 방법을 함께 설명합니다.
external-controller API란 무엇인가요?
Clash의 external-controller는 실행 중인 코어를 외부 프로그램에서 관리할 수 있도록 열어 두는 HTTP API입니다. 일반적인 GUI에서는 프록시 그룹을 클릭해 노드를 바꾸지만, API를 사용하면 현재 선택된 노드 확인, 정책 그룹 전환, 프로필 상태 조회, 연결 목록 확인 같은 작업을 스크립트나 모니터링 도구로 자동화할 수 있습니다. 이번 글의 핵심은 특정 노드의 지연 시간이 높거나 연결이 실패했을 때, 가장 상태가 좋은 노드로 정책 그룹을 자동 전환하는 구성입니다.
이 기능은 노드 자체를 새로 만드는 기능이 아닙니다. 구독이나 YAML 설정에 이미 정의된 프록시와 정책 그룹을 대상으로 선택 상태를 바꾸는 관리 인터페이스에 가깝습니다. 따라서 먼저 Clash가 정상적으로 실행되고 있어야 하며, 자동 전환 대상 노드가 하나의 select 또는 fallback 그룹에 포함되어 있어야 합니다. 그룹 이름과 노드 이름은 API 요청에서 정확히 사용되므로, 공백·특수문자·한중일 문자까지 실제 설정과 일치하는지 확인해야 합니다.
Clash Verge Rev나 Mihomo 기반 클라이언트에서는 메뉴 이름이 조금씩 다를 수 있지만, 핵심 설정은 대체로 External Controller, Controller 또는 API listen address라는 이름으로 표시됩니다. 원본 Clash와 Meta 계열 코어도 비슷한 API 구조를 제공하지만, 지원되는 엔드포인트와 응답 필드는 버전에 따라 다를 수 있습니다. 그러므로 자동화 스크립트를 만들기 전에 사용 중인 코어의 API 응답을 직접 확인하는 습관이 중요합니다.
자동 전환을 위한 정책 그룹 준비
자동화가 안정적으로 작동하려면 먼저 수동 전환이 가능한 정책 그룹을 만들어야 합니다. 단순히 프로파일에 노드가 여러 개 있다는 것만으로는 부족합니다. 스크립트가 변경할 대상 그룹이 있어야 하고, 해당 그룹 안에 실제 프록시 노드가 포함되어 있어야 합니다. 가장 이해하기 쉬운 구조는 여러 노드를 select 그룹에 넣고, 평소에는 사용자가 선택한 노드를 유지하다가 장애가 감지되면 API로 선택 항목을 바꾸는 방식입니다.
| 구성 요소 | 역할 | 확인할 내용 |
|---|---|---|
proxies |
실제 서버 노드 정의 | 이름이 서로 겹치지 않고 연결 정보가 유효한지 확인 |
proxy-groups |
노드를 묶고 선택하는 정책 그룹 | 자동화에서 사용할 그룹 이름을 고정 |
health-check |
노드 응답 시간과 가용성 판단 | 테스트 URL, 간격, 타임아웃을 네트워크 환경에 맞게 설정 |
external-controller |
외부 API 요청 수신 | 수신 주소와 인증 토큰을 안전하게 관리 |
아래는 개념을 설명하기 위한 예시입니다. 실제 노드 주소와 이름은 이용 중인 구독 제공업체의 설정에 맞춰 바꾸어야 합니다.
mixed-port: 7890
external-controller: 127.0.0.1:9090
secret: "change-this-secret"
proxies:
- name: "Tokyo-01"
type: ss
server: example-one.net
port: 443
cipher: aes-128-gcm
password: "password-one"
- name: "Seoul-01"
type: ss
server: example-two.net
port: 443
cipher: aes-128-gcm
password: "password-two"
proxy-groups:
- name: "AUTO"
type: select
proxies:
- "Tokyo-01"
- "Seoul-01"
- DIRECT
주의
정책 그룹 이름에 한글을 사용할 수 있는지는 클라이언트와 코어 버전에 따라 다르게 느껴질 수 있습니다. 자동화 호환성을 우선한다면 AUTO, Proxy처럼 짧은 영문 이름을 사용하고, 노드 이름에도 불필요한 따옴표·슬래시·줄바꿈을 넣지 않는 편이 안전합니다.
select 그룹은 사용자가 선택한 항목을 그대로 유지하는 데 적합합니다. 반면 url-test는 설정한 테스트 URL을 기준으로 지연 시간이 낮은 노드를 자동 선택하고, fallback은 앞쪽 노드부터 연결 가능한 대상을 선택합니다. 직접 API를 호출해 전환하는 목적이라면 select 그룹이 결과를 예측하기 쉽습니다. 여러 정책 그룹이 같은 노드를 참조하는 경우에는 어느 그룹을 바꾸어야 실제 트래픽에 영향을 주는지도 먼저 확인하세요.
external-controller와 인증 설정
API를 열 때 가장 먼저 결정할 것은 수신 주소입니다. 같은 컴퓨터의 스크립트만 API를 호출한다면 127.0.0.1:9090이 가장 안전한 기본값입니다. 이 주소는 외부 LAN 기기에서 접근할 수 없으므로, 실수로 토큰이 노출되더라도 공격 표면을 줄일 수 있습니다. 반대로 라우터, 다른 서버, 홈 네트워크의 모니터링 도구에서 호출해야 한다면 0.0.0.0:9090처럼 모든 인터페이스에 바인딩해야 할 수 있습니다.
모든 인터페이스에 API를 열어야 한다면 방화벽에서 신뢰하는 관리 장치의 IP만 허용하고, 인터넷 방향의 포트 포워딩은 만들지 마세요. external-controller는 단순 조회뿐 아니라 프록시 그룹 변경과 설정 제어까지 수행할 수 있으므로, 포트가 노출되면 일반 웹 서버보다 훨씬 큰 피해가 발생할 수 있습니다. 사설망이라도 게스트 Wi-Fi와 관리망이 분리되어 있는지 확인하고, 공용 서버에서는 로컬 소켓이나 SSH 터널을 우선 고려하는 것이 좋습니다.
인증 토큰은 secret 항목에 설정합니다. API 요청에는 보통 Authorization: Bearer 토큰 헤더를 넣습니다. 토큰을 YAML 파일이나 셸 스크립트에 직접 기록하면 파일 권한과 백업 경로를 통해 유출될 수 있으므로, 운영 환경에서는 환경 변수나 권한이 제한된 별도 파일에 보관하세요.
curl -s \
-H "Authorization: Bearer change-this-secret" \
http://127.0.0.1:9090/proxies
보안 팁
API 테스트가 끝난 뒤에는 실제 토큰으로 교체하고, 설정 파일 권한을 사용자 전용으로 제한하세요. Windows에서는 일반 사용자 프로필 아래의 비공개 디렉터리에 저장하고, Linux나 macOS에서는 chmod 600을 적용한 파일을 사용하는 방식이 무난합니다. 로그에 Authorization 헤더를 출력하는 디버깅 옵션도 장시간 켜 두지 않는 편이 좋습니다.
API가 열렸는지는 먼저 전체 프록시 목록 조회로 확인합니다. 정상 응답이 오면 다음으로 그룹 이름이 응답 JSON에 어떤 형태로 나타나는지 살펴보세요. 일부 코어는 정책 그룹도 proxies 객체 안에 포함하며, 그룹에는 현재 선택된 항목을 나타내는 now 필드가 포함됩니다. GUI에 보이는 이름과 API가 반환하는 이름이 다르면 화면의 표시명보다 API 응답의 실제 키를 기준으로 요청해야 합니다.
API로 현재 노드 확인 및 전환하기
정책 그룹의 현재 선택 노드는 그룹별 조회 엔드포인트로 확인할 수 있습니다. 일반적인 Clash 계열 API에서는 GET /proxies/{name}으로 그룹 또는 프록시 정보를 읽고, PUT /proxies/{name}으로 선택 그룹의 현재 프록시를 변경합니다. 그룹 이름에 공백이나 특수문자가 있다면 URL 인코딩이 필요하므로, 자동화 초기에는 영문 그룹 이름을 사용하는 것이 오류를 줄이는 데 도움이 됩니다.
# 현재 AUTO 그룹 상태 확인
curl -s \
-H "Authorization: Bearer change-this-secret" \
"http://127.0.0.1:9090/proxies/AUTO"
# AUTO 그룹을 Seoul-01로 변경
curl -s -X PUT \
-H "Authorization: Bearer change-this-secret" \
-H "Content-Type: application/json" \
-d '{"name":"Seoul-01"}' \
"http://127.0.0.1:9090/proxies/AUTO"
응답이 비어 있거나 HTTP 오류가 발생한다고 해서 곧바로 노드가 고장 났다고 판단하면 안 됩니다. API 경로, 그룹 이름 인코딩, 토큰, 코어의 수신 포트가 모두 맞는지 순서대로 확인해야 합니다. 401이나 403은 인증 문제일 가능성이 높고, 404는 엔드포인트 또는 그룹 이름 오류를 의심할 수 있습니다. 연결 거부는 Clash 코어가 실행 중인지, 설정이 실제로 로드되었는지, 다른 프로그램이 포트를 점유하지 않았는지 확인해야 합니다.
지연 시간 검사는 API에서 제공하는 테스트 기능을 활용할 수 있습니다. 많은 Mihomo 계열 코어는 특정 프록시에 대해 테스트 URL과 타임아웃을 전달하는 방식을 사용합니다. 다만 엔드포인트와 매개변수 이름은 버전별 차이가 있으므로, 사용 중인 코어 문서와 /version, /proxies 응답을 먼저 확인하세요. 검사 결과의 숫자가 작을수록 빠르다는 뜻이지만, 한 번의 측정만으로 품질을 단정하지 말고 여러 번의 실패율과 함께 판단해야 합니다.
# 예시: 노드 지연 시간 테스트
curl -s \
-H "Authorization: Bearer change-this-secret" \
"http://127.0.0.1:9090/proxies/Seoul-01/delay?url=https%3A%2F%2Fwww.gstatic.com%2Fgenerate_204&timeout=5000"
자동 전환 조건은 너무 민감하게 만들지 않는 것이 좋습니다. 예를 들어 300ms를 한 번 넘었다고 즉시 노드를 바꾸면 일시적인 무선 간섭이나 테스트 서버 지연에도 선택이 계속 흔들릴 수 있습니다. 보통은 연속 2~3회 타임아웃, 또는 최근 5회 중 일정 횟수 이상 실패처럼 히스테리시스를 둡니다. 전환 후에는 일정 시간 동안 같은 노드를 유지하는 쿨다운을 추가해야 여러 노드 사이를 반복해서 오가는 현상도 줄일 수 있습니다.
스크립트 자동화와 문제 해결
다음은 개념적인 Python 예시입니다. 여러 노드를 순서대로 검사하고, 통과한 노드 중 지연 시간이 가장 낮은 노드를 AUTO 그룹에 적용하는 흐름입니다. 실제 운영에서는 코어 버전에 맞춰 지연 시간 API의 경로와 응답 형식을 조정해야 하며, 토큰을 코드에 직접 넣지 않는 것이 좋습니다.
import os
import time
import requests
BASE = "http://127.0.0.1:9090"
TOKEN = os.environ["CLASH_SECRET"]
GROUP = "AUTO"
NODES = ["Tokyo-01", "Seoul-01"]
TEST_URL = "https://www.gstatic.com/generate_204"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
}
results = []
for node in NODES:
try:
response = requests.get(
f"{BASE}/proxies/{node}/delay",
params={"url": TEST_URL, "timeout": 5000},
headers=headers,
timeout=7,
)
response.raise_for_status()
delay = response.json().get("delay")
if isinstance(delay, int):
results.append((delay, node))
except (requests.RequestException, ValueError):
continue
if results:
results.sort()
selected = results[0][1]
requests.put(
f"{BASE}/proxies/{GROUP}",
headers=headers,
json={"name": selected},
timeout=5,
)
print(f"selected: {selected}")
else:
print("no healthy node")
이 스크립트를 실행할 때는 호출 주기를 신중하게 정해야 합니다. 10초마다 모든 노드를 검사하면 노드 수가 많을수록 테스트 트래픽과 API 요청이 빠르게 증가합니다. 개인 PC라면 1~5분 간격으로도 충분한 경우가 많고, 장시간 연결이 중요한 서버라면 짧은 검사와 긴 쿨다운을 조합하는 방식이 현실적입니다. 스케줄러가 여러 인스턴스를 동시에 실행하지 않도록 잠금 파일이나 단일 서비스 프로세스도 고려하세요.
가장 흔한 문제는 “API는 정상인데 트래픽이 바뀌지 않는다”는 증상입니다. 이때는 호출한 그룹이 실제 규칙에서 사용하는 그룹인지 먼저 확인합니다. 규칙이 Proxy 그룹을 가리키는데 스크립트는 AUTO만 바꾸고 있다면 API 응답은 성공해도 사용자 트래픽에는 변화가 없습니다. 또한 상위 그룹이 하위 그룹을 참조하는 구조에서는 최종적으로 실제 연결에 사용되는 경로를 따라가야 합니다.
노드가 계속 바뀌는 경우에는 테스트 URL이 특정 지역에서 불안정하거나, 타임아웃이 지나치게 짧거나, 성공 기준이 너무 엄격할 수 있습니다. 같은 URL을 브라우저에서 직접 열어 보고, Clash 로그에서 DNS 실패와 TLS 실패를 구분하세요. 지연 시간만 낮고 실제 서비스 접속은 되지 않는 노드가 선택된다면 테스트 URL을 하나 더 추가하거나, 단순 속도 대신 HTTP 상태 코드와 연결 성공 여부를 함께 판단해야 합니다.
운영 전 점검 순서
- GUI에서 정책 그룹을 수동으로 바꿔 실제 트래픽이 변경되는지 확인합니다.
- 토큰을 사용해
/proxies조회가 되는지 확인합니다. - 노드 하나만 대상으로 지연 시간 테스트를 실행합니다.
- 수동으로
PUT요청을 보내 그룹 전환 결과를 검증합니다. - 스크립트에 실패 횟수, 선택 노드, 전환 시간을 기록합니다.
- 쿨다운과 재시도 횟수를 설정한 뒤 백그라운드 스케줄러에 등록합니다.
API를 외부 장치에서 호출해야 한다면 TLS를 지원하는 보호된 관리 경로를 사용하는 것이 더 안전합니다. 단순히 포트를 인터넷에 공개하고 긴 토큰 하나에 의존하는 방식은 권장되지 않습니다. 방화벽 허용 목록, VPN, SSH 포트 포워딩, 역방향 프록시의 추가 인증을 조합하면 관리 범위를 좁힐 수 있습니다. 자동화 로그에는 노드 이름과 결과만 남기고, 구독 URL·비밀번호·API 토큰은 기록하지 마세요.
일부 GUI 클라이언트는 화면에서 설정을 저장할 때 외부 컨트롤러 주소나 토큰을 덮어쓸 수 있습니다. 자동화가 갑자기 중단되었다면 코어 로그와 실제 로드된 설정을 다시 확인하고, 앱을 업데이트한 뒤 설정을 재적용하세요. 특히 원본 Clash for Windows와 커뮤니티 포크, Mihomo 기반 클라이언트는 메뉴와 API 지원 범위가 다를 수 있으므로, “Clash에서 된다”는 설명만으로 모든 버전이 같은 동작을 한다고 가정해서는 안 됩니다.
다른 프록시 도구는 단순한 노드 선택에는 편리하지만, 외부 API의 지원 범위가 제한되거나 정책 그룹과 연결 상태를 한 번에 다루기 어려워 자동 장애 조치 구성이 복잡해질 수 있습니다. 반면 Clash는 규칙 기반 라우팅, 정책 그룹, 지연 시간 검사, 연결 로그와 external-controller API를 하나의 흐름으로 묶을 수 있어 개인 PC부터 홈 서버까지 같은 방식으로 확장하기 좋습니다. 장애 시 수동으로 여러 화면을 오가고 싶지 않거나, 서비스별 정책 그룹을 정밀하게 제어하고 싶다면 이 구성이 특히 유용합니다.
지연 시간 검사와 보안 설정을 충분히 검증한 뒤에도 더 단순한 관리 화면과 폭넓은 클라이언트 호환성을 원한다면 Clash를 직접 구성해 보세요. 환경에 맞는 빌드를 선택하고 구독을 불러온 다음, 이 글의 API 설정을 단계적으로 적용하면 됩니다. Clash 무료 다운로드로 시작해 안정적인 자동 전환 환경을 만들어 보세요.