Overview
Running ImmortalWrt 24.10.5 as a VM on a PVE N5095 host (16GB DDR4), with a passed-through USB WiFi adaptor (MT7612U/RTL8811AU) broadcasting a visitor SSID. The setup enforces LAN isolation, bandwidth caps, and BitTorrent port blocking.
VM IP: 192.168.2.49 | Gateway: 192.168.2.254
1. VM Creation
# Download ImmortalWrt
wget https://downloads.immortalwrt.org/releases/24.10.5/x86_64/immortalwrt-24.10.5-x86-64-generic-ext4-combined.qcow2.gz
# Create VM (ID 100)
qm create 100 --name openwrt --memory 512 --net0 virtio,bridge=vmbr0 --cores 2 --cpu host
qm importdisk 100 immortalwrt-24.10.5-x86-64-generic-ext4-combined.qcow2.local qcow
qm set 100 --scsi0 local-lvm:qcow2
qm set 100 --boot order=scsi0
qm start 100
Attach the USB WiFi adaptor to the VM via PVE web UI (Hardware → Add → USB Device).
2. USB WiFi Adaptor Identification
Inside the VM:
opkg update
opkg install usbutils
lsusb
| Field | Value |
|---|---|
| Device | Realtek 802.11ac WLAN Adapter |
| USB ID | 0bda:0811 (RTL8811AU) |
| Driver tried | kmod-rtl8xxxu — did not bind |
| Driver used | kmod-rtl8812au-ct — worked |
opkg install kmod-rtl8812au-ct hostapd
The
0bda:0811device needsrtl8812au-ct, not the genericrtl8xxxu. Ifwlan0doesn't appear, checkdmesg | grep rtl.
3. Network Config (/etc/config/network)
# LAN bridge (eth0, native)
uci set network.lan.device='br-lan'
uci set network.lan.ipaddr='192.168.2.49'
uci set network.lan.netmask='255.255.255.0'
uci set network.lan.gateway='192.168.2.254'
uci add_list network.lan.dns='8.8.8.8'
# Visitor bridge (wlan0.20)
uci add network device
set network.@device[-1].name='br-visitor'
set network.@device[-1].type='bridge'
set network.@device[-1].ports='wlan0.20'
uci add network interface
set network.@interface[-1].name='vlan20'
set network.@interface[-1].device='br-visitor'
set network.@interface[-1].proto='static'
set network.@interface[-1].ipaddr='192.168.20.1'
set network.@interface[-1].netmask='255.255.255.0'
# IoT bridge (wlan0.30) — optional
uci add network device
set network.@device[-1].name='br-iot'
set network.@device[-1].type='bridge'
set network.@device[-1].ports='wlan0.30'
uci add network interface
set network.@interface[-1].name='vlan30'
set network.@interface[-1].device='br-iot'
set network.@interface[-1].proto='static'
set network.@interface[-1].ipaddr='192.168.30.1'
set network.@interface[-1].netmask='255.255.255.0'
uci commit network
4. Wireless Config (/etc/config/wireless)
# Radio0 — 5GHz, channel 36
uci set wireless.radio0=wifi-device
set wireless.radio0.type='mac80211'
set wireless.radio0.path='pci0000:00/0000:00:1e.0/usb2/2-1/2-1:1.0'
set wireless.radio0.band='5g'
set wireless.radio0.channel='36'
set wireless.radio0.country='CN'
set wireless.radio0.disabled='0'
# Visitor SSID (no encryption for demo — add WPA2 in production)
uci add wireless wifi-iface
set wireless.@wifi-iface[-1].device='radio0'
set wireless.@wifi-iface[-1].mode='ap'
set wireless.@wifi-iface[-1].ssid='Visitor'
set wireless.@wifi-iface[-1].network='vlan20'
set wireless.@wifi-iface[-1].ifname='wlan0.20'
set wireless.@wifi-iface[-1].encryption='none'
# IoT SSID
uci add wireless wifi-iface
set wireless.@wifi-iface[-1].device='radio0'
set wireless.@wifi-iface[-1].mode='ap'
set wireless.@wifi-iface[-1].ssid='IoT'
set wireless.@wifi-iface[-1].network='vlan30'
set wireless.@wifi-iface[-1].ifname='wlan0.30'
set wireless.@wifi-iface[-1].encryption='none'
uci commit wireless
wifi
5. Firewall — LAN Isolation & NAT (/etc/config/firewall)
⚠️ Known Issue: LAN isolation rules added via
iptablesdirectly are NOT persistent — they disappear after reboot. Must use UCIfirewallconfig or add to/etc/firewall.user.
5a. Persistent Firewall Zones (UCI way)
# WAN zone (default)
uci set firewall.@zone[0].name='wan'
list firewall.@zone[0].network='wan'
set firewall.@zone[0].masq='1'
set firewall.@zone[0].mtu_fix='1'
# Visitor zone
uci add firewall zone
set firewall.@zone[-1].name='visitor'
list firewall.@zone[-1].network='vlan20'
set firewall.@zone[-1].input='REJECT'
set firewall.@zone[-1].output='ACCEPT'
set firewall.@zone[-1].forward='REJECT'
# Visitor → WAN forwarding
uci add firewall forwarding
set firewall.@forwarding[-1].src='visitor'
set firewall.@forwarding[-1].dest='wan'
# Allow DHCP/DNS for visitor
uci add firewall rule
set firewall.@rule[-1].name='Visitor DHCP/DNS'
list firewall.@rule[-1].src='visitor'
list firewall.@rule[-1].dest='wan'
set firewall.@rule[-1].proto='udp'
list firewall.@rule[-1].dest_port='53 67'
set firewall.@rule[-1].target='ACCEPT'
# Allow gateway access (192.168.2.254)
uci add firewall rule
set firewall.@rule[-1].name='Allow Gateway'
list firewall.@rule[-1].src='visitor'
set firewall.@rule[-1].dest='wan'
set firewall.@rule[-1].dest_ip='192.168.2.254'
set firewall.@rule[-1].proto='all'
set firewall.@rule[-1].target='ACCEPT'
# ❌ Drop all other access to LAN (192.168.2.0/24)
uci add firewall rule
set firewall.@rule[-1].name='Drop LAN Access'
list firewall.@rule[-1].src='visitor'
set firewall.@rule[-1].dest='wan'
set firewall.@rule[-1].dest_ip='192.168.2.0/24'
set firewall.@rule[-1].proto='all'
set firewall.@rule[-1].target='REJECT'
uci commit firewall
/etc/init.d/firewall restart
5b. Persistent iptables Rules (fallback — /etc/firewall.user)
# Append to /etc/firewall.user — survives reboot
cat >> /etc/firewall.user << 'EOF'
# --- Visitor LAN Isolation ---
# Allow gateway only
iptables -A forwarding_rule -i br-visitor -d 192.168.2.254 -j ACCEPT
# Drop everything else to LAN
iptables -A forwarding_rule -i br-visitor -d 192.168.2.0/24 -j DROP
EOF
6. Bandwidth Cap — HTB on br-visitor (/etc/config/sqm)
opkg update
opkg install sqm-scripts kmod-sched
# /etc/config/sqm
config queue
option enabled '1'
option interface 'br-visitor'
option qdisc 'htb'
option script 'queue.sh'
option linklayer 'ethernet'
option overhead '22'
option download '4000' # 4Mbit down
option upload '512' # 512Kbit up
uci set sqm.eth0.interface='br-visitor'
uci set sqm.eth0.qdisc='htb'
uci set sqm.eth0.linklayer='ethernet'
uci set sqm.eth0.download='4000'
uci set sqm.eth0.upload='512'
uci commit sqm
/etc/init.d/sqm enable
/etc/init.d/sqm start
Verify:
tc qdisc show dev br-visitor
tc class show dev br-visitor
Expected output shows htb root with 4Mbit ceiling.
7. BitTorrent Port Blocking
# /etc/firewall.user — add before "Return" line
cat >> /etc/firewall.user << 'EOF'
# --- Block BitTorrent ---
# Common BitTorrent ports
iptables -A FORWARD -i br-visitor -p tcp --dport 6881:6889 -j DROP
iptables -A FORWARD -i br-visitor -p tcp --dport 51413 -j DROP
iptables -A FORWARD -i br-visitor -p udp --dport 51413 -j DROP
EOF
/etc/init.d/firewall restart
8. DHCP for Visitor Network
# /etc/config/dhcp
config dhcp 'vlan20'
option interface 'vlan20'
option start '100'
option limit '150'
option leasetime '1h'
list dhcp_option '6,8.8.8.8,8.8.4.4'
uci commit dhcp
/etc/init.d/dnsmasq restart
9. Verification Checklist
| Feature | Command | Expected |
|---|---|---|
| NAT masquerade | iptables -t nat -L POSTROUTING -v |
MASQUERADE on WAN |
| LAN isolation | iptables -L forwarding_rule -v |
192.168.2.0/24 DROP packets |
| Gateway access | ping 192.168.2.254 from visitor client |
✓ reply |
| Bandwidth cap | tc qdisc show dev br-visitor |
htb with 4Mbit |
| Torrent block | `iptables -L FORWARD -v | grep 688` |
| SSID up | logread -e hostapd |
wlan0.20, wlan0.30 active |
10. Known Issue: LAN Isolation Not Persistent After Reboot
Symptom: After OpenWrt VM reboots, LAN isolation stops working — visitor clients can reach 192.168.2.0/24.
Root cause: Direct iptables commands issued via CLI are ephemeral. They are lost on reboot.
Fix: Rules must be in /etc/firewall.user or UCI firewall config (see Section 5 above).
If you already have broken rules: Clear and restart:
# Flush all forwarding rules
iptables -F forwarding_rule
iptables -F FORWARD
# Restart firewall to load persistent rules
/etc/init.d/firewall restart
# Verify
iptables -L forwarding_rule -v
11. Full Config File Summary
| File | Purpose |
|---|---|
/etc/config/network |
Bridges, VLAN sub-interfaces, static IPs |
/etc/config/wireless |
Radio0, SSIDs, encryption |
/etc/config/firewall |
Zones, forwarding, masquerade |
/etc/config/dhcp |
DHCP pools for visitor/IoT |
/etc/config/sqm |
HTB bandwidth shaping |
/etc/firewall.user |
Persistent iptables custom rules |
Hardware Used
- PVE Host: N5095 / 16GB DDR4
- USB WiFi: Realtek
0bda:0811(MT7612U/RTL8811AU based) - Working driver:
kmod-rtl8812au-ct - OS inside VM: ImmortalWrt 24.10.5 x86_64