플랫폼 예상 읽는 시간 15분

OpenWrt 보조 라우터에 mihomo 설치하기: 투명 프록시 구성 가이드

OpenWrt 보조 라우터에서 기본 라우터와 게이트웨이 역할을 나누고, mihomo 실행 파일과 서비스를 설정하는 방법을 안내합니다. 투명 프록시와 DNS 리다이렉션, 연결 장애 시 복구 절차도 확인하세요.

1. 네트워크 구성: 단말 한 대부터 보조 라우터를 거치게 하기

OpenWrt 보조 라우터에 mihomo를 구성하려면 세 단계가 필요합니다. 단말이 트래픽을 보조 라우터로 보내고, 방화벽이 연결을 mihomo로 전달하며, mihomo가 규칙에 따라 출구를 선택해야 합니다. mihomo만 실행하거나 DNS만 바꿔서는 투명 프록시가 완성되지 않습니다.

이 가이드에서는 단일 LAN 포트와 동일 서브넷을 사용하는 IPv4 테스트 구성을 기준으로 합니다. OpenWrt 23.05 및 24.10 계열에서 흔히 쓰이는 firewall4와 nftables 환경을 가정합니다. 아래 주소는 설정 전체를 보여 주기 위한 예시이므로 적용 전에 실제 네트워크 대역과 하나씩 대조하세요. OpenClash, 다른 투명 프록시 플러그인 또는 사용자 지정 정책 라우팅이 이미 구성된 기기에는 이 규칙을 그대로 추가하지 마세요.

장치주소 또는 설정역할
기본 라우터192.168.10.1/24인터넷 연결, 외부 NAT, DHCP 계속 제공
OpenWrt 보조 라우터192.168.10.2/24mihomo 실행, 테스트 단말 트래픽 수신
보조 라우터 기본 게이트웨이192.168.10.1mihomo의 노드 연결 및 직접 연결용
테스트 단말192.168.10.100/24게이트웨이와 DNS를 모두 192.168.10.2로 설정
보조 라우터 LAN 인터페이스br-lan같은 LAN에 있는 테스트 트래픽 수신

게이트웨이와 DHCP 역할 분담

  1. OpenWrt의 “네트워크” → “인터페이스” → “LAN” → “편집”에서 고정 주소, IPv4 게이트웨이와 DNS를 설정합니다. 보조 라우터 자체에서 인터넷에 연결되는지도 확인하세요.
  2. 같은 화면의 “DHCP 서버” → “일반 설정”에서 “이 인터페이스 무시”를 선택해 기본 라우터와 보조 라우터가 동시에 IP 주소를 할당하지 않도록 합니다.
  3. 먼저 테스트 단말의 IPv4 게이트웨이와 DNS만 변경하세요. 기본 라우터 DHCP의 게이트웨이 옵션을 보조 라우터 주소로 바로 바꾸지 마세요.
  4. “네트워크” → “방화벽”에서 LAN 영역의 정책을 확인하세요. 이 가이드에서는 LAN 입력, 출력 및 영역 간 전달이 허용된 일반적인 구성을 가정합니다. 제한된 네트워크라면 필요한 허용 규칙을 별도로 설계해야 합니다.

같은 서브넷의 보조 라우터를 이용하면 직접 연결 응답이 기본 라우터에서 단말로 바로 돌아가 보조 라우터를 다시 거치지 않을 수 있습니다. 이런 비대칭 경로는 연결 통계와 상태 기반 방화벽 판정에 영향을 줄 수 있습니다. 처음 테스트할 때는 기본 라우터의 기존 외부 NAT를 유지하고, “경로 대칭성”을 이유로 LAN 전체에 주소 변환 규칙을 추가하지 마세요.

2. mihomo 설치: 바이너리와 최소 설정부터 확인

mihomo는 Clash Meta에서 이어져 개발되는 프록시 코어이며 OpenWrt 관리 플러그인은 아닙니다. mihomo를 직접 실행하면 설정 디렉터리, 프로세스 관리, 구독 업데이트, 방화벽 규칙을 관리자가 직접 관리해야 합니다. CPU 아키텍처에 맞는 Linux 바이너리를 선택하세요. 기기 제품명만 보고 판단하면 안 됩니다.

ubus call system board
uname -m
df -h /overlay
free -m

mkdir -p /etc/mihomo
chmod 700 /etc/mihomo
chmod 755 /usr/bin/mihomo
/usr/bin/mihomo -v

아래 명령은 압축을 푼 mihomo 바이너리를 /usr/bin/mihomo에 저장했다고 가정합니다. 예를 들어 aarch64는 보통 ARM64를 뜻하지만, ARMv7이나 MIPS 기기는 명령어 집합, 바이트 순서, 부동소수점 ABI도 확인해야 합니다. Exec format error가 발생하면 방화벽을 수정하기 전에 아키텍처부터 확인하세요. 버전은 해당 기기에서 mihomo -v를 실행한 결과를 기준으로 하고, 나중에 문제를 진단할 수 있도록 출력 내용을 보관하세요.

설정 파일: DIRECT로 트래픽 전달 경로 확인

아래 내용을 /etc/mihomo/config.yaml로 저장하세요. 프록시 노드를 설정하지 않은 테스트용 직접 연결 구성입니다. 따라서 트래픽이 프록시 서버로 전송되지는 않습니다. 먼저 트래픽이 mihomo에 전달되는지 확인한 뒤 노드와 정책 그룹을 추가하면 네트워크 문제와 구독 문제를 구분하기 쉽습니다.

mixed-port: 7890
tproxy-port: 7893
allow-lan: true
bind-address: 192.168.10.2
mode: rule
log-level: info
ipv6: false

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: redir-host
  nameserver:
    - udp://223.5.5.5:53
    - udp://119.29.29.29:53

rules:
  - MATCH,DIRECT

7890은 HTTP/SOCKS 혼합 프록시 포트, 7893은 TPROXY 포트, 1053은 mihomo DNS 수신 포트입니다. 처음부터 Fake-IP 주소 풀과 추가 라우팅까지 설정하지 않도록 redir-host를 사용합니다. 두 상위 DNS 서버는 예시용 일반 DNS 리졸버이며 암호화 DNS가 아닙니다.

chmod 600 /etc/mihomo/config.yaml
/usr/bin/mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml

트래픽을 가로채기 전에 설정 테스트를 통과해야 합니다. 이 기본 설정은 GEOIP, GEOSITE 또는 규칙 세트에 의존하지 않습니다. 구독 설정으로 교체한다면 관련 데이터 파일, 규칙 제공자 다운로드 주소, 정책 그룹 참조도 확인하세요. 데스크톱 클라이언트용으로 생성된 구독 설정에는 라우터에 적합하지 않은 DNS, TUN 또는 관리 인터페이스 설정이 포함될 수 있습니다.

3. 프로세스 관리: procd로 mihomo 실행

OpenWrt에서는 procd로 서비스를 관리합니다. SSH 세션에 프로세스를 계속 연결해 두거나, 예약 작업에서 매분 새로 실행하지 마세요. 아래 스크립트는 mihomo를 시작하고 비정상 종료 시 다시 실행하며 로그를 시스템에 연결합니다. 투명 프록시 규칙을 설치하는 기능은 포함하지 않습니다.

아래 내용을 /etc/init.d/mihomo로 저장하세요.

#!/bin/sh /etc/rc.common

START=95
STOP=10
USE_PROCD=1

start_service() {
    /usr/bin/mihomo -t -d /etc/mihomo \
        -f /etc/mihomo/config.yaml || return 1

    procd_open_instance
    procd_set_param command /usr/bin/mihomo \
        -d /etc/mihomo -f /etc/mihomo/config.yaml
    procd_set_param respawn 3600 5 5
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_set_param file /etc/mihomo/config.yaml
    procd_close_instance
}
chmod 755 /etc/init.d/mihomo
/etc/init.d/mihomo enable
/etc/init.d/mihomo start
logread -e mihomo
ss -lnptu | grep -E ':(7890|7893|1053)\b'

시스템에 ss가 없다면 netstat -lnptu로 수신 포트를 확인할 수 있습니다. 포트가 이미 사용 중이라는 로그가 나오면 기존 프록시 프로세스, 중복 서비스 또는 DNS 플러그인을 먼저 확인하세요. 방화벽 설정을 함께 바꾸지 않은 채 포트만 임의로 변경하지 마세요.

4. 투명 프록시: TPROXY, 정책 라우팅, 방화벽의 역할

Linux의 TPROXY는 원래 목적지 주소를 유지하면서 TCP와 UDP를 수신할 수 있습니다. 이를 사용하려면 세 가지가 함께 작동해야 합니다. nftables가 연결을 선택하고, 정책 라우팅이 표시된 패킷을 로컬 시스템으로 전달하며, mihomo의 투명 프록시 포트가 연결을 받아야 합니다. tproxy-port만 설정하고 앞의 두 항목을 구성하지 않으면 단말 트래픽은 mihomo로 자동 전달되지 않습니다.

아래 예시는 충돌이 없는 것으로 확인된 테스트 환경에서 192.168.10.100의 트래픽만 대상으로 합니다. 실행 전에 ip -4 rule show, ip -4 route show table 100, nft list ruleset을 실행해 라우팅 테이블 100, 우선순위 100 규칙, 마크 0x1을 다른 서비스가 사용하지 않는지 확인하세요. 멀티 WAN, VPN, 다른 프록시가 이 리소스를 이미 사용하는 경우가 많습니다.

커널 모듈과 패킷 전달 설정

사용 중인 펌웨어 패키지 저장소에서 nftables TPROXY 지원 모듈을 설치하세요. opkg를 사용하는 펌웨어라면 kmod-nft-tproxy 패키지를 확인할 수 있습니다. 패키지와 실행 중인 커널 버전이 일치해야 합니다. Operation not supported가 표시되거나 TPROXY 표현식을 찾지 못하면 먼저 모듈 문제를 해결하세요.

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.br-lan.send_redirects=0

ip -4 rule add priority 100 fwmark 0x1/0x1 lookup 100
ip -4 route add local 0.0.0.0/0 dev lo table 100

ICMP Redirect 전송을 끄면 보조 라우터가 같은 서브넷의 기본 라우터를 통해 경로를 바꾸라고 단말에 알리는 일을 방지할 수 있습니다. 인터페이스별 설정도 빠뜨리지 마세요. 엄격한 역방향 경로 필터링이 활성화되어 있다면 net.ipv4.conf.all.rp_filter와 net.ipv4.conf.br-lan.rp_filter도 확인해야 합니다. 정책 라우팅 환경에서는 엄격 모드가 정상 패킷을 버릴 수 있으므로 네트워크 보안 요구사항에 맞춰 느슨한 모드로 바꾸거나 비활성화하세요.

단일 출발지 IP만 대상으로 하는 nftables 규칙

아래 내용을 /etc/mihomo/test-tproxy.nft로 저장하세요. 별도로 관리하는 테스트 테이블이므로 firewall4의 테이블 내부 include 파일에 그대로 붙여 넣으면 안 됩니다. 처음 불러오기 전에 구문을 확인하고 적용하세요. 같은 이름의 테이블이 이미 있다면 다시 불러오지 마세요.

table inet mihomo_test {
    chain ingress_proxy {
        type filter hook prerouting priority mangle; policy accept;

        iifname != "br-lan" return
        ip saddr != 192.168.10.100 return

        meta l4proto { tcp, udp } th dport 53 return

        ip daddr {
            0.0.0.0/8,
            10.0.0.0/8,
            100.64.0.0/10,
            127.0.0.0/8,
            169.254.0.0/16,
            172.16.0.0/12,
            192.168.0.0/16,
            224.0.0.0/4,
            240.0.0.0/4
        } return

        meta l4proto { tcp, udp } counter \
            tproxy to :7893 meta mark set 0x1 accept
    }

    chain ingress_dns {
        type nat hook prerouting priority dstnat; policy accept;

        iifname "br-lan" ip saddr 192.168.10.100 \
            meta l4proto { tcp, udp } th dport 53 \
            counter redirect to :1053
    }
}
nft -c -f /etc/mihomo/test-tproxy.nft
nft -f /etc/mihomo/test-tproxy.nft
nft list table inet mihomo_test

DNS의 53번 포트 요청은 뒤이어 실행되는 NAT 체인에서 1053으로 리다이렉션되도록 투명 프록시 체인에서 먼저 반환합니다. 이렇게 하면 일반 DNS 요청이 TPROXY에 먼저 전달되지 않습니다. 사설 주소와 멀티캐스트 주소는 통과시켜 라우터 관리와 LAN 기기 접근 같은 기본 기능을 유지합니다. 조직 내부에 공인 IP 대역이나 별도 라우팅이 있다면 해당 대역도 제외해야 합니다.

nftables 테스트 체인의 accept는 firewall4의 다른 기본 체인까지 건너뛰게 하지 않습니다. TPROXY 패킷은 원래 목적지 포트를 유지하므로 “목적지 포트 7893”만 허용해 입력 정책을 대신할 수 없습니다. 이 가이드에서는 LAN 입력이 허용된 테스트 환경을 사용합니다. LAN 입력을 거부하는 환경에서는 firewall4에 LAN 출발지와 지정 마크가 있는 TCP/UDP 패킷만 허용하는 제한된 규칙을 추가하고, DNS용 1053도 별도로 허용해야 합니다.

5. DNS 리다이렉션: 일반 DNS, 암호화 DNS, DNS 루프 구분

단말의 게이트웨이와 DNS가 모두 보조 라우터를 가리켜도 모든 도메인 조회가 mihomo를 거치는 것은 아닙니다. 위 규칙이 처리하는 것은 보조 라우터를 통과하는 TCP/UDP 53번 포트 요청입니다. 브라우저의 보안 DNS, 시스템의 Private DNS, 앱에 내장된 DoH는 443 또는 853번 포트를 통해 다른 리졸버에 연결할 수 있습니다.

  • 기본 테스트: 테스트 단말에서 암호화 DNS를 잠시 끄고 일반 DNS 경로를 확인한 다음, 관련 기능을 다시 켜 정책을 검증하세요.
  • 포트 분리: OpenWrt dnsmasq는 53번 포트를 그대로 사용하고, mihomo는 1053번 포트를 사용하세요. 두 프로세스가 같은 주소와 포트를 동시에 수신하도록 설정하지 마세요.
  • 상위 DNS 루프: mihomo의 상위 DNS를 dnsmasq로 지정하면서 dnsmasq의 상위 DNS도 mihomo로 지정하지 마세요. DNS 조회가 반복되거나 시간 초과가 발생할 수 있습니다.
  • 노드 도메인: 프록시 노드를 추가한 뒤에는 노드 서버 도메인의 DNS 조회 경로를 확인하세요. proxy-server-nameserver를 사용하면 노드 도메인 조회용 리졸버를 별도로 지정할 수 있어 프록시 연결 전에 해당 프록시에 의존하는 상황을 피할 수 있습니다.
  • LAN 도메인: DHCP 호스트 이름을 조회해야 한다면 내부 도메인용 DNS 정책을 별도로 구성하고, 앞서 설명한 루프가 생기지 않는지 확인하세요.

예시에서는 테스트 단말의 출발지 IP에 해당하는 DNS 요청만 가로채므로 보조 라우터에서 발생한 DNS 요청은 같은 규칙에 다시 걸리지 않습니다. 이후 규칙을 모든 출발지 IP로 확대한다면 mihomo의 상위 DNS, 노드 연결, 라우터 자체 트래픽의 예외 조건을 다시 검토해야 합니다. 출발지 IP 제한만 무작정 삭제하지 마세요.

TUN 모드를 단순히 추가 옵션으로 켤 수 없는 이유

mihomo는 TUN도 지원하지만, TUN을 사용하려면 커널 장치 지원과 라우팅 및 DNS 리다이렉션을 함께 설계해야 합니다. auto-route, auto-redirect 등의 설정은 기존 라우팅과 nftables 규칙을 바꿀 수 있으므로 이 가이드의 수동 TPROXY 구성과 바로 함께 사용하면 안 됩니다. 단일 LAN 포트의 보조 라우터에서는 라우터 자체 요청만 확인하지 말고 전달되는 트래픽이 실제로 TUN에 들어가는지도 검증해야 합니다.

TUN을 사용하려면 먼저 이 가이드의 테스트 테이블과 정책 라우팅을 제거한 뒤, 현재 mihomo 버전에 맞춰 TUN을 다시 구성하세요. 두 방식의 목적은 처리할 연결을 mihomo로 전달하는 것입니다. 문제를 진단할 때는 여러 진입점을 동시에 켜기보다 트래픽 경로를 하나로 명확히 유지하는 편이 쉽습니다.

6. 동작 확인 순서: 직접 연결부터 프록시 정책까지

먼저 보조 라우터 자체에서 인터넷에 연결되는지 확인한 뒤 단말 트래픽을 점검하세요. 기본 설정의 최종 규칙은 MATCH,DIRECT이므로 외부 IP가 일반 직접 연결과 같아도 정상입니다. 이를 근거로 트래픽이 mihomo를 거치지 않는다고 판단하지 마세요. 카운터와 mihomo 로그를 함께 확인해야 합니다.

  1. 설정 확인: mihomo -t를 실행해 YAML 들여쓰기 오류, 알 수 없는 정책 그룹, 규칙 제공자 로드 실패가 없는지 확인하세요.
  2. 명시적 프록시 확인: 테스트 단말에서 아래 curl 명령을 실행하세요. 이 단계에서는 7890 포트의 프록시 접속만 확인하며 투명 프록시 동작은 검증하지 않습니다.
  3. DNS 확인: 192.168.10.2에 도메인 조회를 보내고 DNS NAT 카운터가 증가하는지 확인하세요. NAT 체인의 카운터는 새 연결이 규칙에 일치했는지 보여 주며, DNS 패킷 개수와 같은 의미는 아닙니다.
  4. 투명 연결 확인: 단말의 명시적 프록시 설정을 끈 뒤 공개 웹사이트에 접속하고 TPROXY 카운터와 logread -e mihomo의 연결 로그를 확인하세요.
  5. 프록시 출구 확인: 작동하는 노드를 가져오고 실제 정책 그룹을 구성한 뒤 최종 규칙을 교체하고 다시 요청을 보내세요. 로그의 출구 이름이 예상한 노드와 일치하는지 확인한 다음 대용량 파일, 동영상, UDP 앱도 테스트하세요.
# 테스트 단말에서 실행
curl -I --proxy http://192.168.10.2:7890 https://example.com/
nslookup example.com 192.168.10.2
curl -I --noproxy '*' https://example.com/

# 보조 라우터에서 실행
ip -4 rule show
ip -4 route show table 100
nft list table inet mihomo_test
logread -e mihomo

브라우저는 정상인데 게임에 문제가 있다면 UDP 리다이렉션 누락, 노드의 UDP 미지원, 앱에서 다른 주소 계열을 사용하는 경우가 흔합니다. 작은 웹페이지는 열리지만 대용량 연결이 멈춘다면 MTU, 경로 MTU 탐색, 패킷 손실을 확인하세요. 이런 문제를 모두 DNS 장애로 단정하지 말고, 로그도 없이 커널 매개변수를 임의로 바꾸지 마세요.

테스트 중에는 “네트워크” → “방화벽”에서 소프트웨어 및 하드웨어 플로우 오프로드를 잠시 끄면 빠른 경로가 관측 결과에 미치는 영향을 줄일 수 있습니다. 구성이 안정되면 항목별로 다시 켜고 재검증하세요. 이 가이드에는 실제 처리량 수치가 없습니다. 기기 CPU, 노드 프로토콜, 암호화 알고리즘, 회선 속도에 따라 결과가 달라지므로 같은 조건에서 여러 번 측정한 값을 기준으로 판단하세요.

7. 연결 장애 복구: 게이트웨이를 되돌린 뒤 가로채기 규칙 제거

전체 네트워크의 DHCP 게이트웨이를 보조 라우터로 바꾼 상태에서 보조 라우터 전원이 꺼져도 클라이언트가 자동으로 기본 라우터로 전환되지는 않습니다. procd는 프로세스 비정상 종료에 대응할 수 있지만 하드웨어 전원 장애, 잘못된 규칙, 상위 네트워크 연결 끊김은 해결하지 못합니다. 따라서 적용 범위를 넓히기 전에 복구 절차를 준비해야 합니다.

단일 단말 테스트 복구 절차

  1. 테스트 단말의 IPv4 게이트웨이와 DNS를 192.168.10.1로 되돌리거나 기본 라우터에서 자동으로 설정을 받도록 복원하세요.
  2. 보조 라우터에서 테스트용 nftables 테이블을 삭제해 연결 가로채기를 중단하세요.
  3. 이번 테스트에서 추가한 정책 라우팅과 로컬 라우팅만 삭제한 뒤 mihomo를 중지하세요.
  4. 네트워크 연결을 다시 설정하거나 단말의 DNS 캐시를 비운 뒤 직접 연결이 복구됐는지 확인하세요. 이미 연결된 프록시 세션은 보통 다시 연결해야 합니다.
nft delete table inet mihomo_test
ip -4 rule del priority 100 fwmark 0x1/0x1 lookup 100
ip -4 route del local 0.0.0.0/0 dev lo table 100
/etc/init.d/mihomo stop
/etc/init.d/mihomo disable

삭제 명령은 해당 항목이 이 가이드의 테스트에서 생성된 것이 확실할 때만 실행하세요. nft flush ruleset으로 기기 전체의 규칙을 비우거나 정책 라우팅 테이블 전체를 삭제하지 마세요. firewall4, VPN, 기타 네트워크 서비스에 영향을 줄 수 있습니다.

전체 네트워크 적용 전 점검 목록

  • 기본 라우터의 기존 DHCP 게이트웨이와 DNS 설정을 저장하고 임대 갱신 시각도 기록하세요. 설정을 복구해도 기존 임대 기간이 남은 단말은 계속 보조 라우터를 사용할 수 있습니다.
  • 고정 IP로 관리하는 PC나 기본 라우터 관리 주소처럼 보조 라우터를 거치지 않는 관리 경로를 유지하세요.
  • 구독 설정은 “임시 파일로 다운로드 → 설정 테스트 → 교체 → 재시작” 순서로 업데이트하세요. 실패하면 이전의 정상 설정을 유지해야 합니다.
  • 저장 공간과 로그 용량을 확인하세요. debug 로그를 계속 켜 두면 제한된 플래시 저장 공간이 소진될 수 있습니다.
  • mihomo 중지와 보조 라우터 전원 차단을 실제로 한 번씩 시험해 클라이언트 복구 절차를 확인하세요. 정상 시작만 점검해서는 충분하지 않습니다.

안정적인 배포 여부는 서비스가 “실행 중”으로 표시되는지만으로 판단할 수 없습니다. 게이트웨이, DNS, 투명 프록시 전달, 규칙에 따른 출구 선택, 장애 복구를 각각 검증해야 합니다. 먼저 단말 한 대에서 전체 흐름을 확인한 뒤 범위를 단계적으로 넓히면 변경으로 인한 영향을 줄일 수 있습니다.

Clash 다운로드