오류 메시지부터 확인: 충돌한 리스닝 항목은 무엇인가
Clash GUI 클라이언트는 열리지만 코어가 시작되지 않고 로그에 address already in use가 표시된다면, 바인딩하려는 주소와 포트를 다른 프로세스가 이미 사용 중일 가능성이 큽니다. 먼저 로그에 나온 프로토콜, 주소, 포트를 기록한 다음 프로세스를 확인하세요. ‘시작 실패’만 보고 구독을 다시 가져오지는 마세요.
listen tcp 127.0.0.1:7890: bind: address already in use
다음은 오류 메시지의 예시이며 실제 측정 결과가 아닙니다. 이 메시지는 로컬 TCP 7890 포트를 가리키며, 노드가 작동하지 않는다는 뜻은 아닙니다. Windows에서는 “일반적으로 각 소켓 주소는 한 번만 사용할 수 있습니다”와 같은 메시지가 표시될 수도 있습니다. 로그에 access denied 또는 권한 거부가 표시되면 포트 제외 범위와 보안 정책도 확인해야 합니다. 일반적인 포트 점유로 단정해서는 안 됩니다.
| 항목 | 용도 | 확인할 사항 |
|---|---|---|
mixed-port | 하나의 포트에서 HTTP와 SOCKS 프록시 요청을 모두 수신 | 예: 7890. 시스템 프록시와 수동 설정한 프록시 앱도 함께 확인 |
port / socks-port | HTTP와 SOCKS 프록시 진입점을 각각 제공 | 활성화된 다른 리스너와 주소·포트가 겹치지 않아야 함 |
external-controller | 코어 제어 API 제공 | 예: 127.0.0.1:9090. 브라우저 프록시 포트가 아님 |
dns.listen | 코어 DNS 리스너 제공 | 예: 127.0.0.1:1053. 로그에 표시된 TCP 또는 UDP를 확인 |
Windows: 리스닝 PID 확인 후 프로세스 경로 확인
PowerShell로 TCP 리스닝 확인
시작 메뉴를 마우스 오른쪽 버튼으로 클릭하고 ‘터미널’ 또는 ‘Windows PowerShell’을 엽니다. 먼저 아래 명령을 실행하세요. 조회가 제한되거나 다른 사용자의 프로세스 정보를 확인해야 할 때는 관리자 권한으로 터미널을 여세요.
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
OwningProcess는 프로세스 ID입니다. 결과가 1234라고 가정하고 프로세스 이름, 경로, 시작 인수를 확인해 보겠습니다. 여기서 1234는 설명을 위한 예시이므로 실제 조회 결과로 바꿔야 합니다.
Get-Process -Id 1234 | Select-Object Id, ProcessName, Path
Get-CimInstance Win32_Process -Filter "ProcessId = 1234" |
Select-Object ExecutablePath, CommandLine
프로세스 이름보다 경로와 시작 인수가 더 유용합니다. 서로 다른 클라이언트가 모두 mihomo.exe라는 이름의 코어를 실행할 수 있습니다. 명령줄에 표시된 설정 파일 경로를 보면 어떤 클라이언트에 속하는지 판단하는 데 도움이 됩니다. 프로세스 이름에 Clash나 mihomo가 들어 있다는 이유만으로 강제 종료하지 마세요.
명령 프롬프트로 확인하는 방법
netstat -ano -p tcp | findstr ":7890"
tasklist /FI "PID eq 1234"
netstat을 사용할 때는 ‘로컬 주소’ 열의 포트와 LISTENING 상태를 확인하세요. findstr는 텍스트를 필터링할 뿐이므로 원격 주소나 더 긴 포트 번호까지 함께 일치할 수 있습니다. TIME_WAIT 항목은 현재 프로세스가 리스닝 중이라는 뜻이 아닙니다.
리스닝 항목은 없는데 바인딩할 수 없다는 오류가 계속 표시되는 경우
먼저 클라이언트가 코어를 반복해서 재시작해 조회하는 순간에는 리스너가 사라지는지 확인하세요. 로그가 권한 오류를 가리킨다면 관리자 터미널에서 Windows의 TCP 제외 포트 범위를 확인할 수 있습니다.
netsh interface ipv4 show excludedportrange protocol=tcp
대상 포트가 제외 범위에 포함된다면 범위에 속하지 않는 사용 가능한 포트로 바꾸는 것이 우선입니다. 시스템 예약 항목을 임의로 삭제하지 마세요. Hyper-V, 컨테이너 또는 다른 네트워크 구성 요소가 해당 설정에 의존할 수 있습니다. 오류에 IPv6 주소가 명시되어 있다면 IPv6 환경도 확인해야 합니다.
macOS·Linux: 일반 프로세스와 백그라운드 서비스 구분하기
macOS: lsof로 리스닝 프로세스 확인
‘터미널’을 열고 TCP 7890을 리스닝하는 프로세스를 조회합니다. -nP 옵션은 주소와 포트가 이름으로 변환되지 않게 하므로 로그와 대조하기 쉽습니다.
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
ps -p 1234 -o pid,ppid,user,command
첫 번째 명령에서 반환된 PID를 두 번째 명령에 사용해야 합니다. 메뉴 막대에 다른 프록시 클라이언트가 계속 실행 중이라면 해당 메뉴에서 정상적으로 종료한 뒤 다시 조회하세요. 일부 클라이언트는 창을 닫아도 계속 실행됩니다. 창이 사라졌다고 코어까지 종료된 것은 아닙니다.
Linux: ss로 소켓 확인
sudo ss -ltnp 'sport = :7890'
ps -p 1234 -o pid,ppid,user,args
-l은 리스닝, -t는 TCP, -n은 숫자 표시, -p는 프로세스 정보 표시를 뜻합니다. 배포판에 ss가 설치되어 있지 않다면 lsof를 사용할 수 있는 환경에서 macOS 항목의 조회 명령을 실행하세요.
프로세스가 systemd로 관리된다면 프로세스를 직접 종료해도 자동으로 다시 시작될 수 있습니다. systemctl status 1234를 실행해 소속 서비스를 확인한 다음, 실제 서비스 단위를 확인한 경우에만 중지하세요. 사용자 단위 서비스는 systemctl --user로 조회해야 합니다. 서비스 이름을 추측해 일괄 중지하지 마세요.
DNS 포트 충돌은 UDP로 다시 확인
앞의 명령은 TCP만 확인합니다. 로그에 UDP 1053이 표시되면 아래 명령을 사용하세요. 다른 포트를 확인하려면 숫자를 바꾸면 됩니다. 같은 포트 번호라도 TCP와 UDP는 서로 다른 전송 프로토콜이므로 TCP 조회 결과가 비어 있다고 UDP도 사용 가능하다는 뜻은 아닙니다.
# macOS 또는 lsof가 설치된 Linux
sudo lsof -nP -iUDP:1053
# Linux
sudo ss -lunp 'sport = :1053'
충돌 원인 파악: 중복 코어, 다른 프로그램 또는 설정 중복
프로세스 경로를 확인한 다음 해결 방법을 선택하세요. 포트 점유만으로 소프트웨어를 삭제하거나 노드 프로토콜, 규칙 모드, 구독 주소를 먼저 변경할 필요는 없습니다.
- 이전 클라이언트가 백그라운드에서 실행 중입니다. 예를 들어 한 클라이언트가 7890 포트를 사용 중인데 다른 클라이언트도 시작하면서 7890을 요청할 수 있습니다. 사용할 클라이언트는 남겨 두고 다른 클라이언트를 정상 종료한 뒤, 시작 프로그램에 등록되어 있는지도 확인하세요.
- GUI 밖에서 별도의 서비스 인스턴스가 실행 중입니다. 직접 실행한 코어, 시스템 서비스 또는 예약 작업이 다른 설정 파일을 불러올 수 있습니다. 프로세스가 어디에 속하는지 확인한 뒤 해당 인스턴스를 중지하세요. 서비스 관리자가 곧바로 다시 실행하지 않는지도 확인해야 합니다.
- 포트를 다른 필수 프로그램이 사용 중입니다. 점유 프로그램의 용도가 분명하다면 그대로 두고 Clash의 리스닝 포트를 바꾸세요. 포트를 비우려고 시스템 프로세스나 정체를 알 수 없는 서비스를 종료하지 마세요.
- 하나의 설정에서 리스너가 중복됩니다.
port,socks-port,mixed-port가 같은 주소와 포트를 사용하는지 확인하세요. 혼합 포트 하나로 두 종류의 요청을 모두 받을 수 있으므로 같은 포트에 별도 리스너를 추가할 필요가 없습니다.
바인딩 주소도 확인하세요. 127.0.0.1:7890은 로컬 루프백 인터페이스에서만 사용할 수 있지만, 0.0.0.0:7890은 모든 IPv4 인터페이스에서 수신합니다. 두 주소가 충돌할 수 있습니다. IPv6의 [::]:7890이 IPv4까지 함께 처리하는지는 시스템과 소켓 설정에 따라 다릅니다. 모든 인터페이스에서 리스닝하도록 바꾸는 것을 일반적인 해결책으로 삼지 마세요. 프록시 진입점에 접근할 수 있는 범위도 넓어집니다.
리스닝 포트 변경: 실제 적용되는 설정 위치 수정
7897 포트를 확인한 뒤 mixed-port 변경
앞서 사용한 조회 명령에서 7890을 7897로 바꿔 현재 충돌이 없는지 확인하세요. 클라이언트 두 개를 계속 사용해야 한다면 각 클라이언트에 서로 다른 프록시 진입점을 할당하세요. 제어 API 등 다른 리스너도 각각 확인해야 합니다.
# 확인할 항목만 표시한 예시이며 전체 설정이 아닙니다
mixed-port: 7897
allow-lan: false
mode: rule
이 예시는 로컬에서만 사용할 혼합 프록시 진입점에 적합합니다. 기존 YAML에 반영할 때는 이미 있는 항목을 수정하고 파일 끝에 두 번째 mixed-port를 추가하지 마세요. 기존에 별도의 port 또는 socks-port가 있다면 실제 용도에 따라 비활성화하거나 다른 포트를 지정하세요. 구독 전체를 이 세 줄로 바꾸지 마세요. 노드, 프록시 그룹, 규칙은 그대로 유지해야 합니다.
구독 파일과 GUI 클라이언트 설정 중 무엇이 우선할까
Clash는 코어와 설정 생태계를 통칭하며, GUI 클라이언트마다 메뉴와 설정 덮어쓰기 방식이 다릅니다. 현재 사용하는 클라이언트의 ‘설정’에서 ‘포트’, ‘혼합 포트’ 또는 ‘Mixed Port’를 찾아 기존 값을 기록한 뒤 변경하세요. 특정 클라이언트의 메뉴 경로가 모든 버전에 공통된다고 가정하지 않습니다.
- 클라이언트에서 포트 설정을 제공하는 경우: 해당 설정에서 먼저 변경하고 화면 안내에 따라 코어를 재시작하세요. 구독 파일의 같은 항목을 덮어쓸 수 있습니다.
- 코어를 직접 실행하는 경우: 시작 인수로 지정한 설정 파일을 수정하세요. 다른 다운로드 사본이 아니라 현재 실제로 불러오는 파일인지 확인해야 합니다.
- 구독이 자동 업데이트되는 경우: 클라이언트에서 제공하는 영구 덮어쓰기 또는 병합 기능을 사용하세요. 다운로드된 구독 파일을 직접 수정하면 업데이트할 때 변경 내용이 사라질 수 있습니다.
저장한 뒤 코어를 재시작하고 시작 로그와 실제 리스닝 상태를 확인하세요. 설정 편집기에 7897이 표시된다고 실행 중인 코어의 포트가 바뀐 것은 아닙니다. 변경 후에도 7890 오류가 계속되면 포트 점유뿐 아니라 설정 우선순위, 설정 파일 경로, 올바른 인스턴스를 재시작했는지도 확인해야 합니다.
충돌 항목이 external-controller라면 해당 제어 주소만 변경하세요. 예를 들어 127.0.0.1:9090을 사용 가능한 것으로 확인한 127.0.0.1:9097로 바꾸고 패널의 연결 설정도 함께 수정합니다. 제어 API를 일반 프록시 포트로 설정해서는 안 되며, 문제 해결을 위해 인터넷에 노출해서도 안 됩니다.
포트를 바꾼 뒤 함께 수정해야 할 항목
코어는 7897 포트에서 정상적으로 시작됐는데 브라우저가 여전히 7890에 연결하면 ‘포트 오류는 사라졌지만 웹페이지가 열리지 않는’ 상황이 생길 수 있습니다. 이때는 노드를 계속 바꾸기보다 프록시를 사용하는 앱을 확인하세요.
| 사용 위치 | 함께 수정할 내용 |
|---|---|
| 시스템 프록시 | 포트가 7897로 변경되었는지 확인하세요. 클라이언트에서 시스템 프록시를 껐다가 다시 켠 뒤 시스템 설정도 확인할 수 있습니다. |
| 브라우저 프록시 확장 프로그램 | 수동으로 설정한 HTTP 또는 SOCKS 포트를 변경하세요. 주소는 대개 127.0.0.1을 그대로 사용합니다. |
| 터미널 환경 변수 | HTTP_PROXY, HTTPS_PROXY, ALL_PROXY와 이에 대응하는 소문자 변수도 확인하세요. |
| Git, 다운로드 프로그램, 개발 도구 | 각 프로그램에 별도로 저장된 프록시 주소를 변경하세요. 시스템 프록시만 바꾸면 충분하지 않습니다. |
| LAN 기기 | 컴퓨터의 프록시를 사용하던 휴대전화나 TV에서는 컴퓨터의 LAN 주소와 함께 새 포트도 설정해야 합니다. |
| 외부 제어 패널 | 제어 API 포트가 바뀐 경우에만 연결 주소를 변경하세요. 프록시 진입점과는 별도로 관리해야 합니다. |
Windows 11에서는 ‘설정’ → ‘네트워크 및 인터넷’ → ‘프록시’ → ‘수동 프록시 설정’에서 주소와 포트를 확인할 수 있습니다. macOS에서는 ‘시스템 설정’ → ‘네트워크’ → 현재 네트워크 연결의 ‘세부사항’ → ‘프록시’에서 확인하세요. OS 버전에 따라 메뉴 이름이 다를 수 있으며, 클라이언트가 관리하는 설정은 시작할 때 다시 적용될 수도 있습니다.
터미널에서 HTTPS_PROXY=http://127.0.0.1:7897은 HTTPS 대상에 HTTP 프록시를 통해 접속한다는 뜻입니다. 로컬 프록시 진입점 자체가 TLS를 사용해야 하는 것은 아닙니다. 앱에서 SOCKS를 사용한다면 해당 프로토콜을 선택하세요. 예를 들어 socks5h는 보통 프록시 측에서 대상 도메인을 조회한다는 의미이며, 실제 지원 여부는 앱에 따라 다릅니다.
TUN 모드는 가상 네트워크 인터페이스로 라우팅 조건에 맞는 트래픽을 처리하며, 모든 앱이 mixed-port를 사용한다는 뜻은 아닙니다. 하지만 앱에 남아 있는 수동 프록시 설정이 요청을 이전 포트로 보낼 수 있습니다. TUN 시작 여부, 라우팅 설정, 프록시 리스닝 포트 충돌은 각각 따로 확인해야 합니다.
결과 확인: 리스닝 복구 후 실제 요청 테스트
- 로그를 다시 확인해 기존 바인딩 오류가 반복되지 않고 제어 API나 DNS 포트 충돌도 새로 발생하지 않았는지 확인하세요.
- 새 포트를 조회해 리스닝 프로세스가 이전 코어가 아니라 현재 사용하는 클라이언트에 속하는지 확인하세요.
- 프록시를 명시적으로 지정해 요청을 보내고 시스템 프록시 설정이 아직 반영되지 않은 영향을 배제하세요.
- 그다음 브라우저에서 대상 사이트에 접속해 클라이언트의 연결 기록과 규칙 적용 결과를 확인하세요.
# macOS / Linux
curl -I --proxy http://127.0.0.1:7897 --connect-timeout 5 --max-time 15 https://example.com
# Windows PowerShell: curl.exe를 명시적으로 실행
curl.exe -I --proxy http://127.0.0.1:7897 --connect-timeout 5 --max-time 15 https://example.com
여기서 example.com은 테스트 주소의 예시이며 확인하려는 사이트 주소로 바꿀 수 있습니다. 대상 서버의 응답 헤더가 도착하면 해당 요청의 접속 과정이 완료된 것입니다. Connection refused가 표시되면 주소, 포트, 리스닝 상태부터 확인하세요. 로컬 프록시가 연결을 수락한 뒤 시간 초과, 인증 실패 또는 상위 서버 연결 오류가 발생한다면 노드, DNS, 네트워크 연결, 규칙을 점검해야 합니다. 이런 문제까지 모두 포트 점유로 보아서는 안 됩니다.
포트 문제가 해결된 상태란 대상 코어가 안정적으로 리스닝하고, 시스템과 앱이 새 포트를 사용하며, 클라이언트를 재시작하거나 구독을 업데이트한 뒤에도 설정이 유지되는 것입니다. ‘로그 확인 → 프로세스 조회 → 소속 판별 → 적용 중인 설정 수정 → 앱 설정 동기화 → 요청 테스트’ 순서로 점검하면 포트 충돌과 다른 네트워크 문제를 대체로 구분할 수 있습니다. 이후 설정은 Clash 설정 가이드를, 자주 발생하는 연결 문제는 자주 묻는 질문을 참고하세요.