OpenWrt 安装Tun

OpenWrt 默认没有 modprobe,所以一般要先安装:

opkg update
opkg install kmod-tun

检查设备节点

ls -l /dev/net/tun

正常情况下应该有:

crw-rw-rw-    1 root     root      10, 200 Aug 20 20:20 /dev/net/tun

如果没有,说明 TUN 设备未启用

openwrt 安装 tcpdump 用于抓包, 在路由器中查看是否劫持客户端电脑的DNS

opkg update
# 体积小:功能裁剪版(多数场景够用)
opkg install tcpdump-mini

# 或者安装完整版(建议,过滤器/解析功能更全)
opkg install tcpdump

路由器抓包看 WAN 口是否有 53 出去

tcpdump -ni eth_wan 'port 53'
tcpdump -ni eth0 'udp and port 443'
tcpdump -ni any icmp          # IPv4 ICMP
tcpdump -ni any proto 50      # ESP
tcpdump -ni any udp port 500 or udp port 4500  # IKE/NAT-T

先确认规则是否在生效、是否有命中

1) 列出 nft 规则

# 全部规则
nft list ruleset

# 只看你截图里的“dnsmasq”那张表
nft list table inet dnsmasq

# 带 handle 和计数器(建议看这个)
nft -a list chain inet dnsmasq prerouting

如果规则里没有 counter,可以临时加一个(或用 LuCI 加),便于看命中数是否在增长:

nft add rule inet dnsmasq prerouting udp dport 53 counter redirect to :53
# ↑ 只是示例,实际以你的规则为准

实时追踪一条 DNS 包是否命中

nft monitor trace

另一个终端执行 nslookup,然后观察 trace 是否显示命中 dnsmasq/prerouting 的 redirect 规则

3) 看 WAN 口是否还有 53 流量(最终验证)

tcpdump -ni <你的WAN口> 'port 53'
# 比如 pppoe-wan/eth0/eth1 等

能看到去 8.8.8.8 的 53 包 → 劫持没有命中。

完全看不到 53 → 劫持成功(即使你在 LAN 口仍能看到目的为 8.8.8.8 的“原始”包)。

4):

A. 追踪路由器自身 → 127.0.0.1:11302 的流量

# 1) 先开一个终端:
nft monitor trace

# 2) 在另一个终端,把打标规则插到 inet fw4 的 output 链最前面(确保能被命中)
nft insert rule inet fw4 output oifname "lo" udp dport {53,11301,11302} meta nftrace set 1
nft insert rule inet fw4 output oifname "lo" tcp dport {53,11301,11302} meta nftrace set 1
# 如有 IPv6 也会走 lo,这两条已覆盖,无需额外加 ip/ip6 条件

# 3) 再做一次 nslookup(指向 127.0.0.1:11302)
nslookup www.google.com 127.0.0.1#11302
# 此时 monitor 窗口应当开始滚动,显示命中的表/链/规则及 verdict

清理(用 handle 删除你刚插入的规则):

nft -a list chain inet fw4 output | grep nftrace
nft delete rule inet fw4 output handle <handle号>

B. 追踪“LAN 客户端的 DNS 被 NAT 重定向到 11302”的路径

(这才会经过你关心的 PREROUTING/DNAT 规则)

在路由器上打标 prerouting + 来自 LAN 的 53 端口,然后从 LAN 电脑 发起查询(别指向 127.0.0.1,而是随便写 8.8.8.8:53 或默认 DNS):

# 1) 监控窗口
nft monitor trace

# 2) 打标(把 br-lan 改成你的 LAN 接口名)
nft insert rule inet fw4 prerouting iifname "br-lan" udp dport 53 meta nftrace set 1
nft insert rule inet fw4 prerouting iifname "br-lan" tcp dport 53 meta nftrace set 1

# 3) 在 LAN 电脑上执行:
nslookup www.google.com 8.8.8.8
# 现在 monitor 会显示:进入 inet/fw4 的 prerouting → 命中 DNAT/redirect → 继续到本机 11302 的轨迹

清理同上,用 handle 删除。

nft -a list chain inet fw4 prerouting | grep nftrace
nft delete rule inet fw4 prerouting handle <handle号>

5): 两种链的对比

三条典型路径(帮助你定位问题)

  1. LAN 客户端 → 路由器本机 DNS (53)
    (ingress br-lan) → PREROUTING → (路由决策) → INPUT

想劫持它:在 PREROUTINGREDIRECT/DNAT → 11301/11302

  1. LAN 客户端 → 互联网(转发)
    (ingress br-lan) → PREROUTING → FORWARD → POSTROUTING → (egress wan)

常在 PREROUTING 打 mark/TProxy,POSTROUTING 做 SNAT/MASQUERADE

  1. 路由器本机进程 → 上游(如 dnsmasq → 1.1.1.1:53)
    (本机进程) → OUTPUT → POSTROUTING → (egress wan)

想“拦/排除”本机发出的 DNS,在 OUTPUT 上做;PREROUTING 是拦不到的。

6): 禁掉/旁路 非 TCP/UDP 对公网(ICMP/ESP/AH/GRE/NTP 等

方式一:用 LuCI(图形界面)加“流量规则”

目标:仅限制某台买家设备(举例 192.168.111.50)从 LAN → WAN 的非 TCP/UDP;另外单独拦截 NTP(UDP/123),避免侧向校时泄露。

  1. 打开:网络 → 防火墙 → 流量规则 → 添加
    • 名称:Block non-TCP/UDP to WAN (buyer)
    • 家族:IPv4/IPv6(任意)
    • 协议:自定义,填:icmp ah esp gre
    • 源区域:lan
    • 源IP:192.168.111.50(或你买家设备的 IP / 子网)
    • 目标区域:wan
    • 动作:丢弃(DROP)拒绝(REJECT)
    • 保存并应用
  2. 再加一条IPv6 的 ICMPv6(因为上面“icmp”不涵盖 v6 的 ICMPv6)
    • 名称:Block ICMPv6 to WAN (buyer)
    • 家族:仅 IPv6
    • 协议:icmp(在 IPv6 家族下就是 ICMPv6)
    • 其它同上 → 丢弃
  3. 可选:拦截 NTP(若你不希望该设备对公网校时)
    • 名称:Block NTP (buyer)
    • 家族:IPv4/IPv6(任意)
    • 协议:udp
    • 目标端口:123
    • 源区域:lan,源IP:192.168.111.50,目标区域:wan
    • 动作:拒绝(REJECT 更直观,应用会立即得到失败)

说明:这些规则只影响 LAN→WAN 的转发,不影响你在路由器本机上 ping/管理,也不影响 LAN 内互访。


方式二:命令行(UCI 一把梭)

把下面整段贴进 SSH 里(把 IP 改成你的买家设备 IP;如用整段 VLAN/子网,可把 src_ip 改成 192.168.111.0/24):

# 1) 阻断 IPv4/IPv6 的非 TCP/UDP 协议到 WAN(icmp/ah/esp/gre)
uci add firewall rule
uci set firewall.@rule[-1].name='Block-non-TCP_UDP-to-WAN'
uci set firewall.@rule[-1].src='lan'
uci set firewall.@rule[-1].src_ip='192.168.111.50'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].proto='icmp ah esp gre'
uci set firewall.@rule[-1].target='DROP'
uci set firewall.@rule[-1].family='any'

# 2) 补一条 ICMPv6(icmp 在 family:any 下未必涵盖 v6)
uci add firewall rule
uci set firewall.@rule[-1].name='Block-ICMPv6-to-WAN'
uci set firewall.@rule[-1].src='lan'
uci set firewall.@rule[-1].src_ip='192.168.111.50'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].proto='icmp'
uci set firewall.@rule[-1].family='ipv6'
uci set firewall.@rule[-1].target='DROP'

# 3) 可选:拦截 NTP(UDP/123)
uci add firewall rule
uci set firewall.@rule[-1].name='Block-NTP-to-WAN'
uci set firewall.@rule[-1].src='lan'
uci set firewall.@rule[-1].src_ip='192.168.111.50'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].proto='udp'
uci set firewall.@rule[-1].dest_port='123'
uci set firewall.@rule[-1].target='REJECT'
uci set firewall.@rule[-1].family='any'

uci commit firewall
/etc/init.d/firewall restart

发表回复