오류 주소를 먼저 확인한 뒤 프로세스를 종료할지 포트를 바꿀지 결정하세요
처리 순서: 바인딩에 실패한 포트 확인 → 점유 프로세스 찾기 → 중복 실행된 인스턴스 종료 또는 사용 가능한 포트로 변경 → 시스템 프록시 동기화. 구독을 삭제하거나 클라이언트를 반복해서 재설치하지 마세요. 포트 충돌은 로컬 리스닝 단계에서 발생하므로 일반적으로 원격 프록시 노드의 작동 여부와는 관계가 없습니다.
Clash 계열 클라이언트의 그래픽 인터페이스는 설정을 관리하지만, 실제 포트를 수신 대기하는 주체는 Clash, Clash Meta(mihomo) 코어 또는 클라이언트가 실행한 백그라운드 서비스일 수 있습니다. 창을 닫아도 코어가 종료되지 않을 수 있으며, 트레이나 시작 프로그램, 서비스 모드에서 리스너가 계속 실행될 수 있습니다.
로그에서 세 가지 정보 확인하기
listen tcp 127.0.0.1:7890: bind: address already in use
이 로그는 예시이며 실제 기기에서 측정한 결과가 아닙니다. TCP 리스닝에 실패했고 주소는 127.0.0.1, 포트는 7890이라는 뜻입니다. Windows에서는 “일반적으로 각 소켓 주소는 한 번만 사용할 수 있습니다”라는 메시지가 표시되기도 합니다. 실제 로그에 나온 숫자를 적어 두고, 이후 명령어에서도 해당 포트를 조회하세요.
| 설정 항목 | 용도 | 확인할 점 |
|---|---|---|
mixed-port | 하나의 포트에서 HTTP와 SOCKS 프록시 연결을 모두 수신 | 7890과 7897은 자주 쓰이는 값일 뿐, 고정된 표준은 아닙니다 |
port / socks-port | HTTP와 SOCKS 전용 포트 | mixed-port와 중복되는지 확인 |
external-controller | 코어 제어 API | 9090은 흔히 쓰이는 예시일 뿐, 인터넷 연결용 프록시 포트가 아닙니다 |
dns.listen | 코어 DNS 리스닝 주소 | UDP와 TCP가 모두 관련될 수 있으므로 TCP만 조회하지 마세요 |
Windows: 리스닝 포트에서 PID와 프로그램 경로 찾기
PowerShell을 열고 먼저 이 기기의 TCP 리스너를 조회합니다. 아래에서는 7890과 7897을 예시로 사용합니다. 일반 권한으로도 리스너 목록을 확인할 수 있지만, 다른 사용자의 프로세스 경로를 조회할 때는 관리자 권한으로 터미널을 열어야 할 수 있습니다.
Get-NetTCPConnection -State Listen -LocalPort 7890,7897 -ErrorAction SilentlyContinue |
Select-Object LocalAddress,LocalPort,State,OwningProcess
OwningProcess 값이 프로세스 PID입니다. 결과에 PID 6420이 표시되었다고 가정하고, 이름과 실행 파일 경로를 조회해 보겠습니다. 6420은 예시일 뿐이므로 실제 조회 결과를 사용하세요. 이 숫자를 그대로 입력해 해당 프로세스를 종료하면 안 됩니다.
Get-Process -Id 6420 | Select-Object Id,ProcessName,Path
Get-CimInstance Win32_Process -Filter "ProcessId = 6420" |
Select-Object ProcessId,ParentProcessId,ExecutablePath,CommandLine
명령 프롬프트에서도 조회할 수 있습니다
netstat -ano -p tcp | findstr ":7890"
netstat -ano -p tcp | findstr ":7897"
tasklist /FI "PID eq 6420"
netstat 출력에는 로컬 주소와 원격 주소가 모두 표시됩니다. 필터링 명령은 조회 범위를 좁힐 뿐이므로 로컬 주소의 포트가 실제로 7890이고 상태가 LISTENING인지 확인해야 합니다. 원격 주소에 7890이 포함되거나 상태가 TIME_WAIT인 것만으로는 프로그램이 로컬 포트를 수신 대기 중이라고 볼 수 없습니다.
- 다른 Clash 클라이언트의 경로라면 트레이 메뉴에서 정상적으로 종료한 뒤 포트를 다시 확인하세요.
- 현재 클라이언트 코어의 경로라면 이미 정상 실행 중이거나 두 번째 인스턴스가 시작된 것일 수 있습니다. 로그 시간과 상위 프로세스를 함께 확인하세요.
- 다른 앱의 경로라면 Clash 포트를 먼저 바꾸세요. 포트를 비우려고 관련 없는 프로그램을 종료하지 마세요.
- PID가 빠르게 바뀐다면 서비스 모드, 작업 관리자의 시작 앱, 서비스 관리자를 확인하세요. 백그라운드 구성 요소가 자동으로 다시 실행될 수 있습니다.
인터페이스에서 제어할 수 없는 잔류 코어임을 확인한 경우에만 Stop-Process -Id 6420 실행을 고려하세요. 프로세스를 종료하면 진행 중인 연결이 끊깁니다. 서비스에 속한 프로세스라면 해당 클라이언트에서 서비스를 먼저 중지해야 서비스 관리자가 즉시 다시 실행하는 일을 막을 수 있습니다. 이름에 Clash가 포함된 프로세스를 모두 한꺼번에 종료하지 마세요.
macOS 및 Linux: 리스닝 주소와 백그라운드 서비스 확인
macOS: lsof 사용하기
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
sudo lsof -nP -iTCP:7897 -sTCP:LISTEN
ps -p 6420 -o pid,ppid,command
-nP 옵션은 숫자 주소와 포트를 그대로 표시해 로그와 쉽게 대조할 수 있게 합니다. lsof에서는 명령 이름, PID, 리스닝 주소를 확인할 수 있습니다. 먼저 메뉴 막대에서 이전 클라이언트를 종료하고 다시 조회하세요. 리스너가 백그라운드 서비스로 실행된 경우 기본 창만 닫아서는 코어가 남을 수 있으므로 해당 클라이언트의 서비스 설정에서 중지해야 합니다.
Linux: ss 사용하기
sudo ss -ltnp 'sport = :7890'
sudo ss -ltnp 'sport = :7897'
ps -p 6420 -o pid,ppid,args
-l은 리스닝 소켓만 표시하고, -t는 TCP, -n은 숫자 형식, -p는 연결된 프로세스를 표시합니다. 프로세스가 systemd에서 관리된다면 실제 서비스 유닛을 확인한 뒤 중지하세요. 서비스 이름을 추측해서는 안 됩니다. 일부 클라이언트는 사용자 서비스를, 다른 클라이언트는 시스템 서비스를 사용하므로 사용자 수준과 시스템 수준 서비스 목록을 각각 확인해야 합니다.
일반적인 잔류 프로세스라면 먼저 kill -TERM 6420으로 종료를 요청한 뒤 포트가 해제되었는지 다시 조회하세요. 처음부터 강제 종료하지 말고 프로세스가 정상적으로 마무리할 시간을 주세요. 종료 후에도 PID가 바뀌고 포트가 계속 사용 중이라면 반복해서 프로세스를 종료하지 말고 자동 실행 원인을 찾아야 합니다.
mixed-port 변경: 새 포트를 확인한 뒤 설정 저장하기
점유 중인 프로그램을 종료할 수 없다면 Clash mixed-port를 사용 가능한 값으로 바꾸세요. 예를 들어 17890을 사용할 계획이라면 앞에서 실행한 명령어의 포트를 17890으로 바꿔 먼저 조회합니다. 리스닝 결과가 없더라도 조회 시점에 해당 포트를 사용하는 리스너를 찾지 못했다는 뜻일 뿐입니다. 재시작 후 실제 바인딩 결과를 확인하세요.
- 현재 클라이언트에서 ‘혼합 포트’ 또는 ‘Mixed Port’ 설정을 찾아 기존 값을 기록해 두세요. 메뉴 이름은 클라이언트 버전에 따라 다를 수 있습니다. 코어 제어 포트를 혼합 포트로 착각하지 마세요.
- 혼합 포트를
17890으로 바꾸고 저장한 다음, 클라이언트 안내에 따라 코어를 다시 불러오거나 재시작하세요. - 실행 로그에서 해당 포트의 바인딩 실패가 더 이상 발생하지 않는지 확인하세요.
- 리스너 목록을 다시 조회해 17890의 PID가 현재 클라이언트 코어의 PID와 일치하는지 확인하세요.
YAML을 직접 관리한다면 필요한 항목만 수정하세요
mixed-port: 17890
allow-lan: false
이 내용은 최상위 설정 일부이며 완전한 구독 설정 파일이 아닙니다. 기존 설정에 병합하고 프록시, 프록시 그룹, 규칙은 그대로 유지하세요. allow-lan: false는 이 예시에서 LAN 접속을 허용하지 않는다는 뜻입니다. 기존 설정에 다른 용도가 있다면 전체를 덮어쓰지 말고 필요한 내용을 유지하세요.
같은 설정에서 port, socks-port, external-controller와 그 밖의 리스닝 항목을 확인해 서로 다른 리스너가 같은 주소와 포트를 사용하지 않도록 하세요. 이름이 같은 mixed-port 항목을 추가하지 마세요. 중복 키의 처리 방식은 파서마다 다를 수 있습니다.
구독을 업데이트하면 구독 파일이 덮어써질 수 있고, 임시로 생성된 실행 설정은 재시작 시 다시 만들어질 수 있습니다. 클라이언트에서 유지되는 포트 설정이나 지원되는 재정의 기능을 우선 사용하세요. 두 곳에 모두 포트가 설정되어 있다면 최종 적용 설정과 로그를 확인해 실제 실행 포트가 17890인지 검증해야 합니다. 재정의 병합 순서는 클라이언트마다 다르므로 편집기에 보이는 한 줄만으로 판단할 수 없습니다.
각 항목의 자세한 용도는 혼합 포트 설정 안내를, YAML 들여쓰기 규칙은 YAML 설정 기초를 참고하세요. 이 로컬 리스닝 설정을 바꾸기 위해 프록시 노드의 서버 포트를 수정할 필요는 없습니다.
시스템 프록시 동기화: 포트 변경 후 연결 주소도 업데이트하기
코어 포트는 17890으로 바꿨는데 시스템 프록시는 여전히 7890을 가리키면 브라우저 연결은 실패합니다. 클라이언트가 시스템 프록시를 설정한다면 먼저 ‘시스템 프록시’ 스위치를 끈 다음 다시 켜 주소를 새로고침하세요. 이후 시스템 설정에서 주소를 직접 확인하고, 스위치가 켜져 있는지만 보지 마세요.
- Windows 11: ‘설정’ → ‘네트워크 및 인터넷’ → ‘프록시’ → ‘수동 프록시 설정’ → ‘편집’으로 이동합니다. 주소가
127.0.0.1, 포트가17890인지 확인하세요. Windows 10에서는 일반적으로 ‘프록시 서버 사용’ 스위치를 찾으면 됩니다. - macOS 13 이상: ‘시스템 설정’ → ‘네트워크’ → 현재 네트워크 서비스 → ‘세부사항’ → ‘프록시’로 이동합니다. 활성화된 웹 프록시, 보안 웹 프록시 또는 SOCKS 프록시를 확인하세요. 혼합 포트를 사용한다면 필요한 항목이 같은 로컬 포트를 가리키도록 설정할 수 있습니다.
- Linux 데스크톱: 데스크톱 환경의 네트워크 프록시 설정에서 수동 프록시를 확인하세요. GNOME과 KDE는 메뉴 위치가 다르며, 모든 배포판에서 같은 경로를 사용한다고 볼 수 없습니다.
브라우저 확장 프로그램, 다운로드 도구, IDE, 터미널은 시스템 프록시를 따르지 않고 자체 프록시 주소를 사용할 수 있습니다. 수동으로 입력한 7890 또는 7897을 17890으로 변경하세요. 터미널 환경 변수를 바꿔도 기존 터미널이나 이미 실행 중인 프로그램에는 이전 값이 남아 있을 수 있으므로 다시 실행해야 합니다.
# 현재 셸의 프록시 환경 변수를 확인합니다. 셸에 따라 출력이 다를 수 있습니다
env | grep -i proxy
# PowerShell에서 프록시 환경 변수 확인
Get-ChildItem Env: | Where-Object Name -Match 'proxy'
이 명령어는 값을 확인할 뿐 환경 변수를 자동으로 변경하지 않습니다. 특히 HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY를 확인하세요. 일반 HTTP 혼합 포트를 통해 HTTPS 사이트에 연결할 때 HTTPS_PROXY 값도 보통 http://127.0.0.1:17890로 설정합니다. 변수 이름은 대상 요청 유형을 뜻하며 로컬 프록시가 TLS를 사용해야 한다는 의미는 아닙니다.
수정 결과 확인: 리스너, 프록시 주소, 실제 요청을 각각 점검하기
수정한 뒤 프록시 주소를 명시한 요청을 한 번 보내 확인하세요. 시스템 프록시 캐시나 브라우저 확장 프로그램의 영향을 피할 수 있습니다. 아래에서는 테스트 대상으로 예약된 예시 도메인을 사용합니다. 대역폭 측정이 아니며 모든 사이트에 접속할 수 있다는 뜻도 아닙니다.
# Windows PowerShell: 이전 버전의 별칭을 피하려면 curl.exe를 명시적으로 실행합니다
curl.exe --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com
# macOS / Linux
curl --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com
127.0.0.1:17890에 연결할 수 없다는 메시지가 나오면 먼저 코어가 해당 포트를 수신 대기 중인지 확인하세요. 로컬 프록시에는 연결되지만 대상 연결 시간 초과, DNS 오류 또는 TLS 오류가 발생한다면 로컬 포트 문제는 해결되었을 수 있습니다. 규칙 적용 결과, 대상 도메인 조회, 선택한 프록시를 계속 확인하세요. HTTP 헤더나 터널 응답은 문제를 좁히기 위한 단서일 뿐, 임의의 상태 코드를 전체 연결이 정상이라는 증거로 보면 안 됩니다.
점유 프로세스를 찾지 못했을 때 추가로 확인할 사항
- 로그에 실패 대상이 UDP로 표시되면 Windows에서는
Get-NetUDPEndpoint -LocalPort 7890, Linux에서는sudo ss -lunp 'sport = :7890', macOS에서는sudo lsof -nP -iUDP:7890을 사용하세요. 포트 번호는 실제 오류에 나온 값으로 바꾸면 됩니다. - Windows에서 액세스 권한 오류가 발생하면
netsh interface ipv4 show excludedportrange protocol=tcp로 제외된 포트 범위를 확인하세요. IPv6 관련 문제라면 IPv6 범위도 확인해야 합니다. 시스템 예약 항목을 직접 삭제하지 말고 해당 범위 밖의 사용 가능한 포트로 변경하세요. - 포트를 해제했는데도 계속 실패한다면 로그 시간이 이번 실행 시점인지 확인하세요. 화면에 이전 기록이 남아 있을 수 있습니다. 자동으로 다시 실행되는 서비스가 있는지도 확인하세요.
- 포트를 바꾼 뒤 재시작하면 이전 값으로 돌아가는 경우 구독 업데이트, 재정의 우선순위, 클라이언트의 지속 설정을 확인해 실제 설정을 다시 기록하는 원인을 찾으세요.
나중에 확인할 수 있도록 변경 내역 기록하기
기존 포트와 새 포트, 점유 프로그램 경로, 설정을 변경한 위치를 기록해 두세요. 다음에 부팅한 뒤에는 예상한 클라이언트만 17890을 수신 대기 중인지, 시스템 프록시와 앱 프록시가 같은 주소를 가리키는지 확인하세요. 나중에 클라이언트를 종료할 때는 먼저 시스템 프록시를 끄고 종료해야 이미 중지된 로컬 포트로 연결을 시도하지 않습니다.