설치 방식: 백그라운드 서비스와 데스크톱 클라이언트
mihomo는 Clash Meta에서 발전한 프록시 코어로, 설정을 읽고 프록시 연결을 구성하며 트래픽 분기 규칙을 적용합니다. 코어 자체에는 데스크톱 UI가 없으며, 프로세스를 실행한다고 모든 Linux 앱이 자동으로 프록시를 사용하는 것도 아닙니다. 앱에서 로컬 프록시 포트를 지정하거나, 설정된 TUN으로 트래픽을 처리해야 합니다.
서버, GUI가 없는 기기, 부팅 후 계속 실행해야 하는 시스템에는 바이너리와 systemd 조합이 적합합니다. 데스크톱에서 일상적으로 사용하거나 노드를 자주 바꾸고 구독을 업데이트한다면 Clash Verge Rev, FlClashs 같은 GUI 클라이언트를 선택할 수 있습니다. 두 방식을 각각 테스트할 수 있지만, 두 코어가 같은 포트를 동시에 점유하지 않도록 주의하세요.
| 항목 | 바이너리 + systemd | 데스크톱 클라이언트 |
|---|---|---|
| 적합한 환경 | 서버, 원격 터미널, 상시 백그라운드 실행 | GUI 환경의 Linux 데스크톱 |
| 설정 관리 | YAML 파일과 업데이트 절차를 직접 관리 | 설정 목록에서 가져오기, 업데이트 및 전환 |
| 실행 방식 | 사용자 로그인과 별개로 실행되는 시스템 서비스 | 앱 실행 또는 데스크톱 로그인 시 자동 시작 |
| 권한 범위 | 일반 프록시 포트는 전용 비권한 사용자로 실행 가능 | TUN은 보통 클라이언트 서비스나 권한 상승이 필요 |
바이너리 준비: 아키텍처, 권한, 작업 디렉터리
시스템 아키텍처와 초기화 시스템 확인
uname -m
ps -p 1 -o comm=
systemctl --version
x86_64는 보통 amd64 빌드에, aarch64는 arm64 빌드에 해당합니다. 32비트 ARM은 빌드 요구 사항도 확인해야 하며, 기기 브랜드만 보고 파일을 선택하면 안 됩니다. 두 번째 명령의 결과는 systemd여야 합니다. 컨테이너, WSL 또는 다른 초기화 시스템에서는 별도의 실행 방법이 필요할 수 있습니다.
신뢰할 수 있는 프로젝트 배포 채널에서 아키텍처에 맞는 mihomo 바이너리를 받으세요. 압축을 푼 뒤 파일 이름을 mihomo로 바꾸고 현재 디렉터리에 둡니다. 압축 파일은 그대로 실행할 수 없습니다. Exec format error가 발생하면 실행 권한을 반복해서 추가하기보다 아키텍처와 압축 해제 여부부터 확인하세요.
chmod +x ./mihomo
./mihomo -v
sudo install -m 0755 ./mihomo /usr/local/bin/mihomo
-v로 실제 코어 버전을 확인합니다. 설정 항목의 지원 여부를 확인할 때는 이 출력 결과를 기준으로 삼으세요. 데스크톱 클라이언트 버전으로 코어 버전을 대신할 수 없습니다.
프로그램, 설정, 실행 데이터를 분리하기
세 경로를 다음과 같이 사용합니다. 프로그램은 /usr/local/bin/mihomo, 설정은 /etc/mihomo/config.yaml, 실행 데이터는 /var/lib/mihomo에 둡니다. 코어가 규칙 세트나 데이터베이스를 내려받거나 캐시를 저장하려면 데이터 디렉터리에 쓰기 권한이 필요합니다. 설정 파일은 읽기 전용으로 유지해도 됩니다.
sudo useradd --system --home-dir /var/lib/mihomo --shell /usr/sbin/nologin mihomo
sudo install -d -m 0750 -o root -g mihomo /etc/mihomo
sudo install -d -m 0750 -o mihomo -g mihomo /var/lib/mihomo
전용 사용자가 이미 있다면 useradd를 건너뛰고 id mihomo로 확인하세요. 배포판에 따라 nologin 경로가 다를 수 있으므로 command -v nologin으로 확인할 수 있습니다. 디렉터리 권한을 맞추려고 설정 디렉터리 전체를 모든 사용자가 쓸 수 있도록 바꾸지 마세요.
설정 파일: 로컬 포트부터 확인한 뒤 구독 연결하기
최소 설정으로 실행 환경 확인
현재 디렉터리에 config.yaml을 만들고 다음 내용을 입력하세요. 이 설정에는 직결 규칙만 있어 프로그램, 포트, 권한이 정상인지 확인할 수 있습니다. 프록시 노드는 없으므로 서비스 제공업체의 전체 설정을 대신할 수 없습니다.
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
ipv6: false
rules:
- MATCH,DIRECT
mixed-port: 7890은 하나의 TCP 포트에서 HTTP 프록시와 SOCKS5 요청을 모두 받습니다. allow-lan: false와 루프백 주소를 함께 사용하면 로컬 전용으로 배포할 수 있습니다. external-controller를 설정하지 않았으므로 이 예시에서는 제어 인터페이스를 열지 않습니다.
sudo install -m 0640 -o root -g mihomo ./config.yaml /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo -t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
-t는 설정을 불러올 수 있는지 검사하고, -d는 실행 데이터 디렉터리를, -f는 설정 파일 경로를 지정합니다. 포그라운드에서 실행해 오류 출력을 확인한 뒤 다른 터미널에서 포트를 점검하세요:
ss -lntp 'sport = :7890'
curl -I --connect-timeout 10 --max-time 20 --proxy http://127.0.0.1:7890 https://example.com/
이 예시에서는 요청이 로컬 mihomo를 거친 뒤 목적지에 직접 연결됩니다. HTTP 응답이 왔다는 사실은 이 경로로 접속할 수 있음을 보여줄 뿐, 원격 프록시를 사용했다는 뜻은 아닙니다. 확인을 마치면 코어를 실행한 터미널에서 Ctrl+C를 눌러 포그라운드 프로세스를 종료하세요. 그래야 이후 systemd가 시작될 때 포트 충돌을 피할 수 있습니다.
사용 가능한 구독 설정으로 교체
- 서비스 제공업체가 Clash 또는 mihomo용으로 제공한 YAML 설정을 받으세요. 노드 공유 링크, 웹 구독 안내, 다른 클라이언트용 형식은 YAML 설정으로 바로 사용할 수 없습니다.
- 로컬에서 사용할 수 있는 사본을 보관한 다음 새 파일을
/etc/mihomo/config.yaml에 설치하세요. 권한은0640, 소유자는root:mihomo로 유지합니다. - 수신 포트,
proxy-groups,rules와 규칙에서 참조하는 정책 이름이 일치하는지 확인하세요. -t를 다시 실행해 검사를 통과한 뒤 서비스를 시작하세요. 원격 규칙 세트나 데이터베이스를 사용하는 경우 네트워크 접속과 데이터 디렉터리 쓰기 권한도 확인해야 합니다.
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
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=5
UMask=0027
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/mihomo
[Install]
WantedBy=multi-user.target
Restart=on-failure는 프로세스가 비정상 종료되면 재시작을 시도하지만 잘못된 설정을 고쳐 주지는 않습니다. ProtectSystem=strict는 파일 시스템 쓰기를 제한하고 데이터 디렉터리에만 쓰기를 허용합니다. 설정에서 다른 경로를 참조한다면 해당 사용자가 읽을 수 있는지, 다운로드 파일의 저장 위치가 쓰기 허용 경로인지 확인하세요.
sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
systemctl status mihomo --no-pager
sudo journalctl -u mihomo -b -n 80 --no-pager
enable --now는 부팅 시 자동 시작을 설정하고 서비스를 즉시 실행합니다. network-online.target은 시작 순서를 지정하는 조건입니다. 실제로 네트워크를 기다리는지는 시스템의 wait-online 서비스에 따라 달라지므로 인터넷 연결이 보장된다고 해석하면 안 됩니다. 구독, 규칙 세트, 노드 연결 상태는 별도로 확인해야 합니다.
설정 변경 후 작업 순서
sudo cp -p /etc/mihomo/config.yaml /etc/mihomo/config.yaml.bak
sudoedit /etc/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo -t -d /var/lib/mihomo -f /etc/mihomo/config.yaml
sudo systemctl restart mihomo
sudo journalctl -u mihomo -n 40 --no-pager
설정 검사를 통과한 경우에만 재시작하세요. service 파일을 수정했다면 먼저 daemon-reload를 실행해야 하지만 YAML만 수정했다면 필요하지 않습니다. 여기서는 재시작으로 설정을 적용합니다. ExecReload를 정의하지 않았으므로 systemctl reload mihomo가 적용될 것이라고 가정하지 마세요. 재시작하면 기존 프록시 연결이 끊기므로 다운로드와 원격 세션을 미리 조정하세요.
Linux 프록시 환경 변수: 터미널, Git, APT
코어가 포트를 수신하기 시작해도 터미널 프로그램에는 프록시 주소를 알려야 합니다. 아래 변수는 현재 셸과 그 셸에서 이후 실행하는 하위 프로세스에만 적용됩니다. 이미 실행 중인 브라우저나 다른 터미널, 시스템 서비스의 설정은 바뀌지 않습니다.
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 -I --connect-timeout 10 --max-time 20 https://example.com/
https_proxy 값은 http://로 지정해도 됩니다. 이는 HTTP 프록시의 CONNECT 터널을 통해 HTTPS 대상에 접속한다는 뜻이며, 대상 연결을 평문으로 바꾸는 것이 아닙니다. socks5h는 SOCKS 프록시 서버가 대상 도메인을 조회한다는 의미입니다. 로컬 코어가 이후 DNS를 처리하는 방식은 DNS 설정에 따라 달라집니다.
- 프로그램마다 지원하는 환경 변수가 다릅니다. curl은 보안상 대문자
HTTP_PROXY를 허용하지 않으므로 위의 소문자 형식을 사용하세요. - 대화형 터미널을 열 때마다 적용하려면 사용하는 셸에 따라
~/.bashrc또는~/.zshrc에 변수를 추가하세요. 서비스가 중지되면 이 변수도 함께 비활성화해야 합니다. sudo는 프록시 환경 변수를 정리하는 경우가 많습니다. systemd 서비스도 사용자의 셸 시작 파일을 자동으로 읽지 않으므로 환경을 별도로 설정해야 합니다.- 컨테이너에서
127.0.0.1은 호스트가 아니라 컨테이너 자신을 가리킵니다. 컨테이너 연결 문제를 해결하려고 LAN 전체에 프록시를 섣불리 개방하지 마세요.
특정 명령에 프록시를 직접 지정하기
git -c http.proxy=http://127.0.0.1:7890 ls-remote https://github.com/MetaCubeX/mihomo.git HEAD
sudo apt \
-o Acquire::http::Proxy="http://127.0.0.1:7890" \
-o Acquire::https::Proxy="http://127.0.0.1:7890" \
update
이 설정은 이번 명령에만 적용되므로 Git이나 APT 설정을 장기간 변경하지 않고 확인할 수 있습니다. 현재 셸의 프록시 변수를 해제하려면 다음을 실행하세요:
unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
앱이 프록시 환경 변수도 자체 프록시 설정도 읽지 않는다면 일반 mixed-port로 해당 앱의 트래픽을 자동 처리할 수 없습니다. 이럴 때 TUN을 고려해야 하며, 변수를 반복해서 내보내는 방식으로 해결할 수는 없습니다.
데스크톱 클라이언트 설정: 가져오기, 시스템 프록시, TUN
GUI 데스크톱을 사용한다면 다운로드 센터에서 Linux 클라이언트를 선택하세요. Debian과 Ubuntu에는 보통 DEB 패키지를, Fedora 등 RPM 계열 배포판에는 RPM 패키지를 사용합니다. 프로세서 아키텍처도 함께 확인하세요. 아래 명령에서 사용하는 파일은 다운로드한 뒤 이름을 바꾼 로컬 설치 패키지입니다:
# Debian / Ubuntu
sudo apt install ./client.deb
# Fedora
sudo dnf install ./client.rpm
클라이언트 UI와 메뉴 이름은 버전에 따라 달라집니다. 사용할 때는 ‘설정 가져오기, 프록시 선택, 네트워크 트래픽 처리’ 기능을 찾아보세요. 앱 버전과 코어 버전을 혼동하지 않도록 주의하세요.
- 설정 가져오기: 설정 또는 구독 화면에서 구독 URL을 추가하거나 로컬 YAML 파일을 가져옵니다. 다운로드가 완료되고 해당 설정이 선택되어 있는지 확인하세요. 목록에 항목이 보이는 것만으로 활성화된 것은 아닙니다.
- 정책 선택: 프록시 그룹 화면에서 규칙이 참조하는 정책 그룹을 열고 사용할 노드를 선택하세요. 규칙 모드에서는 모든 요청이 이 노드를 거치는 것은 아닙니다. DIRECT에 해당하는 요청은 직접 연결됩니다.
- 포트 확인: 설정의 네트워크 또는 포트 항목에서 혼합 포트를 확인하세요. 데스크톱 클라이언트는
7897같은 다른 포트를 사용할 수 있으므로 이 문서의7890을 그대로 사용하면 안 됩니다. - 시스템 프록시 사용: 데스크톱 환경에서 제공하는 프록시 설정을 주로 변경하며, 적용 범위는 앱이 시스템 설정을 따르는지에 따라 달라집니다. 브라우저에서 확인한 뒤 터미널 프로그램도 별도로 테스트하세요.
- 필요한 경우 TUN 사용: 클라이언트가 제공하는 서비스 설치와 권한 부여 절차를 따르세요. 이후 가상 네트워크 인터페이스, 라우팅, DNS를 확인합니다. 클라이언트를 상시 root 권한으로 실행하는 것은 피하세요.
TUN은 속도를 높이는 버튼이 아닙니다. 가상 네트워크 장치로 조건에 맞는 트래픽을 처리하며 /dev/net/tun, 네트워크 관리 권한, 라우팅 설정이 필요합니다. 활성화 후 원격 SSH, LAN 접속, 컨테이너 네트워크에 문제가 생기면 먼저 TUN을 끄고 연결을 복구한 뒤 라우팅 제외 규칙과 DNS를 확인하세요. 비권한 service의 제한은 실제 TUN 배포 방식에 맞춰 다시 검토해야 합니다. tun.enable: true만 추가한다고 정상 작동하는 것은 아닙니다.
시작 실패와 프록시 미적용: 계층별 점검
| 증상 | 확인할 항목 | 해결 방법 |
|---|---|---|
| 실행 시 아키텍처 오류 발생 | uname -m、file /usr/local/bin/mihomo | 해당 아키텍처에 맞는 압축 해제된 바이너리로 교체 |
| 서비스가 반복해서 재시작됨 | journalctl -u mihomo 및 mihomo -t | YAML, 참조 이름 또는 파일 권한 수정 |
| 포트가 이미 사용 중임 | sudo ss -lntp 'sport = :7890' | 중복 실행 중인 코어를 종료하거나 포트와 앱 설정을 통일 |
| 규칙 세트 다운로드 실패 | 다운로드 로그, 대상 주소, 데이터 디렉터리 권한 | 네트워크 오류, 경로 쓰기 권한, 콘텐츠 형식 오류를 구분 |
| 브라우저는 되지만 터미널은 안 됨 | 환경 변수와 해당 프로그램의 프록시 설정 | 터미널에서 올바른 로컬 프록시 포트를 명시적으로 사용 |
| 요청이 여전히 직접 연결됨 | 현재 모드, 적용된 규칙, 정책 그룹 | MATCH, DIRECT 규칙에 해당하거나 그룹에서 DIRECT를 선택한 것은 아닌지 확인 |
프로세스, 수신 포트, 앱 연결, 규칙과 정책, 원격 노드 순서로 점검하세요. 먼저 curl --proxy를 명시해 앱 설정 문제를 배제한 다음 로그에서 적용된 규칙과 정책 결과를 확인합니다. 노드 응답 시간 초과와 로컬 연결 거부는 서로 다른 계층의 문제이므로 모두 ‘Linux 프록시가 작동하지 않음’으로 묶어서는 안 됩니다.
설치 후에는 코어 버전, 정상 작동하는 설정 사본, service 파일, 복구 명령을 보관하세요. 바이너리를 업그레이드하기 전에 서비스를 중지하고 기존 프로그램을 보존한 뒤 새 파일로 교체하고 설정을 테스트합니다. 규칙과 DNS에 관한 자세한 설명은 용어집을 확인하세요. 오류가 계속되면 문제 해결 절차에 따라 원인을 찾아보세요.