먼저 네트워크 구성부터 정하기: 메인 라우터는 인터넷 연결, 보조 라우터는 트래픽 분배
보조 라우터에서 mihomo를 직접 실행할 때 가장 먼저 해결할 문제는 구독 가져오기가 아니라 트래픽 경로입니다. 테스트 기기 한 대만 게이트웨이를 변경해 포워딩, DNS, 규칙이 모두 정상인지 확인한 다음 DHCP를 조정하세요. 이 글에서는 단일 NIC와 동일 서브넷으로 구성한 보조 라우터를 사용합니다. 메인 라우터는 계속 인터넷에 연결하고 DHCP와 인터넷 출구를 제공하며, OpenWrt는 메인 라우터의 LAN에 연결되어 mihomo가 지정된 기기의 트래픽을 처리합니다.
| 장치 | IPv4 주소 | 기본 게이트웨이 및 역할 |
|---|---|---|
| 메인 라우터 | 192.168.10.1/24 | 상위 네트워크에 연결하고 DHCP 제공 |
| OpenWrt 보조 라우터 | 192.168.10.2/24 | 기본 게이트웨이: 192.168.10.1 |
| 테스트 기기 | 192.168.10.100/24 | 게이트웨이와 DNS를 모두 192.168.10.2로 설정 |
여기 나온 주소는 설정 예시입니다. 실제 적용 전에는 자신의 서브넷에 맞게 바꾸세요. 보조 라우터 주소는 메인 라우터의 동적 주소 풀과 겹치지 않도록 하거나 DHCP에서 고정 임대를 설정해야 합니다. OpenWrt의 「네트워크」→「인터페이스」→「LAN」→「편집」에서 고정 IPv4 주소, 서브넷 마스크, IPv4 게이트웨이를 설정하세요. 보조 라우터의 게이트웨이에 자기 주소를 입력하면 안 됩니다.
- 같은 브로드캐스트 도메인에서는 DHCP 서버를 하나만 사용하세요. 보조 라우터 LAN의 「DHCP 서버」→「일반 설정」에서 「이 인터페이스 무시」를 선택하되 dnsmasq의 DNS 기능은 유지합니다.
- 메인 라우터의 기본 출구를 보조 라우터로 설정하지 마세요. “보조 라우터가 메인 라우터로 보내고, 메인 라우터가 다시 보조 라우터로 보내는” 포워딩 루프가 발생할 수 있습니다.
- 테스트 중에는 메인 라우터 관리 페이지에 직접 접속할 경로를 남겨 두세요. 서비스가 중단되더라도 테스트 기기의 설정을 바꿀 수 있습니다.
커널 설치: CPU 아키텍처, 작업 디렉터리, 실행 권한 확인
mihomo는 Clash Meta에서 이어지는 커널 이름입니다. 커널만 직접 설치해도 GUI 클라이언트가 포함되거나 OpenWrt 방화벽 설정이 자동으로 생성되지는 않습니다. 먼저 SSH로 시스템을 확인하고, 기기에 맞는 Linux 실행 파일을 다운로드했는지 점검하세요.
ubus call system board
uname -m
df -h /overlay /tmp
date
ip -4 route show
x86_64는 보통 amd64, aarch64는 보통 arm64에 해당합니다. MIPS 기기는 엔디언, 명령어 세트, 부동소수점 ABI도 확인해야 합니다. “64비트 라우터”라는 이유만으로 파일을 선택하면 안 됩니다. Exec format error가 나타나면 아키텍처를 확인하고, Illegal instruction이 발생하면 CPU 명령어 세트 요구사항을 점검하세요. YAML을 반복해서 수정할 문제는 아닙니다.
바이너리와 설정 파일 배치
압축을 푼 커널을 SCP 또는 SFTP로 라우터의 /tmp/mihomo에 업로드한 다음 아래 명령을 실행하세요. /tmp는 보통 메모리에 있으므로 재부팅하면 내용이 사라집니다. 계속 사용할 커널과 설정 파일은 영구 저장소에 보관하세요.
mkdir -p /etc/mihomo
cp /tmp/mihomo /usr/bin/mihomo
chmod 0755 /usr/bin/mihomo
chmod 0700 /etc/mihomo
/usr/bin/mihomo -v
실제 설정 파일을 /etc/mihomo/config.yaml에 저장하고 chmod 0600 /etc/mihomo/config.yaml을 설정하세요. 구독 주소, 노드 비밀번호, 컨트롤 인터페이스 키는 모두 민감한 정보입니다. 설정에서 규칙 집합이나 지리 데이터베이스를 사용하는 경우 관련 리소스를 다운로드할 수 있는지, 또는 작업 디렉터리에 이미 있는지 확인하세요. 플래시 용량이 작은 기기라면 남은 공간도 점검해야 합니다.
TUN을 사용하려면 커널 지원도 필요합니다. OpenWrt 24.10 계열에서 흔히 사용하는 opkg 환경을 예로 들면 아래 명령을 실행할 수 있습니다. 다른 버전에서는 먼저 펌웨어의 패키지 관리자와 소프트웨어 저장소를 확인하세요. 커널 모듈은 현재 펌웨어 커널과 일치해야 하며, 다른 버전의 패키지를 강제로 설치하면 안 됩니다.
opkg update
opkg install kmod-tun ip-full
test -c /dev/net/tun && echo "TUN device ready"
먼저 /usr/bin/mihomo -t -d /etc/mihomo를 실행해 설정을 검사하세요. 테스트를 통과해도 구문과 일부 리소스 초기화만 확인된 것이며, 투명 포워딩이 정상 작동한다는 뜻은 아닙니다.
TUN과 redir: 필요한 프로토콜에 맞춰 한 가지 방식 선택
TUN은 가상 네트워크 장치로 IP 트래픽을 받아 TCP와 UDP를 함께 처리해야 하는 환경에 적합합니다. redir는 방화벽을 통해 TCP 연결을 커널의 리스닝 포트로 리디렉션합니다. 경로를 단계별로 확인하기 쉽지만 redir-port만으로는 UDP를 처리할 수 없습니다. 먼저 둘 중 한 가지 방식만 선택하고, 여러 플러그인과 TUN, 수동 투명 프록시 규칙을 동시에 활성화하지 마세요.
| 항목 | TUN | redir |
|---|---|---|
| 처리 범위 | TCP와 UDP 처리 가능. 실제 지원 여부는 노드에 따라 다름 | 주로 TCP 처리. UDP는 TPROXY 등 별도 구성 필요 |
| 필수 조건 | /dev/net/tun, 라우팅 권한, 포워딩 허용 | TCP 리스닝 포트와 방화벽 리디렉션 규칙 |
| 주요 점검 항목 | 정책 라우팅, 출구 인터페이스 확인, TUN 방화벽 영역 | 규칙 적용 여부, 사설 주소 제외, 중복 트래픽 처리 |
| 이 글의 예시 포트 | 명시적 프록시 테스트에 사용하는 mixed-port: 7890 | redir-port: 7892 |
TUN 최소 구성 테스트 설정
아래는 직접 연결 포워딩을 확인하기 위한 기본 설정입니다. 프록시 노드가 없고 최종 규칙이 DIRECT이므로 테스트에 성공해도 노드 프록시가 정상이라는 뜻은 아닙니다. 먼저 이 설정으로 TUN과 DNS 경로를 점검한 다음 실제 proxies, proxy-providers, proxy-groups와 분기 규칙을 추가하세요. 백업하지 않은 설정을 이 파일로 덮어쓰지 마세요.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
tun:
enable: true
device: mihomo
stack: mixed
auto-route: true
auto-detect-interface: true
strict-route: false
dns-hijack:
- any:53
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
nameserver:
- 223.5.5.5
- 119.29.29.29
rules:
- IP-CIDR,192.168.10.0/24,DIRECT,no-resolve
- MATCH,DIRECT
allow-lan: false는 명시적 프록시 리스닝을 제한하는 설정이지, 포워딩 트래픽을 TUN이 처리하지 못하게 하는 설정은 아닙니다. auto-route는 트래픽을 받아오는 데 필요한 경로를 설정하지만 OpenWrt 방화벽 영역까지 모두 구성해 주지는 않습니다. auto-detect-interface를 사용하려면 기본 경로가 정상이어야 합니다. 다중 WAN, VPN 출구 또는 별도의 정책 라우팅을 함께 쓰는 경우 실제 출구에 맞게 interface-name을 지정하세요. 반드시 eth0일 것이라고 추측하면 안 됩니다.
redir 사용 시 주의할 점
redir를 선택했다면 tun.enable을 끄고 redir-port: 7892를 설정한 뒤, 방화벽의 prerouting 경로에서 지정한 LAN 기기의 TCP 트래픽만 리디렉션하세요. OpenWrt 22.03 이후에는 보통 firewall4와 nftables를 사용하므로, 오래된 안내의 iptables 명령이 현재 적용되는 규칙 집합에 반영된다고 가정하면 안 됩니다.
- 규칙의 입력 인터페이스와 테스트 출발지 주소
192.168.10.100를 제한하고, 라우터 관리 주소와 LAN, 필요한 예약 주소 대역은 제외하세요. - 커널이 노드 연결을 만들 때 해당 트래픽이 투명 프록시 진입점으로 다시 들어오지 않게 해야 합니다. 라우터 자체 트래픽까지 처리하려면 출구 우회와 루프 방지 규칙을 별도로 구성하세요.
- HTTP/3은 UDP/443을 사용합니다. TCP redir만 설정한 경우 브라우저의 HTTP/2와 HTTP/3 연결이 서로 다른 출구를 사용할 수 있습니다. 이는
7892포트가 작동하지 않는다는 뜻이 아닙니다. table inet fw4전체를 통째로 바꾸지 마세요. 규칙을 영구 설정한 뒤/etc/init.d/firewall reload도 테스트해 규칙이 다시 불러온 후에도 유지되는지 확인하세요.
DNS 설정: 기기는 보조 라우터에 질의하고, 로컬 서비스가 상위 DNS로 전달
초기 구성에서는 기기가 192.168.10.2:53에 질의하고, OpenWrt의 dnsmasq가 127.0.0.1:1053으로 전달한 다음 mihomo가 지정된 상위 DNS 서버에 질의하도록 설정하는 것이 좋습니다. 이렇게 하면 dnsmasq의 로컬 네트워크 이름 처리 기능을 유지하면서 두 서비스가 같은 53번 포트를 동시에 사용하는 문제를 피할 수 있습니다.
사용자 지정 도메인별 DNS 설정이 없는 단순한 환경에서는 아래 UCI 설정을 사용할 수 있습니다. 먼저 /etc/config/dhcp를 백업하세요. 이 명령은 첫 번째 dnsmasq의 기존 일반 상위 DNS 목록을 삭제합니다. 기업 도메인이나 다른 로컬 전달 규칙이 있다면 직접 병합해야 하므로 그대로 실행하지 마세요.
cp /etc/config/dhcp /root/dhcp.before-mihomo
uci set dhcp.@dnsmasq[0].noresolv='1'
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server='127.0.0.1#1053'
uci commit dhcp
/etc/init.d/dnsmasq restart
nslookup example.com 127.0.0.1
noresolv='1'은 dnsmasq가 자동 생성된 상위 DNS 목록을 함께 읽지 않도록 합니다. mihomo의 상위 DNS를 192.168.10.2로 설정하면 안 됩니다. dnsmasq와 mihomo가 서로 DNS 요청을 전달하는 루프가 생길 수 있습니다. 노드 서버가 도메인 이름을 사용한다면 프록시 연결 전에도 해당 도메인을 조회할 수 있는 경로가 있어야 합니다.
처음 구성할 때는 redir-host를 사용하면 DNS 조회 결과를 확인하기 쉽습니다. fake-ip로 전환하기 전 보조 라우터의 포워딩이 안정적인지 확인한 뒤, LAN 도메인과 기기 호환성에 맞춰 fake-ip-filter를 설정하세요. 브라우저의 보안 DNS, Android 비공개 DNS, 앱 내 DoH는 일반적인 53번 포트 질의를 우회할 수 있습니다. dns-hijack을 설정해도 이런 연결이 자동으로 복호화되지는 않습니다.
OpenWrt 포워딩과 같은 서브넷의 반환 경로: TUN 생성만으로는 충분하지 않습니다
「네트워크」→「방화벽」에서 실제 영역과 포워딩 관계를 확인하세요. 일반적으로 TUN 장치 mihomo용 별도 영역을 만들고 LAN 트래픽이 해당 영역으로 들어오도록 허용하며, TUN에서 나온 직접 연결 트래픽은 실제 출구 영역으로 나가도록 허용합니다. 단일 NIC 보조 라우터의 출구는 여전히 LAN인 경우가 많습니다. 듀얼 NIC 안내를 그대로 따라 출구가 반드시 WAN이라고 가정하지 마세요.
- 기기에서 보조 라우터의 UDP/TCP 53번 포트에 접근할 수 있도록 허용하세요. 신뢰할 수 없는 인터페이스에 DNS 서비스가 노출되지 않게 주의해야 합니다.
net.ipv4.ip_forward값이1인지 확인하세요. 커널에 경로가 있어도 포워딩이 꺼져 있으면 기기는 인터넷에 연결할 수 없습니다.- 문제 해결 중에는 소프트웨어 및 하드웨어 트래픽 오프로딩을 일시적으로 끄세요. 기존 연결이 빠른 경로를 사용하면 규칙 카운터와 패킷 캡처 결과를 확인하기 어렵습니다.
- 방화벽을 전부 끄는 방식으로 포워딩 문제를 “해결”하지 마세요. 필요한 영역과 방향만 허용하고 기존 규칙의 순서도 확인하세요.
같은 서브넷에서 놓치기 쉬운 문제가 하나 더 있습니다. 보조 라우터가 직접 연결 트래픽을 메인 라우터로 전달한 뒤 메인 라우터가 응답을 기기에 직접 보내면 경로가 비대칭이 됩니다. 양방향 모두 보조 라우터를 거쳐야 하는 구성이라면 지정한 포워딩 트래픽에만 범위를 제한해 SNAT를 적용하세요. 그러면 상위 라우터에는 출발지 주소가 192.168.10.2로 표시됩니다. 별다른 검토 없이 LAN 영역 전체의 모든 트래픽에 마스커레이드를 켜지 마세요. 프록시 대상 기기를 별도 서브넷에 두는 방법도 더 명확한 대안입니다.
같은 인터페이스로 들어오고 나가는 포워딩에서는 ICMP Redirect가 발생해 기기가 메인 라우터를 사용하도록 안내할 수도 있습니다. 이 구성에서는 특히 실제 LAN 장치의 값을 포함해 관련 설정을 확인하세요.
sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.send_redirects
sysctl net.ipv4.conf.default.send_redirects
sysctl net.ipv4.conf.br-lan.send_redirects
ip -4 route show
ip -4 rule show
ip -4 route show table all
장치 이름이 실제로 br-lan이라면 위 세 가지 send_redirects 값을 0으로 설정하고 동작을 확인한 뒤 영구 적용하세요. 인터페이스 이름에 점이 포함되거나 브리지 구성이 다르면 실제 장치에 맞춰 조정해야 합니다. 모든 sysctl 설정을 한꺼번에 변경하면 데이터 경로가 바뀐 원인을 찾기 어렵습니다.
부팅 시 자동 실행: systemd 대신 procd 사용
OpenWrt는 보통 procd로 서비스를 관리하므로 데스크톱 Linux의 systemctl enable mihomo 명령은 사용할 수 없습니다. 다른 프록시 관리 플러그인을 먼저 중지하고, 다른 프로세스가 포트를 사용하거나 같은 TUN 경로를 관리하고 있지 않은지 확인한 다음 /etc/init.d/mihomo를 만드세요.
#!/bin/sh /etc/rc.common
START=99
STOP=10
USE_PROCD=1
start_service() {
/usr/bin/mihomo -t -d /etc/mihomo || return 1
procd_open_instance
procd_set_param command /usr/bin/mihomo -d /etc/mihomo
procd_set_param respawn 3600 5 5
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param limits nofile="65535 65535"
procd_close_instance
}
이 스크립트는 설정을 먼저 확인한 뒤 procd를 통해 실행합니다. respawn 예시 인수는 짧은 시간에 계속 충돌하고 재시작하는 상황을 제한합니다. 서비스는 TUN 생성과 경로 수정에 필요한 권한을 위해 기본적으로 root로 실행됩니다. 권한이 낮은 사용자로 실행하려면 권한 부여를 별도로 설계해야 하며, 사용자 이름 한 줄만 추가해서는 안 됩니다.
chmod 0755 /etc/init.d/mihomo
/etc/init.d/mihomo start
logread -e mihomo
ip link show mihomo
# 실행 및 포워딩이 정상인지 확인한 후 자동 시작 활성화
/etc/init.d/mihomo enable
YAML을 수정한 뒤 먼저 mihomo -t -d /etc/mihomo를 실행하세요. 검사를 통과하면 /etc/init.d/mihomo restart를 실행합니다. 방화벽 규칙이 별도로 저장되고 DNS 서비스가 준비되며 부팅 후 리소스를 다운로드할 수 있어야 완전한 부팅 복구라고 할 수 있습니다. START=99만으로 인터넷 연결이 보장되지는 않습니다.
검수 및 롤백: 포트, DNS, 포워딩, 노드 순서로 확인
검수 중에는 테스트 기기 한 대만 게이트웨이를 변경해 두세요. 먼저 보조 라우터에서 명시적 프록시를 확인하고, 다음으로 기기의 투명 프록시 트래픽을 점검한 뒤, 마지막으로 메인 라우터 DHCP에서 게이트웨이와 DNS를 배포하세요. 이렇게 하면 “커널이 인터넷에 연결됨”과 “기기 트래픽이 실제로 전달됨”을 구분할 수 있습니다.
- 커널 실행 상태를 확인합니다.
logread -e mihomo를 확인해 포트 충돌, 규칙 다운로드 실패, TUN 생성 실패가 없는지 살펴보세요.ss가 설치되어 있다면ss -lntup을 실행해 7890, 1053 등 실제 리스닝 포트를 확인할 수 있습니다. - 명시적 프록시를 테스트합니다. 라우터에서 curl을 사용할 수 있다면
curl -I -x http://127.0.0.1:7890 https://example.com을 실행하세요. 이 단계에서는 기기의 투명 포워딩을 거치지 않습니다. 실패하면 먼저 커널, 상위 DNS, 출구를 확인하세요. - 기기의 DNS를 확인합니다. Linux 테스트 기기에서
nslookup example.com 192.168.10.2를 실행한 다음ip -4 route show default로 게이트웨이를 확인하세요. DNS 조회가 성공해도 TCP 트래픽이 TUN을 통과한다는 뜻은 아닙니다. - 투명 프록시 규칙이 적용되는지 확인합니다. 기기에서 앱 내 명시적 프록시를 끈 뒤 새 연결을 시작하고 mihomo 로그에서 출발지 주소, 규칙, 아웃바운드를 확인하세요. 노드 설정을 병합한 뒤에는 계속
DIRECT만 적용되는 것이 아니라 실제 프록시 그룹과 노드가 표시되어야 합니다. - 복구 동작을 테스트합니다. 서비스 재시작, 방화벽 다시 불러오기, 기기 재부팅을 순서대로 테스트하세요. DNS가 복구되는지, TUN이 다시 생성되는지, 기기가 계속 지정한 게이트웨이를 사용하는지 확인합니다.
자주 발생하는 증상과 우선 점검 항목
| 증상 | 우선 점검 항목 |
|---|---|
| 라우터에는 접속되지만 기기에서는 접속되지 않음 | 기기의 게이트웨이, IPv4 포워딩, 방화벽 영역, 같은 서브넷의 반환 경로 |
| IP 연결은 되지만 도메인 연결은 실패 | 53/1053 포트, dnsmasq 상위 DNS, DNS 루프 |
| 일부 앱이 프록시를 우회함 | IPv6 기본 경로, UDP, 앱 자체 프록시 또는 DNS |
| 작은 요청은 성공하지만 다운로드가 자주 멈춤 | 경로 MTU, 상위 네트워크 캡슐화, 재전송. TUN MTU를 무작정 높이지 마세요. |
| 재부팅 후 작동하지 않음 | procd 활성화 상태, 영구 설정 파일 위치, 방화벽 규칙 복구, 시작 로그 |
롤백하려면 먼저 테스트 기기의 게이트웨이와 DNS를 메인 라우터 192.168.10.1로 되돌린 다음 mihomo를 중지하고 사용자 지정 투명 프록시 규칙과 포워딩 설정을 제거하세요. dnsmasq가 1053으로만 전달하도록 설정했다면 상위 DNS도 함께 복구해야 합니다. 그렇지 않으면 커널을 중지한 뒤에도 보조 라우터가 DNS 질의를 받지만 응답할 서비스가 없어집니다.
/etc/init.d/mihomo stop
/etc/init.d/mihomo disable
# 백업이 이번 구성 적용 전의 설정일 때만 복원
cp /root/dhcp.before-mihomo /etc/config/dhcp
/etc/init.d/dnsmasq restart
마지막으로 전체 네트워크에 적용할지 결정하세요. 메인 라우터는 DHCP 옵션 3으로 게이트웨이를, 옵션 6으로 DNS를 배포합니다. 보조 라우터를 거쳐야 하는 기기에만 해당 주소를 제공해야 합니다. 한 번에 전체 규칙을 적용하는 것보다 네트워크 구성 기록, 설정 백업, 롤백 경로를 남겨 두는 편이 장기적인 관리에 유리합니다. 각 항목의 의미는 설정 참고에서, 클라이언트 설정 가져오기는 빠른 시작에서 확인하세요.