Linux에서 Clash 사용하기
Linux 데스크톱에 GUI 클라이언트를 설치하는 방법과, 헤드리스 서버에서 mihomo를 systemd 서비스로 상시 실행하는 방법을 단계별로 안내합니다.
1. 데스크톱 클라이언트와 CLI 서비스 중 선택하기
Linux에서 Clash를 사용하는 방법은 크게 두 가지입니다. 데스크톱 클라이언트는 구독 가져오기, 프록시 그룹 선택, 시스템 프록시 설정, 로그 확인을 담당합니다. 프록시 코어인 mihomo는 YAML 설정을 읽고 포트를 열어 규칙에 따라 연결을 처리합니다. 코어를 설치했다고 데스크톱의 시스템 프록시까지 자동으로 설정되는 것은 아닙니다.
| 사용 환경 | 권장 구성 | 직접 설정할 항목 |
|---|---|---|
| Ubuntu, Fedora 등 데스크톱 Linux | Clash Verge Rev, FlClash 등 GUI 클라이언트 | 구독 가져오기, 설정 활성화, 로컬 포트 확인 |
| SSH로 관리하는 서버 | mihomo와 systemd 시스템 서비스 | 설정 파일, 실행 계정, 권한, 로그, 업데이트 |
| 터미널 프로그램에만 프록시 적용 | 어느 구성이든 로컬 HTTP 프록시 제공 | 프록시 옵션 또는 환경 변수 직접 지정 |
이 글은 systemd가 활성화된 일반적인 Linux 배포판을 기준으로 합니다. 컨테이너, WSL, 경량 시스템에서는 시스템 수준의 systemd를 사용할 수 없을 수 있습니다. 먼저 아래 명령으로 환경을 확인한 뒤 설치 패키지를 선택하세요. 코어 버전은 실제 명령 실행 결과를 기준으로 확인해야 하며, 클라이언트 화면에 표시된 버전으로 추정하면 안 됩니다.
uname -m
cat /etc/os-release
ps -p 1 -o comm=
x86_64는 일반적으로 amd64 또는 x64 패키지에 해당합니다.aarch64는 일반적으로 arm64 패키지에 해당하며, x64 실행 파일은 사용할 수 없습니다.- Debian과 Ubuntu에서는 보통 DEB 패키지를, Fedora 등에서는 RPM 패키지를 사용합니다. 패키지 형식과 CPU 아키텍처가 모두 시스템에 맞아야 합니다.
2. Linux 데스크톱에 설치하고 구독 가져오기
GUI 클라이언트 설치
다운로드 페이지에서 Linux 플랫폼을 선택하고 배포판과 아키텍처에 맞는 클라이언트를 받으세요. 아래 명령을 실행하기 전에 다운로드한 DEB 파일은 clash-client.deb, RPM 파일은 clash-client.rpm으로 이름을 바꾸세요. 그런 다음 파일이 있는 디렉터리에서 해당 명령 하나만 실행합니다.
# Debian / Ubuntu: 이 명령만 실행
sudo apt install ./clash-client.deb
# Fedora: 이 명령만 실행
sudo dnf install ./clash-client.rpm
패키지 관리자가 의존성을 확인합니다. GUI 구성 요소가 없다는 메시지가 나오면, SSH 전용 세션에서 창 프로그램을 반복 실행하기보다 데스크톱 환경이 설치되어 있는지 먼저 확인하세요. 설치가 끝나면 애플리케이션 메뉴에서 클라이언트를 실행하면 됩니다. 일반적으로 전체 GUI를 sudo로 실행할 필요는 없습니다.
설정을 가져온 뒤 시스템 프록시 활성화
- Clash Verge Rev를 예로 들면, ‘구독’ 페이지에서 구독 URL을 추가하고 다운로드가 끝나면 해당 설정을 선택합니다. 버튼 이름은 버전에 따라 조금 다를 수 있습니다.
- ‘프록시’ 페이지에서 프록시 그룹을 확인하고 사용할 노드를 선택하세요. ‘규칙’ 모드에서는 설정된 규칙에 따라 요청이 분기됩니다. 노드를 선택해도 모든 연결이 자동으로 프록시를 통과하는 것은 아닙니다.
- ‘설정’에서 ‘시스템 프록시’와 포트 설정을 확인하고 실제 혼합 포트 번호를 기록하세요. 이후 예시에서는
7890을 사용합니다. 화면의 포트가 다르면 명령에 사용된 포트도 함께 바꿔야 합니다. - 먼저 시스템 프록시를 활성화해 브라우저를 테스트한 뒤 터미널을 따로 확인하세요. 다른 클라이언트의 시스템 프록시를 동시에 켜면 설정이 서로 덮어쓸 수 있습니다.
데스크톱 환경에는 보통 자체 프록시 설정 메뉴가 있습니다. 예를 들어 GNOME에서는 ‘설정’ → ‘네트워크’ → ‘네트워크 프록시’에서 확인할 수 있습니다. 여기서 클라이언트가 예상한 주소를 설정했는지 살펴볼 수 있지만, 모든 앱이 데스크톱 프록시 설정을 사용하는 것은 아닙니다. 브라우저에서 웹페이지가 열린다는 이유만으로 시스템 전체에 프록시가 적용됐다고 판단하지 말고, 터미널의 curl, Git, 패키지 관리자도 각각 확인하세요.
3. mihomo 설치 및 서비스 계정 생성
헤드리스 서버에는 GUI 클라이언트를 설치할 필요가 없습니다. 아키텍처에 맞는 mihomo 코어를 다운로드하고 파일 형식에 맞게 압축을 푼 다음, 실행 파일 이름을 mihomo로 변경하세요. 아래 절차는 현재 디렉터리에 압축 파일이 아니라 압축을 푼 실행 파일이 있다고 가정합니다.
chmod +x ./mihomo
./mihomo -v
sudo install -m 0755 ./mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v
Exec format error가 표시되면 먼저 아키텍처가 맞는지, 파일 압축을 제대로 풀었는지 확인하세요. Permission denied가 표시되면 실행 권한과 파일 시스템의 noexec 마운트 옵션을 점검하세요. 실행 문제를 해결하려고 파일에 불필요한 쓰기 권한을 부여하지 마세요.
프로그램, 설정, 실행 데이터 분리하기
전용 시스템 계정으로 서비스를 실행하세요. 설정은 /etc/mihomo에, 캐시와 규칙 데이터는 /var/lib/mihomo에 두고, 실행 파일은 /usr/local/bin에 보관합니다. 아래 계정 생성 명령은 한 번만 실행하면 됩니다. 시스템에 같은 이름의 계정이 이미 있으면 용도와 권한부터 확인하세요.
sudo useradd --system --user-group \
--home-dir /var/lib/mihomo \
--shell /usr/sbin/nologin mihomo
sudo install -d -o root -g mihomo -m 0750 /etc/mihomo
sudo install -d -o mihomo -g mihomo -m 0750 /var/lib/mihomo
여기서는 일반 사용자 계정으로 7890 포트를 열기 때문에 낮은 포트를 바인딩하는 권한이 필요하지 않습니다. 이 서비스 구성에서는 TUN도 사용하지 않으므로 네트워크 관리 권한을 부여하지 않습니다. 나중에 TUN을 추가해야 한다면 장치 접근, 권한 범위, 라우팅 동작을 다시 검토하세요. 서비스를 계속 root로 실행하는 방식은 피해야 합니다.
4. 설정 준비 및 시작 전 점검
실제 구독을 연결하기 전에 최소 설정으로 프로그램, 권한, 수신 포트를 확인하세요. 아래는 로컬 직결 테스트용 전체 설정입니다. 프록시 노드를 만들지 않으며 모든 요청을 직접 연결합니다. HTTP와 SOCKS 혼합 포트가 정상 작동하는지 확인하는 용도로만 사용하세요.
sudo tee /etc/mihomo/config.yaml > /dev/null <<'YAML'
mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false
proxies: []
proxy-groups: []
rules:
- MATCH,DIRECT
YAML
sudo chown root:mihomo /etc/mihomo/config.yaml
sudo chmod 0640 /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo \
-t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
-t는 설정을 검사하고, -d는 작업 디렉터리를, -f는 설정 파일을 지정합니다. 테스트를 통과했다는 것은 코어가 설정을 읽을 수 있다는 뜻일 뿐, 노드에 연결되거나 대상 사이트에 접속할 수 있다는 의미는 아닙니다. GeoIP, GeoSite 또는 원격 규칙 세트를 사용하는 설정은 해당 데이터 파일을 준비하고 다운로드 경로도 확인해야 할 수 있습니다.
실제 구독 설정으로 교체
현재 디렉터리에 있는 profile.yaml처럼 mihomo와 호환되고 로컬에 저장된 YAML 파일을 준비하세요. 파일 내용이 실제 설정인지 확인해야 합니다. 구독 오류 페이지나 로그인 페이지, 노드 목록만 들어 있는 인코딩된 텍스트가 아닌지 확인한 뒤 지정된 경로에 덮어씁니다.
sudo install -o root -g mihomo -m 0640 \
./profile.yaml /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo \
-t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
- 서비스에 필요한
mixed-port: 7890과 로컬 수신 제한은 유지하세요. 설정에 같은 키가 이미 있다면 기존 값을 수정하고 중복 키를 추가하지 마세요. proxy-groups에서 참조하는 노드 이름과 규칙에서 참조하는 정책 그룹 이름이 서로 일치하는지 확인하세요.proxy-providers또는rule-providers를 사용한다면 로컬 캐시 경로를 작업 디렉터리 아래에 두는 것이 좋습니다. 예를 들어./providers를 사용하고, 서비스 계정이 쓸 수 없는 설정 디렉터리는 지정하지 마세요.tun, LAN 수신 또는 원격 제어 인터페이스가 실수로 활성화되어 있지 않은지 확인하세요. 구독에 포함된 실행 옵션도 검토해야 합니다.
5. systemd로 서비스 상시 실행
시스템 수준 서비스 유닛을 만듭니다. 전용 계정으로 실행하고, 시작 전에 설정을 검사하며, 프로세스가 비정상 종료되면 5초 후 다시 시작합니다. 보안 강화 옵션에 따라 시스템 디렉터리는 읽기 전용으로 설정되고 실행 데이터 디렉터리에만 쓰기가 허용됩니다. 따라서 설정에 지정하는 캐시 파일도 해당 디렉터리 아래에 두어야 합니다.
sudo tee /etc/systemd/system/mihomo.service > /dev/null <<'UNIT'
[Unit]
Description=mihomo local proxy service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/var/lib/mihomo
ExecStartPre=/usr/local/bin/mihomo -t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=5
UMask=0077
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/mihomo
[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service
systemctl status mihomo.service --no-pager
sudo journalctl -u mihomo.service -n 80 --no-pager
enable --now는 부팅 시 자동 시작을 설정하는 동시에 서비스를 바로 시작합니다. network-online.target은 시작 순서만 지정합니다. 실제 동작은 배포판의 네트워크 대기 서비스에도 영향을 받으므로, 이 시점에 구독 서버나 프록시 노드에 연결할 수 있다고 보장하지는 않습니다.
변경 사항 적용 방법
YAML만 수정했다면 앞서 설명한 -t 테스트를 먼저 실행하고 통과한 뒤 sudo systemctl restart mihomo.service를 실행하세요. 서비스 유닛을 수정했다면 sudo systemctl daemon-reload를 실행한 다음 서비스를 다시 시작합니다. 이 구성에는 ExecReload가 없으므로 systemctl reload를 설정 다시 불러오기 명령으로 사용할 수 없습니다.
6. 포트, 요청, 규칙을 각각 확인하기
1단계: 포트가 실제로 열려 있는지 확인
sudo ss -lntp 'sport = :7890'
curl --proxy http://127.0.0.1:7890 \
--connect-timeout 10 --max-time 30 \
-I https://example.com/
curl --proxy socks5h://127.0.0.1:7890 \
--connect-timeout 10 --max-time 30 \
-I https://example.com/
수신 주소는 루프백 주소여야 하며 외부에 공개되는 0.0.0.0:7890이어서는 안 됩니다. 두 curl 명령은 혼합 포트의 HTTP 및 SOCKS 연결을 각각 확인합니다. socks5h는 대상 도메인의 처리를 프록시에 맡기므로 curl이 로컬에서 도메인을 먼저 조회하는 문제를 배제하는 데 유용합니다. 다만 mihomo가 최종적으로 어떤 DNS 업스트림을 사용할지 결정하는 옵션은 아닙니다.
최소 설정에서 요청이 성공했다면 직결 연결이 정상이라는 점만 확인된 것입니다. 실제 설정으로 바꾼 뒤에는 로그에서 규칙 매칭과 정책 선택을 살펴 테스트 도메인이 예상한 노드를 사용하는지 확인하세요. HTTP 연결 성공, 대상 사이트의 응답 코드, 예상한 출구 IP는 각각 별도로 확인해야 합니다.
2단계: 터미널 프로그램에 프록시를 명시적으로 지정
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export no_proxy=localhost,127.0.0.1,::1
curl -I --connect-timeout 10 --max-time 30 https://example.com/
# 현재 터미널에서 위 설정만 해제
unset http_proxy https_proxy no_proxy
https_proxy의 값으로 http://를 사용해도 됩니다. 이는 HTTP 프록시의 CONNECT 터널을 통해 HTTPS 사이트에 접속한다는 의미이지, 대상 사이트를 HTTP로 낮춘다는 뜻이 아닙니다. 환경 변수는 현재 프로세스와 하위 프로세스에만 적용됩니다. 다른 터미널이나 데스크톱 앱, 이미 실행 중인 systemd 서비스에는 자동으로 전달되지 않습니다.
특정 프로그램에서만 문제가 생긴다면 해당 프로그램이 자체적으로 프록시를 지원하는지 확인하세요. 기본 설정에서는 sudo가 환경 변수를 제거할 수도 있습니다. curl에 프록시 설정이 적용됐다고 해서 APT, 컨테이너 빌드, 백그라운드 서비스도 같은 프록시를 사용한다고 단정해서는 안 됩니다.
7. 원격 사용과 TUN 권한 범위
서버의 127.0.0.1은 서버 자신을 가리키며 로컬 컴퓨터를 뜻하지 않습니다. 테스트를 위해 서버의 프록시를 잠시 사용하려면 혼합 포트를 인터넷에 직접 공개하지 않고 로컬에서 SSH 포트 포워딩을 사용할 수 있습니다. 192.0.2.10은 문서용 예시 주소이므로 실행 전에 실제 서버 주소로 바꾸고, ops도 실제 SSH 계정으로 변경하세요.
# 로컬 컴퓨터에서 실행하고 이 세션을 열어 둡니다
ssh -N -o ExitOnForwardFailure=yes \
-L 127.0.0.1:17890:127.0.0.1:7890 [email protected]
# 로컬 컴퓨터의 다른 터미널에서 테스트
curl --proxy http://127.0.0.1:17890 \
--connect-timeout 10 --max-time 30 \
-I https://example.com/
로컬 포트에 17890을 사용하면 흔히 쓰이는 로컬 클라이언트 포트와 충돌을 피할 수 있습니다. LAN에 프록시를 제공해야 한다면 allow-lan, 수신 주소, 인증, 방화벽을 함께 설정하고 허용할 출발지 네트워크를 제한하세요. 제어 인터페이스 포트와 프록시 수신 포트는 서로 다르며, 제어 인터페이스를 프록시 주소로 사용해서는 안 됩니다.
TUN은 배포 성공을 위한 필수 조건이 아닙니다
TUN은 가상 네트워크 인터페이스와 라우팅을 통해 조건에 맞는 IP 트래픽을 처리하며, 시스템 프록시를 사용하지 않는 앱에 적합합니다. Linux에서는 보통 /dev/net/tun, 네트워크 관리 권한, DNS 라우팅 설정이 필요합니다. 이 글의 서비스 구성은 일반 사용자 계정과 보안 제한을 사용하므로 TUN을 지원하도록 설정되어 있지 않습니다. YAML에 tun.enable: true만 추가하면 권한 부족으로 실패할 수 있습니다.
8. 문제 해결 및 정기 업데이트
| 증상 | 우선 확인할 항목 | 해결 방법 |
|---|---|---|
| 서비스가 종료되고 포트가 열리지 않음 | journalctl 로그와 설정 검사 결과 | YAML, 파일 권한 또는 규칙 리소스 문제를 수정한 뒤 다시 시작 |
| 로그에 address already in use가 표시됨 | ss로 7890 포트를 점유한 프로세스 확인 | 중복 실행 중인 코어를 종료하거나 수신 포트와 앱의 프록시 주소를 동일하게 변경 |
| 브라우저는 되지만 터미널은 직접 연결됨 | 터미널의 프록시 옵션과 환경 변수 | 먼저 curl의 --proxy 옵션으로 명시적으로 테스트 |
| 프록시에 연결되지만 요청은 계속 직결됨 | 규칙 순서, 정책 그룹 선택, 로그의 아웃바운드 확인 | DIRECT 규칙에 매칭됐거나 직결 정책을 선택했는지 확인 |
| 규칙 세트 다운로드 실패 | 작업 디렉터리 권한, 다운로드 주소, 현재 네트워크 | 캐시 경로에 쓰기 권한이 있는지 확인하고, 업데이트 경로가 아직 사용할 수 없는 프록시에 의존하지 않는지 점검 |
업데이트 전 되돌릴 수 있도록 기존 프로그램과 설정 보관
코어를 업데이트하기 전에 mihomo -v 출력을 기록하고 기존 실행 파일을 보관하세요. 새 실행 파일은 임시 경로에 두고 버전 확인 명령과 설정 검사를 먼저 실행해 현재 사용 중인 프로토콜과 필드를 지원하는지 확인합니다. 그다음 서비스를 중지하고 실행 파일을 교체한 뒤 다시 시작하세요. 실행 중인 파일을 바로 덮어쓰지 말고, 문제 해결 과정에서 프로그램 업데이트와 대규모 규칙 변경을 한꺼번에 하지 마세요.
구독 설정을 업데이트하기 전에 /etc/mihomo/config.yaml을 백업하고 포트, 수신 주소, 제어 인터페이스, TUN, provider 경로를 비교하세요. 설정 검사에 통과한 뒤 서비스를 다시 시작하고 포트 확인과 명시적 프록시 요청을 반복합니다. 이 순서대로 진행하면 문제를 프로그램, 설정, 네트워크 중 한 영역으로 좁힐 수 있어 여러 항목을 한 번에 바꿔 원인을 놓치는 일을 줄일 수 있습니다.
데스크톱 구성에서는 현재 설정, 정책 그룹, 시스템 프록시가 서로 일치하는지가 중요합니다. 서버 구성에서는 계정 권한, 고정 설정 경로, systemd 로그를 중점적으로 확인하세요. 먼저 기본 로컬 프록시를 안정적으로 작동시킨 뒤 필요에 따라 자동 업데이트, 원격 관리, TUN을 추가하면 유지 관리 부담을 줄일 수 있습니다.