증상: 프록시는 되는데 웹 패널만 실패

사용자 입장에서는 “인터넷은 되는데 대시보드만 이상하다”가 잘 이해되지 않습니다. mixed-port나 시스템 프록시로 나가는 일반 웹 트래픽과, 코어가 따로 듣는 관리용 API(external-controller)는 포트도 프로토콜도 다릅니다. 브라우저가 127.0.0.1:9090 같은 제어 포트에 접속해 JSON을 주고받을 때는, 출국 노드 지연이 아니라 바인딩 주소·비밀번호·URL 스킴이 어긋난 경우가 훨씬 많습니다.

이 글의 목표는 “전 세계에 제어 포트를 연다”가 아니라, 같은 PC 안에서 패널과 코어가 서로를 찾게 만드는 것입니다. DNS·규칙 튜닝은 Clash Meta DNS 가이드규칙 라우팅에서 다루고, 여기서는 제어 면만 분리해 설명합니다.

용어: 필드 이름은 Meta/Mihomo 계열 YAML 관례를 따릅니다. GUI가 내보낸 파일에서 키 철자가 조금 다르면, 화면에 보이는 “API 주소·비밀번호”가 실제 런타임과 같은지부터 확인하세요.

external-controller와 REST API

external-controller는 코어가 REST API를 노출하는 호스트:포트입니다. 기본 예시는 문서에 자주 나오는 127.0.0.1:9090이지만, 다른 서비스와 포트가 겹치면 9091 등으로 바꾼 프로필도 흔합니다. Yacd·metacubexd는 이 주소로 /version·/proxies 같은 경로를 호출해 그래프를 그립니다. 즉 패널 설정의 “API”는 브라우저 프록시 주소가 아니라 이 관리 포트를 가리켜야 합니다.

mixed-port(예: 7890)는 사용자 트래픽용이고, external-controller설정 전환·로그 조회 같은 관리용입니다. 둘을 헷갈리면 “7890은 되는데 패널만 안 된다”는 상태가 바로 나옵니다.

config.yaml fragment (illustrative)
mixed-port: 7890
external-controller: 127.0.0.1:9090
secret: "replace-with-a-long-random-string"

로컬 바인딩: 127.0.0.1을 기본으로

같은 기기의 브라우저에서 패널을 연다면 external-controller127.0.0.1:포트에 두는 편이 가장 단순합니다. 루프백은 기본적으로 외부에서 직접 들어오지 않으므로, “인터넷에 관리 포트를 무작정 연다”는 실수를 피하기 좋습니다. 반대로 0.0.0.0이나 LAN IP에 바인딩하면 휴대폰이나 다른 PC에서도 API에 닿을 수 있는데, 그만큼 방화벽·secret 강도를 함께 설계해야 합니다.

휴대폰에서만 패널을 보고 싶다고 해서 곧바로 0.0.0.0으로 여는 대신, SSH 터널이나 VPN처럼 신뢰 경로 안에서만 제어 포트에 닿게 하는 방법을 먼저 검토하는 편이 안전합니다. LAN 공유가 꼭 필요하면 LAN 공유·바인딩에서 리스너 주소와 방화벽 규칙을 함께 읽으세요.

secret·토큰·Authorization 헤더

설정에 secret:이 있으면 API 요청에 동일한 문자열을 실어 보내야 합니다. 패널 UI에서는 “Secret”“Token”“API Key”처럼 표시되기도 합니다. 코어가 기대하는 형식은 버전에 따라 Bearer … 헤더 또는 단순 토큰 필드로 나뉘므로, 401이 나오면 (1) YAML의 따옴표·공백 (2) 패널에 붙여 넣은 값에 불필요한 공백·줄바꿈이 없는지 (3) GUI가 별도 “비밀번호”를 덮어쓰지 않는지 순으로 봅니다.

secret을 비워 두면 로컬에서 편할 수 있지만, 제어 포트가 한 번이라도 넓은 인터페이스에 열리면 위험합니다. 로컬 전용이라도 의미 있는 길이의 임의 문자열을 두는 습관을 권합니다. 외부 컨트롤러 노출과 비밀번호에 대한 일반적인 주의사항은 FAQ에도 정리돼 있습니다.

curl — Authorization Bearer example
curl -sS -H "Authorization: Bearer YOUR_SECRET_HERE" \
  http://127.0.0.1:9090/version

일부 환경에서는 헤더 이름이나 접두사가 다를 수 있으니, 401이 계속되면 코어 문서의 “External Controller” 절을 해당 버전 기준으로 다시 대조하세요.

Yacd·metacubexd에서 API 주소 맞추기

정적 파일로 패널을 열었다면(로컬 HTML 또는 공식 데모 사이트), 브라우저는 사용자가 입력한 Base URL로 API를 호출합니다. 여기에 http://127.0.0.1:9090처럼 코어가 실제로 듣는 값을 넣어야 하고, 끝에 잘못된 경로를 붙이거나 https://로 적었는데 코어는 평문 HTTP만 제공하는 식의 스킴 불일치도 흔한 원인입니다.

브라우저 확장·별도 프록시가 127.0.0.1 요청까지 가로채는 경우는 드물지만, 기업 보안 제품이 있는 환경에서는 예외 없이 검사되어 연결이 끊기기도 합니다. 이때는 정책 허용 범위를 확인하거나, 테스트 시에만 해당 보호를 잠시 끄는 등 조직 규칙 안에서 대응해야 합니다.

curl로 API 살아 있는지 먼저 확인

패널을 띄우기 전에 터미널에서 API가 응답하는지 확인하면 원인을 절반까지 좁힐 수 있습니다. /version이나 /configs 같은 가벼운 GET으로 시작하세요. 여기서 연결이 거부되면 패널 문제가 아니라 코어가 꺼져 있거나, 포트가 다르거나, 방화벽이 막는 경우입니다.

curl — no secret (only if your core allows)
curl -sS http://127.0.0.1:9090/version

secret이 있는데 위 요청이 401이면 정상에 가깝습니다. 앞 절의 Bearer 헤더를 붙여 다시 시도하세요. 반대로 아무 응답도 없고 즉시 실패하면 OS 수준에서 포트가 닫혀 있을 가능성이 큽니다.

401·연결 거부·포트 혼동·스킴(http/https)

아래는 현장에서 자주 보는 분기입니다.

트래픽 경로 자체가 이상하면 연결 로그·TLS 가이드로 넘어가되, 그 전에 “지금 말하는 포트가 mixed인지 controller인지”를 먼저 구분하면 시간을 아낍니다.

GUI 클라이언트에서 덮어쓰는 값 확인

Clash Verge·기타 런처는 설정 화면에서 external-controllersecret을 따로 보여 주거나, 실행 시 임시 디렉터리에 병합한 YAML을 씁니다. 파일 에디터로 고쳤는데 UI에 반영이 안 되거나, 반대로 UI 저장이 디스크의 다른 복사본을 덮어쓰는 경우가 있습니다. “어제까지 됐는데 업데이트 후 안 된다”면 업그레이드 가이드와 함께, 클라이언트가 가리키는 실제 프로필 경로를 한 번 확인하세요.

제품별 화면 차이가 크므로, 장기적으로는 클라이언트 선택 가이드에서 말하는 것처럼 “원본 설정을 어디서 읽고 어떻게 재시작하는지”가 분명한 도구를 쓰는 편이 덜 지칩니다.

제어 포트를 열 때의 보안 체크

보안: external-controller는 노드 전환·구독 갱신 등 코어를 사실상 전부 조작할 수 있습니다. 공용 Wi-Fi나 인터넷에 직접 노출하지 말고, 강한 secret·방화벽·VPN/SSH 같은 신뢰 경로를 전제로 하세요. 직장·학교 네트워크 정책을 위반하지 마십시오.

“편해서” 0.0.0.0과 빈 비밀번호를 동시에 쓰면, 같은 LAN의 누군가가 실수로가 아니라 의도적으로 프록시 설정을 바꿀 수 있습니다. 최소 권한 원칙에 맞게, 필요한 범위만 열고 나머지는 루프백에 두는 습관이 장기적으로 가장 저렴한 보험입니다.

맺음말

Clash Meta에서 웹 패널이 먹통일 때는 대개 “출국”이 아니라 제어 REST의 주소·포트·비밀번호·스킴 네 가지가 어긋난 것입니다. 127.0.0.1에 맞춘 external-controller, 패널과 동일한 secret, curl로 먼저 확인하는 습관만 있어도 401과 연결 오류의 대부분을 줄일 수 있습니다. LAN이나 원격 관리가 필요해지면 그때 비로소 바인딩 범위를 넓히고, 방화벽과 비밀번호 정책을 함께 올리면 됩니다.

규칙·DNS·TUN까지 한 번에 다루는 글들과 달리, 이 글은 대시보드와 API 보안이라는 좁은 축에 집중했습니다. 다른 증상과 섞여 보일 때는 본문의 링크를 따라가며 층을 나누어 보세요.

오픈소스 릴리스와 이슈 트래커는 신뢰할 수 있는 정보원이지만, 설치 패키지를 받을 때는 저장소 대신 사이트 다운로드 페이지를 우선 경로로 두면 경로가 단순해집니다.

Clash를 무료로 다운로드하고, external-controllersecret을 로컬에서 먼저 맞춘 뒤 Yacd·metacubexd를 다시 열어 보세요.