먼저 배포 토폴로지 결정하기: 메인 라우터인가, 보조 라우터인가

OpenWrt에서 Clash 계열 코어를 실행할 때는 현재 보통 mihomo를 배포합니다. mihomo는 Clash Meta의 설정 형식과 규칙 기능을 이어받아 YAML 설정을 직접 읽고 mixed-port, DNS, TUN, 규칙 세트와 외부 제어 인터페이스를 제공합니다. 라우터 환경은 데스크톱 클라이언트와 다릅니다. 데스크톱 클라이언트는 로컬 트래픽만 처리하지만, 라우터는 LAN 기기에서 들어오는 전달 트래픽을 식별하고 DNS, 정책 라우팅, IPv4와 IPv6의 반환 경로까지 처리해야 합니다.

배포 전에 장치가 네트워크에서 맡을 역할부터 정해야 합니다. 메인 라우터 방식은 OpenWrt가 PPPoE 연결, DHCP, DNS와 기본 게이트웨이를 담당하므로 데이터 경로가 명확하고 투명 프록시 규칙도 통합 관리하기 쉽습니다. 보조 라우터 방식은 기존 메인 라우터를 유지하면서 OpenWrt를 같은 LAN의 두 번째 3계층 장치로 사용해 지정한 단말이나 DHCP로 할당된 트래픽만 넘겨받습니다. 보조 라우터는 변경 범위가 작지만 게이트웨이, DNS와 반환 경로를 항목별로 확인해야 합니다.

메인 라우터 토폴로지

  • 광모뎀을 브리지 모드로 사용하면 OpenWrt의 WAN 포트가 PPPoE 연결을 수행하고, 광모뎀이 라우터 모드라면 OpenWrt WAN 포트가 상위 네트워크에서 주소를 받습니다.
  • LAN 단말의 기본 게이트웨이는 OpenWrt를 가리킵니다. 예: 192.168.10.1.
  • DHCP와 DNS는 모두 OpenWrt가 제공하므로 단말에서 프록시 주소를 따로 설정할 필요가 없습니다.
  • TUN 또는 TProxy 규칙은 전체 LAN에 적용할 수도 있고, 소스 주소, MAC에 연결된 고정 임대 주소 또는 대상 네트워크를 기준으로 우회할 수도 있습니다.

보조 라우터 토폴로지

  • 메인 라우터는 192.168.1.1을 사용하고, 보조 라우터는 같은 서브넷의 고정 주소 192.168.1.2로 설정할 수 있습니다.
  • 보조 라우터의 기본 게이트웨이와 상위 DNS는 먼저 메인 라우터를 가리키게 설정해야 구독을 업데이트할 때 자체 인터넷 연결이 끊기지 않습니다.
  • 프록시가 필요한 단말은 게이트웨이와 DNS를 192.168.1.2로 지정하고, 나머지 단말은 계속 메인 라우터를 사용합니다.
  • 메인 라우터의 DHCP가 사용자 지정 게이트웨이 배포를 지원한다면 보조 라우터 주소를 일괄 배포할 수 있습니다. 그렇지 않으면 단말에서 직접 설정하거나 DHCP 서비스 범위를 신중하게 조정해야 합니다.

하드웨어, 아키텍처와 저장 공간

코어가 시작되는지는 아키텍처와 런타임 라이브러리의 호환 여부에 달려 있고, 실제 처리량은 CPU 단일 코어 성능, 암호화 알고리즘, 규칙 규모, 연결 수와 네트워크 드라이버의 영향을 함께 받습니다. 두세 대의 단말에서 약 100Mbps 대역폭을 사용하는 정도라면 듀얼 코어 ARM64와 256MB 메모리로 기본 규칙 프록시를 처리할 수 있습니다. 500Mbps 이상을 목표로 하면서 TUN, DNS fake-ip와 대규모 규칙 세트를 동시에 사용한다면 쿼드 코어 ARM64와 512MB 메모리부터 시작하는 것이 좋습니다. 기가비트 회선에서는 장치의 NAT 처리 성능, 네트워크 카드 인터럽트와 CPU 소프트 인터럽트 사용량도 확인해야 합니다.

수만 개의 규칙과 여러 rule-provider가 포함된 설정에서 mihomo의 상주 메모리는 보통 약 80~180MB입니다. 도메인 규칙, 연결 추적과 패널 조회를 많이 활성화하면 더 늘어납니다. OpenWrt 자체와 dnsmasq, firewall4, 로그 서비스도 메모리를 사용하므로 128MB 장치는 대개 간소화한 설정에만 적합합니다. 플래시 저장 공간은 코어 파일, GeoIP, GeoSite, 규칙 세트와 임시 다운로드 파일을 합쳐 100MB 이상 확보하는 편이 안전합니다.

CPU 아키텍처 확인

SSH로 OpenWrt에 로그인한 뒤 먼저 시스템 보고서를 확인하세요. 라우터 상품명만 보고 바이너리 파일을 선택해서는 안 됩니다.

uname -m
ubus call system board
cat /etc/openwrt_release

x86_64는 AMD64에 해당하고 aarch64는 ARM64에 해당합니다. 일부 구형 장치는 armv7l, mips 또는 mipsel을 반환합니다. MIPS는 엔디언과 부동소수점 구현도 나뉘므로 다운로드 전에 릴리스 파일의 아키텍처 표기와 항목별로 대조해야 합니다. 바이너리 아키텍처가 잘못되면 실행 시 대개 Exec format error가 바로 반환됩니다.

TUN과 투명 프록시 모듈 확인

ls -l /dev/net/tun
opkg list-installed | grep -E 'kmod-tun|firewall4|nftables'
nft list ruleset | head

TUN 모드에는 최소한 커널의 TUN 지원이 필요하며 OpenWrt에서 흔히 사용하는 패키지는 kmod-tun입니다. nftables 기반 TProxy 방식에는 현재 펌웨어가 제공하는 투명 프록시 모듈도 필요합니다. 예를 들면 kmod-nft-tproxy입니다. 패키지 이름은 OpenWrt 브랜치와 대상 플랫폼에 따라 달라질 수 있으므로 현재 장치의 패키지 저장소를 기준으로 판단하고, 다른 버전 저장소의 커널 모듈을 섞어 설치하지 마세요.

mihomo 코어와 최소 설정 배치

독립 배포라면 실행 파일은 /usr/bin/mihomo에, 설정과 실행 데이터는 /etc/mihomo에 두는 것이 좋습니다. 플래시 공간이 부족한 장치에서는 규칙 세트 디렉터리를 마운트한 USB 저장 장치로 옮길 수도 있지만, 시작 스크립트가 마운트 완료를 기다리도록 해야 합니다. 아래 명령은 바이너리 파일을 SCP로 /tmp/mihomo에 업로드했다고 가정합니다.

mkdir -p /etc/mihomo
install -m 0755 /tmp/mihomo /usr/bin/mihomo
/usr/bin/mihomo -v

먼저 실행 가능한 /etc/mihomo/config.yaml을 만드세요. 프록시 노드와 프록시 그룹은 실제 서비스 설정에서 가져와야 하며, 아래 예시는 라우터와 관련된 수신 포트, 제어 인터페이스와 DNS 구조만 보여 줍니다.

mixed-port: 7890
redir-port: 7892
tproxy-port: 7893
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: false

external-controller: 127.0.0.1:9090
secret: "change-this-controller-secret"

profile:
  store-selected: true
  store-fake-ip: true

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"
  nameserver:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query

proxies: []
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - DIRECT

rules:
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

allow-lan: true를 사용하면 LAN 단말이 프록시 수신 포트에 접근할 수 있으므로 OpenWrt 방화벽은 신뢰할 수 있는 LAN 영역에서만 7890, 7892, 7893과 DNS 수신 포트에 접근하도록 해야 합니다. 외부 제어 인터페이스 예시는 127.0.0.1:9090에만 바인딩되어 있습니다. 패널을 다른 장치에 배포한다면 LAN 수신 주소로 바꾸고, 충분히 무작위적인 secret과 명확한 방화벽 소스 제한을 설정해야 합니다.

저장한 뒤 먼저 구문을 검증하고 포그라운드 방식으로 시작하세요. -d는 실행 디렉터리를 지정하며, mihomo는 해당 디렉터리에서 config.yaml을 읽고 캐시 데이터를 저장합니다.

/usr/bin/mihomo -t -d /etc/mihomo
/usr/bin/mihomo -d /etc/mihomo

설정 로딩이 완료되면 다른 SSH 세션에서 포트를 확인합니다.

ss -lntup | grep -E '7890|7892|7893|9090|1053'
logread -f

TUN과 TProxy 비교

TUN과 TProxy는 모두 단말에서 별도 설정 없이 연결되도록 만들 수 있지만 처리 경로는 다릅니다. TUN은 mihomo가 가상 네트워크 카드를 만들고 가상 인터페이스로 들어온 IP 트래픽을 사용자 공간 프로토콜 스택으로 전달합니다. TProxy는 방화벽 마크, 정책 라우팅과 투명 소켓을 사용해 TCP 또는 UDP 트래픽을 지정된 수신 포트로 보내면서 원래 대상 주소를 유지합니다. 어느 방식도 설정 하나만 켜면 끝나는 것이 아니며, 라우터에서는 현재 OpenWrt의 전달 및 방화벽 구조에 맞춰야 합니다.

TUN: 비교적 단순한 배포 경로

mihomo의 TUN 설정은 YAML에 직접 작성할 수 있습니다. OpenWrt에서는 보통 system 스택을 사용하고 자동 라우팅과 출구 인터페이스 자동 감지를 함께 설정합니다.

tun:
  enable: true
  stack: system
  device: mihomo
  auto-route: true
  auto-detect-interface: true
  strict-route: true
  dns-hijack:
    - any:53
  mtu: 1500

TUN의 장점은 규칙이 주로 코어 설정에 집중되고 TCP와 UDP 처리 방식이 일관되어 게임기, TV와 수동 프록시를 지원하지 않는 앱에 더 적합하다는 점입니다. 단점은 데이터가 사용자 공간의 가상 네트워크 카드로 들어가므로 저성능 라우터에서는 목적에 맞게 구성한 TProxy보다 CPU 사용량이 높을 수 있다는 것입니다. 일부 웹사이트만 시간 초과되고 작은 패킷은 정상이라면 MTU를 1500에서 1480, 1460 또는 1400으로 단계적으로 낮춰 테스트할 수 있지만 최종값은 PPPoE, 터널과 상위 네트워크를 함께 고려해 정해야 합니다.

TProxy: 세밀한 제어

TProxy는 nftables, 정책 라우팅과 OpenWrt firewall4에 익숙한 관리자가 사용하기에 더 적합합니다. 일반적인 데이터 경로는 prerouting 체인에서 LAN 트래픽을 선별하고, LAN과 예약 주소를 제외한 뒤, 대상 연결에 방화벽 마크를 설정하고, ip rule로 마크된 트래픽을 로컬 라우팅 테이블로 보낸 다음 mihomo의 tproxy-port: 7893으로 전달하는 방식입니다. UDP도 별도로 규칙에 포함해야 합니다.

OpenWrt 22.03 이후 기본 방화벽은 firewall4와 nftables를 사용합니다. 예전 튜토리얼의 iptables 명령, 체인 이름과 실행 시점은 nftables 환경에 그대로 적용할 수 없습니다. TProxy 규칙을 직접 작성할 때는 라우터 자체에서 시작한 구독 다운로드, NTP, 패키지 업데이트와 노드 연결을 중복 처리하지 않도록 해야 합니다. 그렇지 않으면 프록시 루프가 발생할 수 있습니다. 실제 배포에서는 현재 OpenWrt 버전에 맞는 관리 구성 요소로 규칙을 생성하고, nft list ruleset으로 결과를 확인하는 편이 좋습니다.

선택 기준

  • TCP, UDP와 대부분의 LAN 장치를 빠르게 처리해야 한다면 TUN을 우선 검토하세요.
  • 장치 CPU가 약하지만 관리자가 nftables를 정밀하게 관리할 수 있다면 TProxy를 검토할 수 있습니다.
  • 브라우저와 소수의 컴퓨터만 프록시로 연결한다면 먼저 mixed-port: 7890을 사용하고 투명 프록시의 복잡성을 바로 추가하지 않아도 됩니다.
  • 단말별로 트래픽을 분기해야 한다면 두 방식 모두 소스 IP 기준 제어가 가능합니다. 단, DHCP가 단말에 고정 주소를 할당해야 합니다.
  • 네트워크에서 IPv6를 사용한다면 IPv6 DNS, 라우팅과 방화벽 정책도 함께 설계해야 합니다. IPv4만 처리한 뒤 모든 연결이 프록시를 통과한다고 가정해서는 안 됩니다.

구독 업데이트: 다운로드, 설정 구문 검증, 원자적 교체

라우터의 구독은 URL을 그래픽 인터페이스에 입력하는 것으로 끝나지 않습니다. 업데이트 과정에는 최소한 임시 파일로 다운로드, YAML 테스트, 정식 설정 교체와 서비스 리로드의 네 단계가 필요합니다. 사용 중인 config.yaml을 바로 덮어쓰면 다운로드가 중단되거나 서버가 HTML 오류 페이지를 반환했을 때 다음 재부팅에서 설정을 불러오지 못할 수 있습니다.

아래 스크립트는 uclient-fetch로 전체 설정을 다운로드합니다. 구독 주소는 root만 읽을 수 있는 파일이나 스크립트에 저장하고 공개 로그에 출력하지 않아야 합니다. 스크립트를 /usr/bin/update-mihomo로 저장한 뒤 chmod 700 /usr/bin/update-mihomo를 실행하세요.

#!/bin/sh
set -eu

CONFIG_DIR="/etc/mihomo"
TEMP_FILE="/tmp/mihomo-config.yaml"
SUB_URL="https://subscription.example/path"

uclient-fetch -q -O "$TEMP_FILE" "$SUB_URL"

/usr/bin/mihomo -t -f "$TEMP_FILE"

cp "$CONFIG_DIR/config.yaml" "$CONFIG_DIR/config.yaml.bak"
mv "$TEMP_FILE" "$CONFIG_DIR/config.yaml"

/etc/init.d/mihomo reload || /etc/init.d/mihomo restart

mihomo -t -f는 지정한 설정 파일을 구문 분석해 YAML 들여쓰기, 필드 구조와 일부 규칙 오류를 잡아낼 수 있습니다. 모든 원격 노드에 연결할 수 있는지까지 확인하지는 않으므로 업데이트 후에도 서비스 로그와 프록시 그룹 상태를 확인해야 합니다. 구독에 특정 User-Agent나 리디렉션이 필요하다면 서비스 제공업체의 요구 사항에 맞춰 다운로드 명령을 조정하세요.

수동 업데이트가 안정적으로 동작하는 것을 확인한 뒤 cron에 등록하세요. 예를 들어 매일 04:17에 한 번 업데이트하려면 다음과 같습니다.

17 4 * * * /usr/bin/update-mihomo >> /tmp/mihomo-update.log 2>&1

OpenWrt의 /tmp는 메모리 파일 시스템에 있으므로 업데이트 로그가 재부팅 후 삭제되며 플래시에 장기간 기록하지 않아도 됩니다. 문제를 해결하는 동안에는 로그 크기를 제한하고, 장기 실행 환경에서는 디버그 수준 로그를 플래시에 계속 기록하지 않는 것이 좋습니다.

procd로 부팅 시 자동 실행 설정

OpenWrt 서비스는 백그라운드 명령을 /etc/rc.local에 직접 추가하지 말고 procd가 관리하도록 해야 합니다. procd는 프로세스를 추적하고 비정상 종료 후 다시 시작하며 시작, 중지와 리로드를 일관되게 처리합니다. /etc/init.d/mihomo를 생성하세요.

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

START=99
STOP=10
USE_PROCD=1

start_service() {
  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
}

reload_service() {
  procd_send_signal mihomo HUP
}

service_triggers() {
  procd_add_reload_trigger "network"
}

실행 권한을 부여하고 서비스를 활성화합니다.

chmod 755 /etc/init.d/mihomo
/etc/init.d/mihomo enable
/etc/init.d/mihomo start
/etc/init.d/mihomo status
logread -e mihomo

respawn 3600 5 5는 관찰 시간 내 비정상 종료를 처리하고 재시작을 지연해 프로세스가 반복적으로 충돌할 때 촘촘한 재시작 루프가 생기지 않도록 합니다. 설정에 포함된 원격 규칙 세트를 네트워크로 다운로드해야 한다면 첫 시작이 WAN 준비 전에 실행되어 영향을 받을 수 있습니다. 필요한 규칙 파일을 미리 로컬에 저장하거나 네트워크 연결 후 업데이트 작업을 별도로 실행하고, 매번 시작할 때 모든 원격 리소스를 즉시 가져오도록 의존하지 마세요.

트래픽 분기, 보안 경계와 일반적인 장애

예약 주소는 반드시 직접 연결

투명 프록시 규칙은 로컬 루프백, LAN, 멀티캐스트와 예약 주소를 제외해야 합니다. 예를 들면 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4입니다. 가정에서 여러 사설 네트워크를 사용한다면 정적 라우팅으로 서로 통신하는 네트워크를 명확히 지정해야 합니다. NAS, 프린터와 관리 페이지를 무조건 프록시로 보내면 우회 경로가 생기고 라우터 관리 화면에 접속하지 못할 수도 있습니다.

제어 인터페이스는 관리 네트워크에만 공개

9090 제어 인터페이스에서는 프록시 그룹 전환, 연결 조회와 실행 상태 변경이 가능하므로 기본적으로 루프백 주소에 바인딩해야 합니다. LAN에서 패널을 사용해야 한다면 라우터 LAN 주소에 바인딩할 수 있습니다. 예: 192.168.10.1:9090. 동시에 secret을 설정하고 방화벽으로 접근 출처를 제한하세요. 프록시 포트도 LAN 방화벽 영역에서만 열어야 하며 WAN에서 연결을 받아서는 안 됩니다.

코어가 시작된 후에도 단말에서 인터넷에 연결되지 않음

  1. 라우터에서 ip route를 실행해 기본 경로가 실제 WAN을 가리키는지 확인하세요.
  2. nslookup openwrt.org 127.0.0.1을 실행해 기본 DNS가 정상인지 확인하세요.
  3. 컴퓨터를 라우터의 7890 포트에 수동으로 연결해 노드와 구독 문제를 분리하세요.
  4. nft list ruleset을 실행해 투명 프록시 체인이 실제로 존재하고 카운터가 증가하는지 확인하세요.
  5. 단말의 게이트웨이와 DNS가 계획한 메인 라우터 또는 보조 라우터 주소를 모두 가리키는지 확인하세요.

중국 본토 사이트는 정상적으로 접속되지만 일부 해외 사이트가 시간 초과됨

먼저 프록시 그룹에서 사용 가능한 노드를 선택했는지 확인한 다음 도메인 해석 결과와 규칙 적용 여부를 비교하세요. 큰 페이지, 업로드 또는 동영상 연결만 실패한다면 MTU를 테스트하세요. PPPoE 회선은 일반 이더넷보다 보통 8바이트 작고, 다른 터널을 추가하면 더 줄어듭니다. 패킷 길이를 단계적으로 줄여 관찰할 수 있지만 모든 장애를 MTU 탓으로 돌려서는 안 됩니다.

라우터에서는 접속되지만 LAN 단말에서는 접속되지 않음

이 경우 대개 mihomo 자체의 외부 연결은 정상이나 LAN 전달 경로가 투명 프록시로 들어가지 않았다는 뜻입니다. 메인 라우터에서는 LAN에서 WAN으로의 전달과 투명 프록시 규칙을 확인하고, 보조 라우터에서는 net.ipv4.ip_forward, 방화벽 영역과 단말 게이트웨이를 확인하세요. 단말이 여전히 메인 라우터를 게이트웨이로 사용한다면 트래픽은 보조 라우터를 거치지 않습니다.

재부팅 후 서비스는 존재하지만 규칙이 적용되지 않음

서비스 시작과 방화벽 로딩에는 순서 차이가 있을 수 있습니다. TProxy 규칙을 별도 스크립트로 생성한다면 firewall4의 include 또는 핫플러그 메커니즘에 연결하고, 반복 실행해도 중복 체인이 생성되지 않도록 해야 합니다. TUN 자동 라우팅을 사용한다면 시작 로그에 인터페이스 생성, 라우팅 테이블 또는 권한 오류가 있는지 확인하고, 시작 시 /dev/net/tun을 사용할 수 있는지도 확인하세요.

배포 검수 체크리스트

라우터에서 코어를 직접 실행할 때 중요한 것은 프로세스가 “실행 중”으로 표시되는 것이 아니라 전체 데이터 경로가 예측 가능하고 복구 가능하게 작동하는 것입니다. 가정용 네트워크를 정식으로 넘기기 전에 다음 체크리스트를 항목별로 확인할 수 있습니다.

  • 코어 아키텍처가 장치와 일치하고 mihomo -v가 버전 정보를 정상적으로 반환합니다.
  • mihomo -t가 설정 검사를 통과하며 구독 업데이트에 실패해도 기존 설정이 덮어쓰이지 않습니다.
  • 7890 일반 프록시 포트를 별도로 검증했고 노드와 프록시 그룹이 연결을 설정할 수 있습니다.
  • 메인 라우터 또는 보조 라우터의 게이트웨이, DHCP와 DNS 역할이 명확하며 두 DHCP 서비스가 충돌하지 않습니다.
  • TUN 또는 TProxy 중 하나의 주요 트래픽 처리 경로만 활성화해 같은 연결이 중복 리디렉션되지 않도록 합니다.
  • LAN, 라우터 관리 주소, 멀티캐스트와 필요한 예약 네트워크가 프록시를 우회하도록 설정되어 있습니다.
  • 제어 인터페이스에 접근 키를 설정하고 방화벽으로 신뢰할 수 있는 관리 네트워크에만 허용합니다.
  • 장치를 재부팅한 뒤 WAN, 시간, DNS, mihomo와 투명 프록시 규칙이 순서대로 복구됩니다.
  • 웹 페이지, 동영상, UDP 앱, LAN NAS와 프린터 접근을 각각 테스트합니다.
  • 속도를 측정할 때 단일 대역폭 결과만 보지 말고 CPU, 메모리, 소프트 인터럽트와 온도를 기록합니다.

처음 배포한다면 먼저 일반 mixed-port와 테스트 단말 한 대로 시작한 뒤 TUN 또는 TProxy로 확장하는 것이 좋습니다. 메인 라우터 방식은 경로가 더 직접적이어서 일괄 적용에 적합하고, 보조 라우터 방식은 단계적인 이전에 유리해 소수의 장치부터 적용하기 좋습니다. 어떤 토폴로지를 선택하든 설정 구문, DNS 경로, 방화벽 규칙과 부팅 후 복구를 각각 검증할 수 있어야 합니다.