osnosn

  博客园 :: 首页 :: :: 联系 :: 订阅 :: 管理 ::

Openwrt2203_双wan口_简单的策略路由_DMZ设置

转载注明来源: 本文链接 来自osnosn的博客,写于 2025-11-20.

环境

  • 使用openwrt2203。 op23,op24的配置方法相同, 因为都是使用的fw4。
  • 有一个lan,两个wan,分别是wan1wan2
    lan:192.168.1.1/24, wan1:10.100.9.20/gw 10.100.9.1, wan2:192.168.8.8/gw 192.168.8.1,
  • 仅 ipv4环境,无ipv6。
  • lan口连接一台windows电脑,未设置 DMZ主机。win电脑上网,所有数据包走wan1
    win: 192.168.1.55
  • op配置了 wireguard,但udp走wan1干扰很大,不稳定。
    需要让 wg的 udp包走 wan2

配置方案

  • 用nft防火墙规则对特定的数据包, 打上标记 (mark 100)
  • 根据 mark 使用特殊的路由表。
    有 mark标记的数据包,走路由表100,走wan2.
    其他所有数据包 使用默认路由表,走 wan1.

策略路由配置

  • op中,主路由表的缺省路由是: default via 10.100.9.1
  • 测试 (2025-12测)
    win中使用 tracert -d -w 1 202.12.12.12测试,数据走的是wan1
    op 中使用 traceroute -n -w 1 202.12.12.12测试,数据走的是wan1

配置路由规则

  • op中,路由表 100中,添加路由记录
    ip route add 10.100.0.0/16 via 10.100.9.1 table 100 metric 10   ## 10.100网段还是走wan1
    ip route add 0.0.0.0/0 via 192.168.8.1 table 100 metric 50      ## 其他数据走wan2
    
    对应的luci操作,
    Network -> Routing -> Static IPv4 Routes -> 添加路由
    ---- 1 ----
    - General Settings
      - Interface: wan1
      - Route type: unicast   #默认值
      - Target: 10.100.0.0/16
      - Gateway: 10.100.9.1
    - Advanced Settings
      - Metric: 10
      - Table: 100
    - 其他内容: 默认/留空/不改变
    ---- 2 ----
    - General Settings
      - Interface: wan2
      - Route type: unicast   #默认值
      - Target: 0.0.0.0/0
      - Gateway: 192.168.8.1
    - Advanced Settings
      - Metric: 50
      - Table: 100
    - 其他内容: 默认/留空/不改变
    
  • op中,添加路由规则。设置优先级3002,是因为后续要加rule在它前面。
    ip rule add from all fwmark 100 lookup 100 pref 3002
    对应的luci操作,
    Network -> Routing -> IPv4 Rules -> 添加规则
    - General Settings
      - Priority: 3002
      - Route type: unicast   #默认值
      - Table: 100
    - Advanced Settings
      - Firewall mark: 100
    - 其他内容: 默认/留空/不改变
    

    Firewall mark 支持 "值/掩码"格式,比如 luci中写 "0x64/0xff" 表示 "fwmark 0x64/0xff"

  • 测试, (没有变化) (2025-12测)
    win中使用 tracert -d -w 1 202.12.12.12测试,数据走的是wan1
    op 中使用 traceroute -n -w 1 202.12.12.12测试,数据走的是wan1

配置防火墙规则

  • op中,添加防火墙规则, 0x64=100, (测试nft规则1)
    nft add rule inet fw4 mangle_output ip daddr 202.12.12.12 counter meta mark set 0x64
    
    对应的luci操作,
    Network -> Firewall -> Traffic Rules -> 添加规则
    - General Settings
      - protocol: Any
      - Source Zone: Device (output)
      - Output Zone: Any zone
      - Destination address: 202.12.12.12
      - Action: XOR firewall mark
      - XOR mark: 100
    - Advanced Settings
      - Restrict to address family: IPv4 only
    - 其他内容: 默认/留空/不改变
    

    XOR mark 支持 "值/掩码"格式,比如 luci中写 "0x64/0xff" 表示 "meta mark set meta mark & 0xffffff64 | 0x64"

  • 测试, (op自身走wan2) (2025-12测)
    win中使用 tracert -d -w 1 202.12.12.12测试,数据走的是wan1
    op 中使用 traceroute -n -w 1 202.12.12.12测试,数据走的是wan2
    如果 "Destination address" 留空,那么op中的所有访问都走wan2,win依然走wan1
  • op中,添加防火墙规则, 0x64=100, (测试nft规则2)
    nft add rule inet fw4 mangle_prerouting iifname "br-lan" ip daddr 202.12.12.12 counter meta mark set 0x64
    
    对应的luci操作,
    Network -> Firewall -> Traffic Rules -> 添加规则
    - General Settings
      - protocol: Any
      - Source Zone: LAN
      - Destination Zone: Any zone
      - Destination address: 202.12.12.12
      - Action: XOR firewall mark
      - XOR mark: 100
    - Advanced Settings
      - Restrict to address family: IPv4 only
    - 其他内容: 默认/留空/不改变
    

    XOR mark 支持 "值/掩码"格式,比如 luci中写 "0x64/0xff" 表示 "meta mark set meta mark & 0xffffff64 | 0x64"

  • 测试, (lan口电脑走wan2) (2025-12测)
    win中使用 tracert -d -w 1 202.12.12.12测试,数据走的是wan2
  • op中, 删除上面(测试nft规则1,2)两条防火墙规则 ,只添加下面这两条, 对端 wg的端口是 udp/34567 udp/34568, ssh端口 tcp/22,
    规则中加入 tcp/22 是为了后续的测试。
    nft add rule inet fw4 mangle_output meta nfproto ipv4 udp dport { 34567, 34568 } counter meta mark set 0x64
    nft add rule inet fw4 mangle_output meta nfproto ipv4 tcp dport 22 counter meta mark set 0x64
    
    对应的luci操作,
    Network -> Firewall -> Traffic Rules -> 添加规则
    ----1----
    - General Settings
      - protocol: UDP
      - Source Zone: Device (output)
      - Output Zone: Any zone
      - Destination port: 34567 34568   #空格隔开的两个端口号
      - Action: XOR firewall mark
      - XOR mark: 100
    - Advanced Settings
      - Restrict to address family: IPv4 only
    - 其他内容: 默认/留空/不改变
    ----2----
    - General Settings
      - protocol: TCP (为了测试22端口)
      - Source Zone: Device (output)
      - Output Zone: Any zone
      - Destination port: 22
      - Action: XOR firewall mark
      - XOR mark: 100
    - Advanced Settings
      - Restrict to address family: IPv4 only
    - 其他内容: 默认/留空/不改变
    

    XOR mark 支持 "值/掩码"格式,比如 luci中写 "0x64/0xff" 表示 "meta mark set meta mark & 0xffffff64 | 0x64"

  • 测试 (2025-12测试成功, 有一点问题)
    op配置 wg连接外部的两台机器。wg通过 wan2 连接成功。
    win电脑走 wan1.
    op自身,连接 wg网段的22端口,wan2网段的22端口,失败。
  • 如果是debian,wg连接的配置中,可能需要在 [Interface] 中用 PostUp/PreDown, 把 wg 的路由写入到 table 100 中。
    也可以指定 wg自动添加的路由写入指定的table,比如在 [Interface] 中加一行 Table = 100
  • op中没找到配置PostUp/PreDown的方法,可能是通过"Import configuration"导入配置的办法,把PostUp/PreDown添加进去。
    op中可以指定 wg自动添加的路由指定写到 table 100。配置在"Advanced Settings->Override IPv4 routing table"。
  • 如果修改上面的"set mark"防火墙规则,删掉tcp/22端口的 nft规则,则只限定了两个udp口,影响不大,
    所以,不添加这个 table或PostUp/PreDown设置,也可以。

再添加一条路由规则

  • op中,添加路由规则
    ip rule add from all fwmark 100 lookup main suppress_prefixlength 0 pref 3001
    对应的luci操作,
    Network -> Routing -> IPv4 Rules -> 添加规则
    - General Settings
      - Priority: 3001
      - Route type: unicast   #默认值
      - Table: main
    - Advanced Settings
      - Firewall mark: 100
      - Prefix suppressor: 0
    - 其他内容: 默认/留空/不改变
    

    Firewall mark 支持 "值/掩码"格式,比如 luci中写 "0x64/0xff" 表示 "fwmark 0x64/0xff"

  • 测试, (2025-12测)
    op自身,连接 wg网段的22端口,wan2网段的22端口, 恢复正常。

wireguard FwMark

  • 对于debian系统,wireguard 本身就可以给 wg 的加密数据包打上 fwmark。
    如需配置,在 [Interface] 中加一行 FwMark = 0x64
    可以配置 wireguard 连接的 fwmark,而无需单独设置 "nft mangle set mark" 的防火墙规则。
    配合 ip route 和 ip rule 就可以实现,wg 加密数据包走 wan2,其他数据包走 wan1.
  • op中 luci界面 wireguard 配置的 fwmark 的位置在:
    Network -> Interfaces -> wg0的配置 -> Advanced Settings -> Firewall Mark。
    只是,仅支持固定值,比如 0x64。不支持 "值/掩码" 格式。
  • 如果使用 wireguard本身的 fwmark,就不需要在 PostUp/PreDown 中设置路由规则了。
  • 删除上面添加的防火墙规则 (所有的 nft set mark 规则)
  • op中 设置 wg的 fwmark 为 0x64。
    Network -> Interfaces -> wg0的配置 -> Advanced Settings -> Firewall Mark: 0x64
    重启 wg连接。
  • 测试 (2025-12测试成功)
    op配置的 wg通过 wan2 连接成功。
    win电脑走 wan1.
    op自身,连接 wg网段的22端口,wan2网段的22端口,正常。

总结

  • 默认的主路由表中,缺省default路由指向wan1
  • 配置几条 ip route 到 table 100。
    • 一条default路由指向wan2。(见下文)
      • 这条default路由,可以通过设置 wan2口的配置中 Advanced Settings->Override IPv4 routing table: 100
        wan2连接时自动写入 table 100。 而无需手动添加default路由到table 100。
    • 其他的路由,按需。
  • 配置两条 ip rule。
    • 包含mark的数据,指向 table main suppress_prefixlength 0。
    • 包含mark的数据,指向 table 100。(此条rule的优先级的,必须大于上一条rule; 注:值小的优先级高)
  • 配合, 任意一种 mark设置方法,或者两种方法都使用。
    • 防火墙规则 nft set mark。
      给需要走wan2的out数据包, 打上mark标记。
    • wireguard fwmark设置。
      配置 wg 的加密数据包, 打上mark标记。
  • 想办法删除 peer IP对应的静态路由。(见下文)
  • 即可实现 wg 走 wan2,其他走 wan1。(2025-12测)

DMZ设置

  • OpenWRT配置完全开放的DMZ主机
  • OpenWrt开启DMZ
  • luci操作
    Network -> Firewall -> Port Forwards -> 添加规则
    - General Settings
      - Restrict to address family: Auto 或者 ipv4 only
      - protocol: Any 或者 按需选择
      - Source Zone: wan
      - External port: 留空 或 1-65535
      - Destination Zone: lan
      - Internal IP address: <内网的dmz主机IP>
      - Internal port: 留空 或 1-65535
    - Advanced Settings
      - 保留默认值
    - 其他内容: 默认/留空/不改变
    
    这条dmz规则,必须是最后一条规则。否则它后面的规则都不生效。

wan2 override routing table

  • wan2 两种配置的对比。

  • 两种配置对比 (2025-12测)
  • 官方文档 default_routing_tables
  • wan2 的设置1

    - Advanced Settings
      - Use default gateway: no
      - Override IPv4 routing table: 留空
      - Override IPv6 routing table: 留空
    
    路由规则,显示为:
    0:      from all lookup local
    32766:  from all lookup main
    32767:  from all lookup default
    
    路由表 table main,显示为:
    default via 10.100.9.1 dev eth1    # wan1的缺省路由
    192.168.8.0/24 dev eth2 scope link src 192.168.8.8
    
    然后手工加入 wan2 的default 路由到table 100:
    ip route add default via 192.168.8.1 table 100
    
  • wan2 的设置2。(我选择使用这个设置)

    - Advanced Settings
      - Use default gateway: yes
      - Override IPv4 routing table:100
      - Override IPv6 routing table: 100
    
    路由规则,显示为:
    0:      from all lookup local
    10000:  from 192.168.8.8 lookup 100
    20000:  from all to 192.168.8.1/24 lookup 100
    32766:  from all lookup main
    32767:  from all lookup default
    90010:  from all iif lo lookup 100
    
    路由表 table 100,显示为:
    default via 192.168.8.1 dev eth2  src 192.168.8.8
    192.168.8.0/24 dev eth2 scope link
    
  • wg0 的也有同样的设置。
    - Advanced Settings
      - Use default gateway: 按需,我选择 no
      - Override IPv4 routing table: 留空 或 100,我选择 留空
      - Override IPv6 routing table: 留空 或 100,我选择 留空
    
  • 无论wan2 使用哪种配置,写路由表main 或 100。(我选择写table 100)
    无论 wg0 使用哪种配置,写路由表main 或 100。(我选择写table main)
    对于wg 所有对端 (peer)的 IP, 会在 table main中留下一个 静态路由指向wan1 的网关。
    例如:202.12.12.12 via 10.100.9.1 dev eth1
    并且 ip route flush cache清除不掉。
    需要自己写个脚本检查,如有则删除ip route del 202.12.12.12 via 10.100.9.1
    否则, wg加密数据包会走 wan1 (我的环境下,极不稳定)。(2025-12测)
    #!/bin/sh
    
    # 有时 wg启动失败, wg设备不存在, 只能重启解决.
    # 因为 wg链接的几个peer IP,生成了几个静态路由在 table main. 需要删除.
    
    logs=/root/task/log.check_route_wg.log
    cnt_file=/root/task/log.check_route.cnt
    
    check_route() {
      if [ "$2" = "ip" ];then
        local IP4="$1"
      else
        local IP4=$(dig "$1" a +short)
      fi
      local IP4_route=$(echo "$ROUTE_STAT"|grep "$IP4 via 10\.100\.9\.1")
      if [ -n "$IP4" -a -n "$IP4_route" ]; then
        echo $(date +%F_%T%z) route err: "$IP4_route" >> $logs
        ip route del $IP4 via 10.100.9.1
      fi
    }
    
    read  chkRoute  < $cnt_file
    # 路由器重启后,只执行5次。
    if [ $chkRoute -lt 6 ]; then
    
      # 检查wg是否启动失败
      WG_STAT=$(wg show interfaces)
      if [ -z "$WG_STAT" ]; then
        echo $(date +%F_%T%z) wg err >> $logs
        sync
        sleep 10
        reboot
      fi
    
      # 检查peer IP 的静态路由是否存在
      ROUTE_STAT=$(ip route show table main)
      check_route 202.12.12.12   ip
      check_route myddns.mydomain.com
    
      chkRoute=$(($chkRoute+1))
      echo $chkRoute  > $cnt_file
      sync
    fi
    
    把以上脚本checkRoute.sh 放入定时任务,每5分钟执行一次 */5 * * * * /bin/sh /root/task/checkRoute.sh
    然后在 /etc/rc.local 中加一行,echo "0" > /root/task/log.check_route.cnt 重置计数器。

其他

  • 关于"前缀抑制器 (Prefix suppressor)",

    • OpenWrt 下的策略路由
    • 前缀抑制器: 拒绝前缀长度小于或等于指定值的路由决策。
    • 比如,新建一个规则,让指定的主机先匹配 main 路由表,然后设置前缀抑制为 0,那么其意思就是不匹配 main 表中默认路由,但是匹配其他路由条目。因为默认路由的前缀长度(掩码长度)=0。
  • 如果 wg对端 IP写的是 ddns,记得在crontab中加入

    */3 * * * * /usr/bin/wireguard_watchdog
  • 如果有线网络是 IEEE802.1X 认证。

    需要设置 wan口 mac地址要 clone 认证机的 mac地址。不用设置 DMZ主机 (不要设置DMZ)。
  • 有时 wg启动失败,信息为wg设备不存在Error: Network device is not present。原因不明,重启整个op能恢复。(可能是op22的问题)
    所以, 需要自己写个脚本检查,如果wg没有启动, 则 reboot 系统。(2025-12测)

--end----


转载注明来源: 本文链接 https://chuna2.787528.xyz/osnosn/p/19309459.html
来自 osnosn的博客 https://chuna2.787528.xyz/osnosn/ .


posted on 2025-12-05 01:12  osnosn  阅读(82)  评论(0)    收藏  举报