튜토리얼 · 약 18분

QEMU/KVM 가상머신이 Linux 호스트의
Mihomo를 탈 때: NAT와 사용자 모드 네트워크

Linux 데스크톱이나 서버에서 virt-managerQEMU/KVM을 돌리며 이미 호스트에 Mihomo(Clash 호환 코어)를 올려 둔 경우, 게스트 안의 apt·컨테이너 레지스트리·브라우저만 따로 프록시를 또 깔고 싶지 않은 사용자가 많습니다. 문제는 망 구성이 libvirt 기본 NAT(virbr0)인지, 아니면 사용자 모드 네트워크(SLIRP 계열)인지에 따라 «프록시 주소에 넣을 IP»가 192.168.122.1 같은 게이트웨이인지, 10.0.2.2 같은 호스트 별칭인지로 갈린다는 점입니다. 본문은 게이트웨이 기반 NAT사용자 모드에서의 호스트 주소를 나누고, hostfwd는 역방향 포트 포워딩으로 따로 짚습니다.

QEMU · KVM · virt-manager · Mihomo · NAT · 사용자 모드

1 virt-manager 기본값이 의미하는 것

대부분의 입문 튜토리얼은 «가상머신이 인터넷에 나간다»까지만 설명하고, 그 사이를 거치는 NAT 장치가 호스트의 어떤 인터페이스와 연결되는지는 생략합니다. libvirtdefault 네트워크는 호스트에 virbr0 같은 브리지를 만들고, 그 뒤에서 게스트 사설 대역을 물리 NIC 쪽으로 마스커레이드합니다. 이 구조에서는 게스트가 보는 기본 게이트웨이가 곧 호스트 쪽 브리지 IP(흔히 192.168.122.1)인 경우가 많고, 같은 주소로 열린 TCP 포트에 HTTP 프록시를 붙이면 됩니다.

반면 QEMU 사용자 모드(-netdev user)는 커널 브리지 없이 QEMU 프로세스가 직접 SLIRP로 NAT를 흉내 냅니다. 게스트에서 호스트로 나가는 TCP는 문서화된 별칭 10.0.2.2로 잡는 것이 일반적이며, virbr0 게이트웨이 공식을 그대로 가져오면 실패합니다. hostfwd는 이와 다른 축으로, 호스트 쪽 포트를 게스트의 서비스 포트에 매핑하는 역방향 포트 포워딩에 쓰입니다. 즉 «NAT»라는 말만 같을 뿐, 주소·포워딩 방향이 KVM 안에서도 나뉩니다.

호스트에서 systemd로 코어를 띄우는 절차는 Linux Mihomo systemd 가이드와 맞물립니다. GUI 클라이언트를 쓰더라도 mixed·HTTP 포트 번호와 Allow LAN 여부는 동일하게 확인하면 됩니다.

2 호스트에서 Mihomo(Clash 호환) 수신 준비

게스트가 호스트의 숫자 주소로 프록시에 붙으려면, Mihomo가 127.0.0.1에만 바인딩되어 있으면 실패합니다. Allow LAN을 켜거나 설정에서 0.0.0.0 또는 virbr0의 호스트 측 주소에 mixed·HTTP 포트를 열어야 합니다. 포트 번호는 문서에 적어 두고 게스트의 http_proxy와 동일하게 맞춥니다.

nftables·firewalld·ufw 중 무엇을 쓰든, 게스트 대역에서 호스트로 들어오는 TCP 인바운드가 막혀 있으면 증상은 전부 타임아웃으로만 보입니다. 호스트에서 ss -lntp로 실제 리슨 주소를 확인한 뒤, 동일 인터페이스로 curl -x http://IP:포트를 먼저 검증하세요. Windows 가상화 글에서 다룬 VMware NAT·브리지 구분과 사고방식은 같고, 차이점은 «브리지가 Linux 브리지·virbr0냐, SLIRP냐»입니다.

보안 Allow LAN으로 0.0.0.0에 포트를 열면 같은 L2 세그먼트의 다른 기기에서도 보일 수 있습니다. 공용 Wi-Fi에서는 끄거나 방화벽으로 출처를 제한하세요.

3 방법 1: libvirt NAT(virt-manager 기본)에서 게이트웨이로 붙기

virt-manager에서 네트워크 소스를 «기본 NAT»로 두었다면, 게스트 Linux에서 ip route show default로 나온 next hop이 곧 호스트 쪽 게이트웨이입니다. 이 IP(예: 192.168.122.1)에 호스트 Mihomo의 HTTP·mixed 포트를 붙여 http://192.168.122.1:7890 형태로 쓰는 패턴이 가장 단순합니다. Debian·Ubuntu 계열에서는 /etc/apt/apt.conf.d/95proxyAcquire::http::Proxy를 명시하면 sudo apt까지 일관되게 따라옵니다.

브라우저는 데스크톱 환경의 시스템 프록시를 따르거나, 확장 프로그램·프로파일별로 수동 프록시를 넣습니다. 중요한 오해 하나: 게스트에서 127.0.0.1를 프록시 주소로 넣으면 «게스트 자기 자신»을 가리키므로 호스트 Mihomo와는 연결되지 않습니다. 반드시 라우팅 테이블의 게이트웨이나, 브리지드 모드에서 따로 잡은 호스트 LAN 주소를 사용해야 합니다.

호스트가 TUN 모드로 전역 트래픽을 가로채더라도, 게스트에서 나가는 SYN는 먼저 virbr0 게이트웨이를 향합니다. 따라서 «호스트 OS 입장에서 이미 프록시를 탄다»와 «게스트가 호스트의 프록시 포트에 명시적으로 붙는다»는 층이 겹칠 수 있으며, 디버깅 시에는 한쪽만 켜고 로그를 보는 편이 빠릅니다.

확인 명령 호스트에서 ip -4 addr show virbr0, 게스트에서 ip -br a와 기본 라우트를 나란히 열어 두고 숫자 대역이 맞는지 먼저 검증하세요.

4 방법 2: QEMU 사용자 모드(SLIRP)와 호스트 쪽 주소

스크립트나 커스텀 XML로 type='user' 네트워크를 쓰는 경우, 게스트는 libvirt virbr0와는 다른 사설 대역에 올라갑니다. QEMU 문서에서 정의하는 대표 값으로, 게스트가 호스트로 TCP를 열 때 쓰는 고정 별칭10.0.2.2입니다. 따라서 Mihomo가 호스트에서 7890을 받고 있으면 게스트 셸에서는 아래처럼 두는 것이 가장 흔한 «사용자 모드 네트워크 + 호스트 프록시» 패턴입니다.

bash
export http_proxy="http://10.0.2.2:7890"
export https_proxy="http://10.0.2.2:7890"

127.0.0.1은 게스트 자신이므로 여기서도 동일하게 피해야 합니다. 호스트 바인딩이 127.0.0.1만일 때도 QEMU가 10.0.2.2 경로로 넘겨 주는 경우가 많지만, 배포판·빌드에 따라 막힐 수 있으므로 재현성을 우선한다면 호스트 Mihomo는 0.0.0.0 또는 명시 LAN과 함께 Allow LAN 구성을 권장합니다.

한편 hostfwd(예: hostfwd=tcp::2222-:22)는 «호스트의 TCP 포트를 게스트의 특정 포트로 넘긴다»는 역방향 포트 포워딩에 가깝습니다. SSH로 게스트에 들어가거나 CI에서 호스트가 게스트 서비스를 찔러 볼 때 자주 쓰이며, «게스트 앱이 호스트 프록시를 쓴다»는 목적의 1차 솔루션은 10.0.2.2 쪽이 맞습니다. libvirt에서 동일한 효과를 내려면 네트워크 XML의 NAT 포트 요소나 qemu:commandline 네임스페이스 등 배포판별 스키마를 따릅니다.

선택 기준 virbr0 NAT라면 게이트웨이 IP(예: 192.168.122.1)가 자연스럽고, 사용자 모드라면 10.0.2.2를 기본값으로 외우면 됩니다. hostfwd는 게스트 서비스를 호스트 포트에 노출할 때 씁니다.

5 브리지드(공유 물리 장치)일 때

게스트를 물리 LAN과 같은 브리지에 올리면 기본 게이트웨이는 대개 집·랩의 공유기이고, 호스트 PC는 그 망의 또 한 대 장치입니다. 이 경우 프록시 서버 주소로는 virbr0가 아니라 호스트의 LAN IPv4를 써야 합니다. QEMU 문서를 읽을 때 «NAT»라는 단어가 등장하면 항상 «어떤 인터페이스 뒤의 NAT인가»를 먼저 짚으면 VMware·Hyper-V 글에서 배운 직관을 그대로 가져올 수 있습니다.

6 apt, 컨테이너 레지스트리, 브라우저

apt는 환경 변수만으로는 root 세션에서 빠지는 경우가 있어, 앞 절의 Acquire::http::Proxy 파일 방식이 재현성이 높습니다. Podman·Docker는 데몬이 http_proxy를 물려받지 않는 경우가 많으므로, daemon.jsonproxies 블록이나 빌드 전용 --build-arg를 따로 두세요. 레지스트리 미러가 HTTPS라면 CONNECT 경로가 막히지 않는지 Mihomo 로그에서 상태 코드를 확인합니다.

게스트 전체를 투명 프록시로 묶고 싶다면 호스트에서 TUN·iptables·nft로 라우팅을 다시 설계해야 하며, 본 글의 범위를 넘어섭니다. 개발·테스트 VM이라면 애플리케이션 계층 프록시를 명시하는 편이 롤백도 쉽습니다.

7 DNS와 Fake-IP

HTTP 프록시만 맞춰 두고 이름 해석이 게스트 로컬 DNS로만 나가면, 호스트 Mihomo의 fake-ip·도메인 규칙과 어긋나 «절반만 되는» 증상이 납니다. 게스트의 resolvectl status 또는 /etc/resolv.conf를 확인하고, 필요하면 호스트 DNS 모드와 맞추거나 게스트에서도 DoH를 쓰도록 정리합니다. 세부는 DNS·DoH·Fake-IP 누설 방지 글의 체크리스트를 참고하면 됩니다.

8 트러블슈팅 체크리스트

  1. 호스트 ss -lntp에 Mihomo 포트가 실제로 어떤 주소에 열려 있는가.
  2. 게스트에서 curl -v -x http://게이트웨이:포트 https://example.com로 먼저 단일 경로를 검증했는가.
  3. 사용자 모드 네트워크인데 10.0.2.2 대신 루프백만 바라보고 있지 않은가.
  4. 호스트 방화벽이 virbr0 인바운드를 차단하지 않는가.
  5. 스냅샷·백업을 만든 뒤에만 라우팅 표나 게스트 게이트웨이를 수동으로 바꿀 것.

9 정리

QEMU/KVM 게스트가 Linux 호스트의 Mihomo를 재사용하려면, virt-manager 기본 NAT에서는 virbr0게이트웨이 IP와 포트를 조합하는 방식이 1차이고, 사용자 모드 네트워크에서는 10.0.2.2로 호스트 쪽 프록시 포트에 붙는 패턴이 1차입니다. hostfwd는 게스트 서비스를 호스트 포트에 노출할 때 쓰는 축으로 분리해 두면 혼란이 줄어듭니다. 장기적으로는 규칙·로그·DNS를 한 화면에서 다루는 Clash 호환 GUI를 쓰면 호스트와 VM을 오가며 상태를 맞추기가 훨씬 수월합니다.

설치 패키지는 출처가 분명한 배포 페이지를 우선하는 것이 좋습니다. 동일한 Mihomo 코어를 데스크톱에서도 다루고 싶다면 아래 링크에서 클라이언트를 받아 mixed 포트와 LAN 수신을 맞춰 보세요.

→ Clash를 무료로 내려받아 QEMU/KVM과 호스트 프록시를 한 번에 맞춰 보세요

태그: QEMU KVM virt-manager Linux Mihomo NAT 사용자 모드 2026
QEMU KVM Linux 호스트에서 Clash Mihomo 프록시를 쓰는 사용자를 위한 로고

Clash Verge Rev

virt-manager·터미널을 오가며 Mihomo 규칙과 포트를 한 화면에서

Linux 호스트에서 LAN 수신·TUN·DNS를 정리해 두면 QEMU 게스트의 apt와 브라우저가 같은 출구로 모이기 쉽습니다. Windows·macOS·Linux 빌드를 한곳에서 받을 수 있습니다.

KVM Mihomo 규칙 분할 DNS 다중 프로파일

관련 읽을거리