
Схема выглядит следующим образом:
Ни macvtap, ни FD‑редиректы, ни /dev/tap52 — ничего этого не нужно. Рабочая схема — только одна:
Это единственный способ, который работает в Docker‑namespace и даёт OpenWRT доступ к реальным портам.
Итоговая архитектура (рабочая)
Схема выглядит следующим образом:
enp6s0 (физика WAN)
↓
br-wan (мост)
↓
tap-wan (виртуальный TAP)
↓
QEMU → eth0 (WAN в OpenWRT)
enp7s0 (физика LAN)
↓
br-lan (мост)
↓
tap-lan (виртуальный TAP)
↓
QEMU → eth1 (LAN в OpenWRT)
OpenWRT внутри QEMU будет работать как настоящий роутер, потому что eth0/eth1 будут подключены к физическим портам.
Создание мостов и TAP‑интерфейсов на хосте
WAN
ip link add br-wan type bridge ip link set br-wan up ip link set enp6s0 master br-wan ip tuntap add tap-wan mode tap ip link set tap-wan up ip link set tap-wan master br-wan
LAN
ip link add br-lan type bridge ip link set br-lan up ip link set enp7s0 master br-lan ip tuntap add tap-lan mode tap ip link set tap-lan up ip link set tap-lan master br-lan
Проверка:
ip a | grep -E 'br-|tap-'
Правильный docker‑compose.yml
services:
openwrt-kvm:
build: .
container_name: openwrt-kvm
privileged: true
stdin_open: true
tty: true
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/kvm
- /dev/net/tun
volumes:
- /dev:/dev
- /opt/openwrt:/opt/openwrt
network_mode: "none"
Почему это правильно?
privileged: true— QEMU получает полный доступ к KVM и TUN./dev:/dev— контейнер видит tap-wan и tap-lan, созданные на хосте.network_mode: none— Docker не создаёт docker0/veth, сеть полностью под контролем QEMU.
Правильный entrypoint.sh (QEMU внутри Docker)
Создай /opt/openwrt/entrypoint.sh:
#!/bin/bash
set -e
exec qemu-system-x86_64 \
-enable-kvm \
-cpu host \
-m 512 \
-drive file=/opt/openwrt/openwrt.img,format=raw,if=virtio \
-nographic \
-serial mon:stdio \
\
-netdev tap,id=wan,ifname=tap-wan,script=no,downscript=no \
-device virtio-net-pci,netdev=wan \
\
-netdev tap,id=lan,ifname=tap-lan,script=no,downscript=no \
-device virtio-net-pci,netdev=lan
Сделать исполняемым:
chmod +x /opt/openwrt/entrypoint.sh
Конфиг OpenWRT
config interface 'wan'
option ifname 'eth0'
option proto 'dhcp'
config interface 'lan'
option ifname 'eth1'
option proto 'static'
option ipaddr '192.168.10.1'
option netmask '255.255.255.0'
OpenWRT в Docker работает через физические порты хоста
- eth0 в OpenWRT = enp6s0 на хосте
- eth1 в OpenWRT = enp7s0 на хосте
- DHCP, NAT, firewall — всё работает как на железном роутере
- скорость = скорость физического интерфейса
- никаких macvtap, никаких FD, никаких namespace‑конфликтов