사용 방식과 트래픽 경로 먼저 정하기
Linux용 Clash 호환 클라이언트는 보통 GUI와 프록시 코어로 구성됩니다. mihomo는 YAML 설정을 읽고 로컬 포트에서 연결을 수신하며 라우팅 규칙을 적용하는 프록시 코어입니다. GUI 클라이언트는 구독 가져오기, 설정 관리, 정책 그룹 선택, 시스템 프록시 또는 TUN 사용을 담당합니다. 두 구성 요소는 하나의 설치 패키지가 아니며, 설정 파일 경로도 정해져 있지 않습니다.
GNOME이나 KDE 같은 데스크톱 환경에서 노드를 자주 바꿔 쓴다면 GUI 클라이언트를 권장합니다. SSH만 가능한 서버나 부팅 시 자동 실행, 로그 통합 관리가 필요한 환경에서는 mihomo와 systemd를 사용하면 권한과 파일 소유자를 명확하게 관리하기 쉽습니다. 이 문서의 CLI 설정은 systemd를 사용하는 일반적인 Linux 호스트를 기준으로 하며, 컨테이너 프로세스 관리자만 있는 환경에는 적용되지 않습니다.
| 항목 | 데스크톱 GUI 클라이언트 | mihomo 서비스 |
|---|---|---|
| 설정 위치 | 클라이언트의 설정 또는 구독 화면 | /etc/mihomo/config.yaml (이 문서에서 지정) |
| 실행 방법 | 데스크톱 앱 메뉴 또는 로그인 시 자동 실행 | systemctl enable --now mihomo |
| 로그 확인 위치 | 클라이언트 로그 화면 | journalctl -u mihomo |
| 기본 트래픽 경로 | 시스템 프록시 또는 앱별 프록시 | 앱에서 127.0.0.1:7890에 직접 연결 |
| 권한 경계 | 일반 사용자 GUI와 권한이 분리된 서비스 | 기본 프록시는 전용 비-root 사용자로 실행 |
데스크톱 방식: GUI 클라이언트 설치 및 설정 가져오기
1. 배포판, 아키텍처, 설치 패키지 형식 확인
클라이언트 다운로드 페이지에서 Linux를 지원하는 Clash Verge Rev 또는 FlClash 등의 클라이언트를 선택할 수 있습니다. 설치 패키지를 고를 때는 PC 모델명만 보지 말고 먼저 시스템 정보를 확인하세요. 일반적으로 x86_64는 배포 페이지의 x64 또는 amd64, aarch64는 arm64에 해당합니다. CPU 아키텍처뿐 아니라 클라이언트가 요구하는 배포판 버전과 런타임 라이브러리도 확인해야 합니다.
cat /etc/os-release
uname -m
Debian과 Ubuntu는 보통 DEB 패키지를, Fedora 등은 보통 RPM 패키지를 사용합니다. 아래에서는 이미 다운로드한 파일의 이름을 로컬에서 client.deb 또는 client.rpm으로 바꿉니다. 설치 명령을 간단히 하기 위한 이름이며, 실제 배포 파일명은 아닙니다. 파일이 있는 디렉터리로 이동한 뒤 배포판에 맞는 명령 하나만 실행하세요.
# Debian / Ubuntu
sudo apt install ./client.deb
# Fedora
sudo dnf install ./client.rpm
데스크톱 앱 메뉴에서 클라이언트를 실행하고, GUI 전체를 sudo로 실행하지 마세요. 서비스 모드나 TUN 권한이 필요하면 클라이언트에 포함된 서비스 설치 또는 권한 부여 기능을 사용하세요. 그래야 사용자 설정 파일이 root 소유로 저장되어 다음에 일반 사용자로 실행할 때 구독 정보를 저장하지 못하는 문제를 예방할 수 있습니다.
2. 구독 가져오기 및 실제 적용 설정 확인
- 클라이언트의 설정 또는 구독 화면에서 유효한 Clash 호환 구독 링크를 가져오거나 로컬 YAML 파일을 불러옵니다. 메뉴 이름은 클라이언트 버전에 따라 다를 수 있습니다.
- 가져온 설정을 선택해 현재 설정으로 지정하세요. 다운로드가 완료된 것만으로 설정이 활성화된 것은 아닙니다.
- 정책 그룹에서 사용할 수 있는 노드를 선택한 다음 로그에서 설정 파싱 오류가 있는지 확인합니다. 정책 그룹 이름은 규칙에서 참조하는 이름과 일치해야 합니다.
- 현재 설정이나 실행 정보에서 HTTP, SOCKS 또는 mixed 수신 포트를 확인하세요. 아래에서는
7890을 예로 들지만, 기존 클라이언트의 포트를 반드시 이 값으로 변경할 필요는 없습니다. - 먼저 명시적 프록시로 테스트한 뒤 시스템 프록시를 활성화하세요. 프록시 설정을 따르지 않는 앱까지 연결해야 할 때만 TUN을 추가로 테스트하면 됩니다.
GUI 클라이언트는 구독, 오버라이드 설정, 인터페이스 옵션을 병합해 최종 실행 설정을 생성할 수 있습니다. 이렇게 임시로 생성된 파일을 직접 수정하지 마세요. 구독을 업데이트하거나 설정을 바꾸면 수정 내용이 사라질 수 있습니다. 포트, 규칙, DNS 변경을 계속 유지하려면 클라이언트의 오버라이드 기능을 사용하세요. 클라이언트가 ~/.config/mihomo/config.yaml을 읽는다고 단정해서도 안 됩니다.
3. 데스크톱 시스템 프록시와 터미널 프록시 구분
클라이언트의 '시스템 프록시'는 보통 데스크톱 환경의 프록시 설정을 변경합니다. 브라우저는 이 설정을 따를 수 있지만, 새 터미널에서 실행한 curl이나 패키지 관리자, 백그라운드 서비스는 따르지 않을 수 있습니다. 반대로 터미널에서 export를 실행해도 이미 열린 브라우저 설정은 바뀌지 않습니다. 테스트할 때는 '프록시 사용 중'이라고만 기록하지 말고 대상 앱, 사용한 프록시 경로, 포트를 함께 적어 두세요.
헤드리스 방식: 코어와 전용 디렉터리 준비
아래 설정은 고정 경로를 사용하므로 현재 SSH 사용자의 홈 디렉터리와 서비스 작업 디렉터리를 혼동하지 않습니다. 코어를 설치하기 전에 uname -m 결과를 확인하고, mihomo 공식 배포 채널에서 시스템 아키텍처와 CPU 명령어 집합에 맞는 Linux 빌드를 선택하세요. 다운로드한 압축 파일을 풀고 실행 파일 이름을 로컬에서 mihomo로 지정합니다. 아래 명령은 해당 파일이 있는 디렉터리에서 실행합니다.
sudo install -m 0755 ./mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v
-v는 실제 설치된 버전을 확인하는 옵션입니다. Exec format error가 표시되면 압축 파일을 그대로 실행하고 있지는 않은지, 아키텍처를 잘못 선택하지 않았는지 먼저 확인하세요. Illegal instruction이 표시되면 빌드에 필요한 명령어 집합을 확인하세요. 파일 권한을 계속 바꾸기보다 호스트에 맞는 빌드를 다시 받는 편이 정확합니다.
전용 서비스 계정 만들기
아래 계정은 프록시 서비스만 실행하며 대화형 로그인에는 사용하지 않습니다. 계정이 이미 있으면 생성 단계는 건너뛰세요. 배포판에서 nologin의 경로가 다르면 command -v nologin으로 확인한 뒤 명령을 조정합니다. 설정 파일은 root가 관리하고 실행 데이터는 서비스 사용자가 기록합니다.
getent passwd mihomo || 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
/usr/local/bin/mihomo: 코어 실행 파일. 일반 서비스 사용자가 덮어쓸 수 없습니다./etc/mihomo/config.yaml: 기본 설정 파일. 노드 인증 정보나 구독 주소가 포함될 수 있으므로 읽기 권한을 제한해야 합니다./var/lib/mihomo:-d로 지정하는 데이터 디렉터리. 실행 상태, 캐시, 설정에 필요한 리소스를 보관합니다.
이 문서에서는 -f로 기본 설정 파일을 명시하므로 기본 경로에 의존하지 않습니다. 실제 설정에 proxy-providers, rule-providers 또는 외부 데이터 파일이 포함되어 있다면 파일 경로와 읽기 권한, 다운로드 조건도 확인해야 합니다. 기본 YAML 파일만 복사한 뒤 필요한 파일이 모두 준비되었다고 가정하지 마세요.
최소 설정으로 수신 포트부터 확인
설치 문제와 구독 문제를 분리하기 위해 먼저 아래의 직접 연결용 설정으로 검증합니다. 현재 디렉터리에 config.yaml을 만들고 다음 내용을 입력하세요. 이 설정은 코어가 실행되고 프록시 요청을 받아 외부로 직접 연결되는지만 확인하며, 프록시 노드는 포함하지 않고 외부 접속 지역도 바꾸지 않습니다.
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
tun:
enable: false
rules:
- MATCH,DIRECT
mixed-port는 하나의 포트에서 HTTP와 SOCKS 프록시 요청을 모두 받습니다. allow-lan: false는 로컬 기기만 접근하도록 제한하며, 예시에는 루프백 주소도 명시되어 있습니다. 지금은 컨트롤러 인터페이스를 활성화할 필요가 없으며 클라우드 서버 보안 그룹에서 7890 포트를 열 필요도 없습니다.
sudo install -o root -g mihomo -m 0640 \
./config.yaml /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo \
-t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
-t는 현재 코어가 설정을 읽을 수 있는지 확인하는 옵션이며, 노드 연결을 테스트하지는 않습니다. YAML 오류가 나오면 들여쓰기, 콜론 뒤 공백, 필드 형식을 먼저 확인하세요. 권한 오류가 나오면 설정 파일과 상위 디렉터리의 각 단계에 서비스 계정의 접근 권한이 있는지 확인해야 합니다.
systemd 상시 실행 설정
/etc/systemd/system/mihomo.service를 만들고 아래 내용을 빠짐없이 입력하세요. 이 서비스는 앞에서 설정한 로컬 명시적 프록시용이며, TUN 장치를 만들거나 시스템 라우팅을 변경할 권한은 부여하지 않습니다.
[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
StateDirectory=mihomo
StateDirectoryMode=0750
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=5s
UMask=0027
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
[Install]
WantedBy=multi-user.target
StateDirectory를 사용하면 systemd가 쓰기 가능한 상태 디렉터리를 관리합니다. ProtectSystem=strict는 시스템 파일에 대한 서비스의 쓰기를 제한하지만 상태 디렉터리는 계속 쓸 수 있습니다. ProtectHome=true는 서비스가 사용자 홈 디렉터리를 읽지 못하게 하므로 provider 파일을 다운로드 디렉터리에 둔 채 참조하지 마세요. 필요한 파일을 서비스가 접근할 수 있는 디렉터리에 넣고 설정에 지정된 경로에 맞춰 정리하세요.
sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service
systemctl status mihomo.service --no-pager
sudo journalctl -u mihomo.service -b -n 80 --no-pager
sudo ss -lntup 'sport = :7890'
enable --now는 부팅 시 자동 실행을 설정하고 서비스를 즉시 시작합니다. network-online.target의 대기 동작은 배포판에서 활성화한 네트워크 대기 서비스에 따라 다르며, 외부 구독 사이트에 접속할 수 있음을 보장하지는 않습니다. 시작할 때 원격 리소스를 다운로드해야 한다면 로그에서 요청이 성공했는지 확인하세요.
설정 업데이트 및 바이너리 업그레이드
YAML을 수정한 뒤 먼저 서비스 사용자로 앞에서 설명한 -t 검사를 실행하세요. 통과한 경우에만 서비스를 재시작합니다. 이 문서에서는 ExecReload를 정의하지 않으므로 systemctl reload mihomo를 사용할 수 있는 명령으로 안내하지 않습니다. 재시작하면 기존 프록시 연결이 끊기므로 적절한 점검 시간을 선택하세요.
sudo -u mihomo /usr/local/bin/mihomo \
-t -d /var/lib/mihomo -f /etc/mihomo/config.yaml \
&& sudo systemctl restart mihomo.service
코어를 업그레이드하기 전에 기존 실행 파일과 설정을 보관하세요. 서비스를 중지한 뒤 install로 새 실행 파일을 설치하고, 버전을 확인한 다음 설정을 다시 검사하고 서비스를 시작합니다. 실행 중인 파일을 바로 덮어쓰지 말고, 새 버전이 기존 설정의 모든 폐기 예정 필드를 지원한다고 가정하지 마세요.
터미널 프록시 변수 설정 및 요청 확인
먼저 명시적 프록시 요청 테스트
mihomo가 실행 중인 호스트에서 아래 테스트를 실행하세요. --noproxy ""를 지정하면 기존 NO_PROXY 설정 때문에 이번 요청이 프록시를 우회하는 상황을 방지할 수 있습니다. HTTP 응답을 받았다면 요청 경로가 진행된 것입니다. 웹사이트가 반환한 구체적인 상태 코드는 별도로 판단해야 합니다.
curl --noproxy "" --proxy http://127.0.0.1:7890 \
--connect-timeout 10 --max-time 30 -I https://example.com/
최소 직접 연결 설정으로 테스트할 때 성공했다는 것은 로컬 프록시 경로를 사용할 수 있다는 뜻일 뿐입니다. 실제 노드 설정으로 바꾼 뒤에는 연결 로그의 대상, 적용 규칙, 정책 그룹을 확인해 노드를 통과하는지 판단하세요. 웹페이지가 열린다는 이유만으로 외부 접속 경로가 바뀌었다고 단정할 수 없습니다.
현재 터미널과 하위 프로세스에 프록시 설정
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=localhost,127.0.0.1,::1
curl --connect-timeout 10 --max-time 30 -I https://example.com/
https_proxy 값에 http://를 사용하는 것은 모순이 아닙니다. 로컬 HTTP 프록시에 연결하는 방식을 지정하며, HTTPS 대상은 보통 CONNECT로 터널을 만듭니다. 이 형식을 지원하는 프로그램에서 socks5h://는 대상 도메인 이름을 SOCKS 프록시에서 조회한다는 의미입니다. 도구마다 지원하는 환경 변수와 우선순위는 다를 수 있습니다.
- 이
export설정은 현재 셸과 이후에 실행되는 하위 프로세스에만 적용되며, 다른 로그인 세션은 변경하지 않습니다. - 계속 적용하려면 사용하는 셸의 시작 파일에 추가할 수 있습니다. 예를 들어 Bash 대화형 터미널에서는 보통
~/.bashrc를 사용하지만, 모든 프로그램이 이 파일을 읽는 것은 아닙니다. sudo는 보통 환경 변수를 제거합니다. 일반 사용자로 실행한 curl이 성공했다고 해서sudo apt도 같은 프록시를 사용한다고 볼 수는 없습니다.- systemd 시스템 서비스는 사용자의
~/.bashrc를 읽지 않습니다. 프록시가 필요한 다른 서비스에는 환경을 각각 설정하고, mihomo 자체에는 자기 포트를 가리키는 프록시 변수를 지정하지 마세요.
기기에 대문자 환경 변수가 설정되어 있다면 값이 일관되는지도 확인하세요. curl은 보안상의 이유로 대문자 HTTP_PROXY를 허용하지 않으므로 이 문서에서는 소문자 형식을 사용합니다. 프록시를 중지하기 전에 현재 터미널의 일반적인 변수를 지워 두면 남은 설정 때문에 이후 명령의 연결이 실패하는 일을 방지할 수 있습니다.
unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
TUN, 원격 접속 및 문제 해결
TUN은 별도의 권한과 라우팅 변경이 필요합니다
TUN은 가상 네트워크 인터페이스를 통해 라우팅 조건에 맞는 IP 트래픽을 처리하는 기능이지, 모든 프로그램의 모든 트래픽이 반드시 프록시를 거친다는 보장은 아닙니다. 라우팅 제외 규칙, DNS, IPv6, 기존 VPN이 결과에 영향을 줍니다. Linux에서는 보통 /dev/net/tun에 접근할 수 있어야 하고 네트워크를 관리할 권한도 필요합니다. tun.enable을 true로 바꾸는 것만으로 이러한 요구 사항을 해결할 수는 없습니다.
이 문서의 비-root systemd 서비스에는 해당 권한이 부여되어 있지 않습니다. TUN이 필요하다면 사용하는 클라이언트 또는 mihomo의 최신 문서를 참고해 서비스 권한, DNS 처리, 라우팅 설정을 다시 검토하세요. 권한을 높이는 명령 하나만 추가해서는 해결되지 않습니다. SSH 서버에서 작업하기 전에 별도의 SSH 세션과 클라우드 콘솔 접속 경로를 확보하고, 관리 네트워크 대역을 제외할 방법을 확인해 라우팅을 적용한 뒤 접속이 끊기지 않도록 하세요.
원격 사용에는 SSH 포트 포워딩 권장
개인 PC에서 서버의 로컬 프록시를 임시로 사용하려면 프록시 포트를 인터넷에 직접 공개하지 말고 개인 PC에서 SSH 로컬 포트 포워딩을 설정하세요. 아래 예시는 SSH 설정에 mihomo-host라는 호스트 별칭이 이미 등록되어 있다고 가정합니다.
ssh -N -o ExitOnForwardFailure=yes \
-L 127.0.0.1:17890:127.0.0.1:7890 mihomo-host
SSH 연결을 유지한 채 개인 PC의 앱에서 프록시 주소를 127.0.0.1:17890으로 설정하세요. 원격 호스트의 127.0.0.1:7890은 개인 PC가 아니라 서버 자신을 가리킵니다. LAN에 프록시를 제공해야 한다면 인증, 방화벽, 접근 범위를 별도로 설정해야 하며 allow-lan만 켜서는 안 됩니다.
오류 증상에 따라 원인 범위 좁히기
| 증상 | 먼저 확인할 항목 |
|---|---|
address already in use | ss로 포트 사용 여부를 확인하세요. 데스크톱 클라이언트와 systemd 서비스가 동시에 7890 포트를 수신할 수 있으므로 프록시 경로를 하나만 남기거나 포트를 각각 다르게 설정하세요. |
Permission denied | 서비스 사용자가 기본 설정과 provider 파일을 읽을 수 있는지, 데이터 디렉터리에 쓸 수 있는지 확인하세요. 원인을 찾는 대신 전체 디렉터리의 접근 권한을 열어 두지 마세요. |
Connection refused | 서비스가 실행 중인지, 실제 수신 주소가 무엇인지, 앱에서 사용하는 포트와 일치하는지 확인하세요. 컨테이너 안의 127.0.0.1은 호스트를 가리키지 않습니다. |
| 포트 연결은 되지만 요청 시간 초과 | 노드 연결 여부, DNS 조회 성공 여부, 현재 선택된 정책 그룹과 적용 규칙을 확인해 로컬 수신과 상위 연결 상태를 구분하세요. |
| 터미널에서는 되지만 다른 앱에서는 안 됨 | 앱이 환경 변수를 지원하는지, 자체 프록시가 활성화되어 있는지, 변수를 설정하기 전에 이미 실행된 앱인지 확인하세요. |
| 터미널에서는 실행되지만 서비스 시작 실패 | 실제 실행 사용자, 작업 디렉터리, 설정 파일의 절대 경로, 파일 권한을 비교하세요. ProtectHome으로 접근이 차단된 파일을 참조하고 있지는 않은지도 확인해야 합니다. |
문제 해결을 위해 다음 세 가지 정보를 보관하세요. mihomo -v의 버전 출력, 서비스 로그에서 처음 발생한 유효한 오류, 앱이 실제로 사용하는 프록시 주소입니다. 로그를 공유하기 전에는 구독 인증 정보, 노드 비밀번호, 컨트롤러 인터페이스 키를 삭제하세요. 설정 필드의 의미는 전체 문서에서 확인할 수 있습니다. 구독을 처음 가져오거나 설정을 전환하는 방법은 설정 가이드를 참고하세요.