Linux에서 Clash 설치하기: 데스크톱 클라이언트, mihomo 명령줄 및 systemd 배포 가이드

데스크톱 배포판과 GUI 없는 서버 환경을 아우르며 설정 디렉터리, 서비스 시작, 로그 확인, 프록시 환경 변수 설정을 안내합니다.

배포 방식과 프로세서 아키텍처부터 확인하기

Linux에서 말하는 ‘Clash 설치’는 보통 두 가지 방식으로 나뉩니다. 데스크톱 방식은 그래픽 클라이언트로 커널, 구독, 시스템 프록시와 정책 그룹을 관리하며 Ubuntu, Debian, Fedora, Arch Linux 같은 데스크톱 환경의 배포판에 적합합니다. 명령줄 방식은 mihomo 커널을 직접 실행한 뒤 systemd로 프로세스를 관리하므로 서버, 소프트 라우터, 개발 머신, GUI가 없는 장치에 알맞습니다.

두 방식의 핵심 동작은 같습니다. YAML 설정을 읽고 로컬 프록시 포트를 열어 규칙에 따라 정책을 선택한 다음, 설정에 지정된 노드로 연결을 전달합니다. 차이는 관리 방식에 있습니다. 그래픽 클라이언트는 구독 업데이트, 정책 전환, 로그 창을 제공하지만 명령줄 배포에서는 설정 디렉터리, 서비스 권한, 로그와 업데이트 절차를 직접 관리해야 합니다.

현재 Linux 명령줄 배포에서는 지속적으로 유지 관리되는 mihomo를 주로 선택합니다. mihomo는 Clash Meta 계열에서 파생되었으며 Clash에서 널리 쓰이는 규칙, 정책 그룹, 프록시 프로바이더, DNS와 TUN 설정을 지원합니다. 기존 설정을 옮길 때는 파일 확장자만 확인하지 말고, 사용 중인 규칙 유형, 스크립트 필드, DNS 옵션과 실험적 기능이 현재 커널에서 지원되는지도 점검해야 합니다.

다운로드하기 전에 CPU 아키텍처를 확인하세요. 패키지 이름의 아키텍처는 시스템과 일치해야 하며, 배포판 이름만으로 판단해서는 안 됩니다. 다음 명령으로 커널이 보고하는 아키텍처를 확인합니다.

uname -m
getconf LONG_BIT
명령 출력 일반적인 패키지 표기 일반적인 장치
x86_64 amd64 또는 x86_64 대부분의 Intel·AMD 데스크톱 및 서버
aarch64 arm64 또는 aarch64 64비트 ARM 서버 및 개발 보드
armv7l armv7 일부 32비트 ARM 장치

데스크톱 배포판에 그래픽 클라이언트 설치하기

데스크톱 사용자는 계속 유지 관리되고 Linux 빌드를 명확히 제공하는 클라이언트를 우선 선택하는 것이 좋습니다. 일반적인 배포 형식으로는 AppImage, Debian 패키지, RPM 패키지가 있습니다. 형식을 고를 때는 아키텍처, 데스크톱 환경, 앱 릴리스 안내를 함께 확인하세요. 그래픽 클라이언트는 대개 사용자 설정을 시스템의 /etc가 아니라 홈 디렉터리 아래 애플리케이션 데이터 디렉터리에 저장합니다.

AppImage로 설치하기

AppImage는 단일 파일로 실행되는 형식이므로 시스템 소프트웨어 저장소를 변경하고 싶지 않은 데스크톱 환경에 적합합니다. 아키텍처에 맞는 파일을 다운로드한 뒤 먼저 실행 권한을 부여하고 터미널에서 실행하세요. 다음 예시는 설치 파일이 현재 사용자의 Downloads 디렉터리에 다운로드되어 있다고 가정합니다. 실제 파일 이름은 다운로드한 결과에 맞춰 입력해야 합니다.

cd "$HOME/Downloads"
chmod +x Clash*.AppImage
./Clash*.AppImage

터미널에서는 실행되지만 파일 관리자에서 더블클릭해도 반응이 없다면 터미널에서 실행 오류를 확인하세요. 일부 배포판에서는 사용 가능한 FUSE 실행 환경이 필요하며, 일부 AppImage는 압축을 풀어 실행할 수도 있습니다. 파일 출처와 권한의 영향을 확실히 알지 못한 상태에서 sudo로 데스크톱 클라이언트를 실행하지 마세요. 설정이 root 사용자의 디렉터리에 저장되어 이후 일반 사용자가 ‘설정이 사라졌다’고 보거나 파일을 수정하지 못할 수 있습니다.

DEB 및 RPM 패키지

Debian, Ubuntu와 그 파생 배포판에서는 해당 DEB 패키지를 설치할 수 있습니다. APT로 로컬 파일을 설치하면 패키지에 선언된 의존성도 함께 처리할 수 있습니다.

sudo apt install ./클라이언트 파일명.deb

Fedora, Rocky Linux 등 RPM 계열 배포판에서는 DNF로 로컬 패키지를 설치할 수 있습니다.

sudo dnf install ./클라이언트 파일명.rpm

설치가 끝나면 애플리케이션 메뉴에서 클라이언트를 실행한 뒤 구독 또는 로컬 YAML 파일을 가져옵니다. 구독 주소는 서비스 제공자가 제공해야 합니다. 클라이언트의 ‘구독 업데이트’는 보통 설정을 다시 다운로드하는 기능일 뿐, 클라이언트나 프록시 커널 업데이트를 의미하지 않습니다. 이 세 가지 업데이트는 각각 따로 확인해야 합니다.

데스크톱 클라이언트 최초 점검

  1. 설정 페이지에서 구독이 노드와 정책 그룹으로 정상적으로 파싱되었는지 확인합니다.
  2. 로그를 열어 수신 대기 포트가 정상적으로 생성되었는지 확인합니다.
  3. 사용할 정책 노드를 선택하고, 정책 그룹이 여전히 사용할 수 없는 항목을 가리키지 않도록 합니다.
  4. 트래픽을 가로챌 범위에 따라 시스템 프록시 또는 TUN을 선택하세요. 권한이 없는 상태에서 TUN을 바로 활성화하지 마세요.
  5. 클라이언트를 종료한 뒤 시스템 프록시가 복원되었는지 확인하여 데스크톱 환경에 작동하지 않는 로컬 포트가 남지 않도록 합니다.

GNOME, KDE, Xfce는 트레이 아이콘과 시스템 프록시를 완전히 동일하게 처리하지 않습니다. 트레이 아이콘이 사라졌다고 커널이 중지된 것은 아니므로 프로세스, 수신 대기 포트와 로그를 함께 확인해야 합니다. Wayland 세션에서는 일부 클라이언트의 창이나 트레이 구현이 데스크톱 확장 기능과 패키징 방식의 영향도 받을 수 있습니다.

mihomo 명령줄 커널 설치하기

GUI가 없는 서버에는 데스크톱 클라이언트가 필요하지 않습니다. 기본 디렉터리는 세 부분으로 나누는 것이 좋습니다. 실행 파일은 /usr/local/bin에, 설정은 /etc/mihomo에 두고 실행 로그는 systemd journal로 관리합니다. 이렇게 하면 커널을 업그레이드해도 설정이 덮어써지지 않고 권한도 일관되게 관리할 수 있습니다.

먼저 설정 디렉터리를 만듭니다. 그런 다음 다운로드하여 압축을 풀어 둔 파일 중 현재 아키텍처에 맞는 바이너리를 대상 위치로 옮깁니다.

sudo install -d -m 0750 /etc/mihomo
sudo install -m 0755 mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v

버전 명령이 정상적으로 출력되면 해당 바이너리를 현재 시스템에서 최소한 실행할 수 있다는 뜻입니다. Exec format error가 나타나면 먼저 CPU 아키텍처를 확인하세요. 경로가 실제로 존재하는데 파일을 찾을 수 없다는 메시지가 나오면 압축이 완전히 풀렸는지, 동적 링크 요구 사항이 충족되는지, 실행이 금지된 마운트 지점에 파일이 있는지도 확인해야 합니다.

서비스를 정식으로 등록하기 전에 포그라운드에서 한 번 실행 테스트를 하는 것이 좋습니다. 설정을 /etc/mihomo/config.yaml로 저장한 뒤 다음 명령을 실행합니다.

sudo /usr/local/bin/mihomo -d /etc/mihomo

-d는 작업 디렉터리를 지정합니다. 커널은 이 디렉터리에서 기본 설정을 읽고 캐시, 규칙 데이터 또는 기타 실행 파일을 저장할 수 있습니다. 포그라운드 실행은 YAML 파싱, 포트 충돌, 규칙 다운로드와 DNS 초기화 오류를 바로 확인하는 데 유용합니다. 정상 실행을 확인한 뒤 Ctrl+C로 중지하고 systemd로 전환하세요.

설정 디렉터리, 구독 및 최소 실행 설정

구독은 보통 완전한 YAML을 반환하지만, 서비스 측에서 변환된 설정을 반환하는 경우도 있습니다. 저장하기 전에 응답 내용이 로그인 페이지, 오류 메시지 또는 접근 확인 페이지가 아닌 실제 설정 텍스트인지 확인하세요. HTML 내용을 그대로 config.yaml로 저장하면 커널이 시작할 때 파싱 오류를 보고합니다.

다음 설정은 로컬 포트와 컨트롤 인터페이스의 기본 관계를 설명하기 위한 예시이며, 완전한 구독 설정이 아닙니다. 실제 프록시 노드, 정책 그룹과 규칙은 유효한 설정에서 가져와야 합니다.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false

external-controller: 127.0.0.1:9090
secret: "로컬 관리 전용 비밀번호 설정"

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false

proxies: []
proxy-groups: []
rules:
  - MATCH,DIRECT

mixed-port는 HTTP와 SOCKS5 프록시 연결을 모두 받아 명령줄 도구의 설정을 통일하기 편리합니다. allow-lan: false는 LAN 장치에 프록시를 공개하지 않는다는 뜻입니다. LAN에 서비스를 제공해야 한다면 수신 주소, 방화벽 규칙과 접근 범위도 함께 설정해야 하며 이 옵션만 켜서는 안 됩니다.

external-controller는 컨트롤 인터페이스이며 일반 프록시 포트가 아닙니다. 패널과 함께 사용할 때는 수신 범위를 제한하고 secret을 설정해야 합니다. 컨트롤 인터페이스를 모든 네트워크 인터페이스에 공개하면 관리 영역이 넓어지므로 서버에서는 루프백 주소로 먼저 제한하고 통제된 관리 채널을 통해 접근하는 것이 좋습니다.

구독에서 설정을 가져온 뒤에는 기존 파일을 먼저 백업하고 원자적으로 교체할 수 있습니다. 커널을 다시 불러오기 전에 파일 권한을 확인하세요.

sudo cp /etc/mihomo/config.yaml /etc/mihomo/config.yaml.bak
sudo chown root:mihomo /etc/mihomo/config.yaml
sudo chmod 0640 /etc/mihomo/config.yaml

서비스 계정이 설정 디렉터리에 캐시를 쓰거나 규칙 세트를 다운로드해야 한다면 디렉터리의 그룹에도 해당 작업 권한을 부여해야 합니다. 권한이 지나치게 엄격하면 규칙 프로바이더가 업데이트되지 않고, 권한 구성이 뒤섞이면 수동 실행은 정상인데 systemd 실행은 실패하는 차이가 생기기 쉽습니다.

systemd로 mihomo 관리하기

systemd는 부팅 시 커널을 시작하고 재시작, 상태와 로그를 통합 관리할 수 있습니다. 먼저 권한이 제한된 시스템 사용자를 만드세요. 이 계정에는 로그인 셸이나 홈 디렉터리가 필요하지 않습니다.

sudo useradd --system --no-create-home --shell /usr/sbin/nologin mihomo
sudo chown -R mihomo:mihomo /etc/mihomo

/etc/systemd/system/mihomo.service에 다음 서비스 유닛을 작성합니다. 이 기본 구성은 HTTP, SOCKS와 규칙 분할에 사용할 수 있습니다. 설정에서 TUN을 활성화했다면 네트워크 권한과 장치 권한을 추가로 처리해야 합니다.

[Unit]
Description=mihomo proxy service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/etc/mihomo
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

저장한 뒤 systemd 설정을 다시 불러오고 서비스를 시작한 다음 부팅 시 자동 실행을 설정합니다.

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
systemctl status mihomo --no-pager

로그를 확인할 때는 journalctl을 사용합니다. 처음 시작할 때는 최근 전체 로그를 확인하고, 지속적으로 문제를 추적할 때는 실시간 출력을 따라가세요.

journalctl -u mihomo -n 100 --no-pager
journalctl -u mihomo -f

YAML을 수정한 뒤에는 sudo systemctl restart mihomo를 실행할 수 있습니다. 재시작하기 전에 포그라운드에서 복사본을 테스트하는 것이 좋습니다. 설정 문법 오류로 서비스가 중단되는 일을 막을 수 있습니다. 구독의 정책 선택만 수정한 경우에도 해당 클라이언트나 컨트롤 패널이 선택 결과를 YAML에 기록하는지, 아니면 캐시에 저장하는지 확인해야 합니다.

TUN 모드의 systemd 권한

TUN은 가상 네트워크 인터페이스를 만들고 라우팅을 수정하므로 일반 로컬 프록시보다 높은 네트워크 권한이 필요합니다. 서비스 유닛의 [Service] 섹션에 권한을 제한해 추가하면 서비스 전체를 장기간 root로 실행하는 것보다 권한 범위를 쉽게 통제할 수 있습니다.

AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW

또한 시스템에 /dev/net/tun이 존재하는지, 커널 모듈을 사용할 수 있는지, 서비스 계정이 해당 장치에 접근할 수 있는지 확인하세요. 컨테이너나 제한된 가상 머신에서는 호스트 플랫폼이 TUN 장치와 네트워크 관리 권한을 허용해야 합니다. 설정에서 TUN을 켠다고 해서 실행 환경이 이러한 조건을 이미 제공하는 것은 아닙니다.

배포판별 systemd 보안 정책과 SELinux 또는 AppArmor 규칙이 네트워크 작업을 계속 제한할 수 있습니다. 로그의 permission denied는 커널 감사 기록과 함께 판단해야 하며, 네트워크 권한 문제를 해결하려고 디렉터리 권한만 반복해서 확대해서는 안 됩니다.

터미널, 패키지 관리자와 원격 세션에서 프록시 사용하기

mihomo가 포트를 정상적으로 열어도 애플리케이션이 요청을 해당 포트로 보내도록 설정해야 합니다. 시스템 프록시, 환경 변수와 TUN은 서로 다른 경로입니다. 명령줄 서버에서는 환경 변수가 가장 흔하고, 데스크톱 프로그램은 대개 데스크톱 환경의 시스템 프록시를 읽습니다. 프록시 설정을 따르지 않는 프로그램일 때만 TUN을 고려하세요.

현재 터미널에 임시로 설정하기

mixed-port가 7890이라고 가정하면 현재 셸에서 다음과 같이 설정할 수 있습니다.

export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export all_proxy="socks5h://127.0.0.1:7890"
export no_proxy="127.0.0.1,localhost,::1"

export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
export ALL_PROXY="$all_proxy"
export NO_PROXY="$no_proxy"

socks5hh는 대상 호스트 이름을 프록시 측에서 해석한다는 뜻이며, 이 표기를 지원하는 도구에 적합합니다. 모든 프로그램이 같은 변수 세트를 읽는 것은 아니므로 대소문자 형식을 함께 설정하면 명령줄 도구의 호환성을 높일 수 있습니다. 현재 셸을 종료하면 이 임시 변수는 사라집니다.

변수를 ~/.profile이나 셸 초기화 파일에 기록하면 로그인할 때마다 적용됩니다. 그러나 서비스가 중지된 뒤에도 이 변수를 읽는 프로그램은 계속 로컬 포트에 연결하려고 합니다. 장기간 운영하는 서버 환경에서는 필요할 때만 프록시를 활성화하고 해제하는 별도 스크립트를 사용하는 편이 좋습니다.

unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY

APT, DNF 및 Git

APT와 DNF는 일반적으로 실행 환경의 프록시 변수를 상속할 수 있지만, sudo로 실행하면 보안 정책에 의해 환경 변수가 제거될 수 있습니다. 장기간 설정해야 한다면 패키지 관리자의 프록시 설정 파일을 사용하고 필요한 저장소에만 적용하세요. Git은 사용자 단위로 HTTP 프록시를 설정할 수 있습니다.

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

Git 설정을 삭제하려면 다음을 실행합니다.

git config --global --unset http.proxy
git config --global --unset https.proxy

SSH는 HTTP 프록시 변수를 자동으로 읽지 않습니다. SSH로 저장소를 가져올 때는 SSH 설정과 프록시 명령이 연결 경로를 결정하므로, 브라우저 접속이 정상이라고 SSH도 반드시 정상이라고 판단할 수 없습니다.

원격 서버의 접근 범위

SSH로 원격 서버를 관리할 때 127.0.0.1:7890은 관리자 컴퓨터가 아니라 원격 서버 자체를 가리킵니다. mihomo가 로컬 컴퓨터에서 실행 중이라면 SSH 포트 포워딩으로 프록시 포트를 원격 측에 전달해야 하고, 서버에 mihomo를 설치했다면 애플리케이션이 서버의 로컬 수신 포트에 연결하도록 해야 합니다. 루프백 주소와 LAN 주소를 같은 것으로 취급하지 마세요.

시작 실패, 포트 충돌 및 DNS 문제 해결

서비스가 반복해서 재시작될 때

먼저 systemctl status mihomo로 종료 코드를 확인한 다음 최근 로그 100줄을 읽습니다. YAML 들여쓰기 오류, 필드 유형 오류, 설정 파일을 읽을 수 없는 문제와 작업 디렉터리에 쓸 수 없는 문제가 모두 시작 실패를 일으킬 수 있습니다. systemd의 자동 재시작으로 로그가 빠르게 넘어가므로 서비스를 먼저 중지한 뒤 같은 계정으로 포그라운드 실행을 하세요.

sudo systemctl stop mihomo
sudo -u mihomo /usr/local/bin/mihomo -d /etc/mihomo

이 단계에서 ‘root로 수동 실행하면 정상인데 서비스 계정으로는 실패하는’ 권한 차이를 확인할 수 있습니다. 수정한 뒤 서비스를 다시 시작하고, 임시 테스트 인스턴스와 systemd 인스턴스를 동시에 실행하지 마세요.

포트가 이미 사용 중일 때

ss로 수신 대기 포트와 해당 프로세스를 확인합니다.

sudo ss -lntup | grep -E '7890|7891|9090|1053'

일반적인 충돌 원인은 다른 Clash 그래픽 클라이언트, 기존 mihomo 프로세스 또는 다른 로컬 프록시입니다. 중복 인스턴스를 중지하거나 포트를 변경하고 환경 변수, 데스크톱 시스템 프록시와 컨트롤 패널 주소도 함께 업데이트해야 합니다. YAML만 수정하고 애플리케이션 측 프록시 주소를 바꾸지 않으면 커널은 정상적으로 실행되지만 모든 요청이 실패하는 현상이 나타납니다.

노드는 있지만 연결되지 않을 때

먼저 로그에서 어느 단계에서 실패했는지 확인하세요. 도메인 이름 해석 실패, 연결 시간 초과, TLS 핸드셰이크 실패와 인증 실패는 서로 다른 문제를 의미합니다. 서버 시간이 정확한지 확인하고 구독이 만료되지 않았는지 점검한 다음 정책 그룹의 현재 선택을 테스트하세요. 규칙 모드에서는 요청이 최종적으로 어떤 규칙과 정책에 매칭되었는지도 확인하여 규칙 분할 문제를 노드 장애로 오해하지 않도록 합니다.

일부 도메인에서만 문제가 발생한다면 DNS 설정, 규칙 세트 업데이트 상태와 IPv6 경로를 확인하세요. 설정에서 IPv6를 끄는 것은 커널과 관련된 해석 및 연결 선택에만 영향을 줄 뿐 운영체제의 모든 IPv6 동작을 반드시 끄는 것은 아닙니다. 데스크톱 브라우저가 자체 보안 DNS를 사용할 수도 있으므로 브라우저, 시스템과 mihomo의 해석 경로를 각각 확인해야 합니다.

시스템 프록시는 켜졌지만 일부 프로그램이 직접 연결할 때

시스템 프록시는 데스크톱 환경이 제공하는 프록시 매개변수일 뿐입니다. 브라우저와 대부분의 데스크톱 앱은 이를 읽지만, 게임, 컨테이너, 일부 명령줄 프로그램과 자체 네트워크 스택을 구현한 소프트웨어는 설정을 무시할 수 있습니다. 먼저 해당 프로그램의 자체 프록시 옵션이나 환경 변수를 사용해 보세요. 더 많은 트래픽을 실제로 가로채야 할 때 TUN을 배포합니다.

Docker 컨테이너 안의 127.0.0.1은 컨테이너 자체를 가리킵니다. 컨테이너가 호스트의 프록시에 접근하려면 연결 가능한 호스트 주소를 사용하고, mihomo의 수신 범위와 방화벽이 해당 출처를 허용하는지 확인해야 합니다. allow-lan을 활성화한 뒤에도 수신 인터페이스를 점검해야 하며, 프록시 포트를 통제되지 않은 공용 네트워크 인터페이스에 직접 노출해서는 안 됩니다.

업그레이드, 백업 및 일상적인 유지 관리

명령줄 커널을 업그레이드할 때는 바이너리와 설정을 분리해 처리해야 합니다. 현재 버전을 기록하고 서비스를 중지한 뒤 /usr/local/bin/mihomo를 교체합니다. 다시 버전 출력을 확인하고 서비스를 시작한 다음 로그를 살펴보세요. 설정 형식이 변경되었다면 해당 버전의 안내를 먼저 읽고 테스트 환경에서 검증한 후 운영 인스턴스를 교체해야 합니다.

다음 항목을 백업하는 것이 좋습니다. 기본 설정, 직접 관리하는 오버라이드 규칙, systemd 서비스 유닛과 환경 변수 스크립트입니다. 캐시 데이터베이스와 자동 다운로드된 규칙 세트는 대개 다시 생성할 수 있지만, 정책 선택이 캐시에 의존한다면 작업 디렉터리를 삭제할 때 정책 그룹이 기본값으로 돌아갈 수 있습니다.

서버를 장기간 실행할 때는 다음 상태를 정기적으로 확인할 수 있습니다.

  • systemctl is-active mihomo가 실행 상태를 반환하는지 확인합니다.
  • 로컬 프록시, DNS와 컨트롤 포트가 예상한 주소에서만 수신 대기하는지 확인합니다.
  • 로그에 규칙 다운로드 실패, DNS 시간 초과 또는 연결 재시도가 계속 나타나는지 확인합니다.
  • 구독 업데이트 시간과 노드 사용 가능 상태가 예상과 일치하는지 확인합니다.
  • 서비스를 재시작한 뒤 TUN 라우팅이 정상적으로 복원되는지 확인합니다.
  • 패키지 업그레이드 후 서비스 계정, 장치 권한과 보안 정책이 변경되지 않았는지 확인합니다.

설치 및 설정 계속하기

Linux 아키텍처와 사용 환경에 맞는 클라이언트를 선택한 뒤 빠른 시작 안내에 따라 구독 가져오기, 정책 선택과 프록시 모드 설정을 진행하세요.

Clash 다운로드