You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于策略的路由配置求助:Arch Linux路由器VPN分流需求

嘿,我刚好折腾过一模一样的Arch Linux路由器+OpenVPN客户端的场景,太懂你这种“想让部分动态多变的IP/域名绕开VPN,但硬写静态路由根本赶不上IP变化”的头疼了!给你几个我亲自验证过的实用方案,一步步来就能搞定:

方案1:用ipset + iptables 动态管理绕开VPN的IP集合

ipset是个能动态维护IP/子网集合的工具,完美解决静态路由的局限性:

  • 先装依赖:
    sudo pacman -S ipset iptables
    
  • 创建一个名为bypass_vpn的IP集合(用hash:net类型支持单个IP和子网):
    sudo ipset create bypass_vpn hash:net
    
  • 配置iptables规则,给这个集合里的目标IP打标记,然后让标记过的流量走原来的非VPN路由表(假设你的VPN接口是tun0,默认所有流量走tun0):
    # 给目标IP在bypass_vpn里的流量打标记100
    sudo iptables -t mangle -A PREROUTING -m set --match-set bypass_vpn dst -j MARK --set-mark 100
    # 让带标记100的流量优先走main路由表(也就是物理网卡的默认路由)
    sudo ip rule add fwmark 100 table main priority 100
    
  • 动态添加/删除IP非常方便:
    • 加单个IP:sudo ipset add bypass_vpn 8.8.8.8
    • 加子网:sudo ipset add bypass_vpn 192.168.0.0/24
    • 删除IP:sudo ipset del bypass_vpn 8.8.8.8
  • 配置开机自动加载:
    1. 保存ipset规则:sudo ipset save > /etc/ipset.conf
    2. 新建一个systemd服务文件/etc/systemd/system/ipset-restore.service:
      [Unit]
      Description=Restore ipset rules on boot
      Before=network.target
      
      [Service]
      Type=oneshot
      ExecStart=/usr/sbin/ipset restore -f /etc/ipset.conf
      ExecStop=/usr/sbin/ipset destroy
      RemainAfterExit=yes
      
      [Install]
      WantedBy=multi-user.target
      
    3. 启用服务:sudo systemctl enable --now ipset-restore.service
    4. 保存iptables规则:sudo iptables-save > /etc/iptables/iptables.rules,然后启用iptables服务:sudo systemctl enable --now iptables.service
方案2:结合DNS自动把域名解析的IP加入集合(应对动态IP域名)

如果你的目标是经常换IP的域名(比如某些流媒体、云服务),用dnsmasq自动把解析到的IP加入ipset,完全不用手动管:

  • 装dnsmasq:sudo pacman -S dnsmasq
  • 编辑/etc/dnsmasq.conf,添加你要绕开VPN的域名(支持通配符):
    # 把example.com及其所有子域名解析到的IP自动加入bypass_vpn集合
    ipset=/example.com/*.example.com/bypass_vpn
    
  • 把系统DNS改成dnsmasq的本地地址:编辑/etc/resolv.conf,把nameserver改成127.0.0.1(如果用systemd-resolved的话,需要调整配置让它用dnsmasq,不过直接改resolv.conf更简单)
  • 重启dnsmasq:sudo systemctl restart dnsmasq
    这样每次解析这些域名时,对应的IP会自动被加入bypass_vpn,IP变了也不用手动更新,太省心了!
方案3:用nftables替代iptables(更现代的选择)

如果你已经在使用nftables(Arch现在默认推荐这个),可以用它自带的集合功能,步骤更简洁:

  • 创建一个动态IP集合:
    sudo nft add set inet filter bypass_vpn { type ipv4_addr; flags dynamic; }
    
  • 添加规则给集合里的IP打标记:
    # 给局域网进来的流量打标记
    sudo nft add rule inet filter prerouting ip daddr @bypass_vpn meta mark set 100
    # 给路由器自身的输出流量打标记
    sudo nft add rule inet filter output ip daddr @bypass_vpn meta mark set 100
    
  • 同样添加ip rule让标记流量走main表:
    sudo ip rule add fwmark 100 table main priority 100
    
  • 保存nftables配置并开机启用:
    sudo nft list ruleset > /etc/nftables.conf
    sudo systemctl enable --now nftables.service
    
  • 动态添加IP:sudo nft add element inet filter bypass_vpn { 8.8.8.8 }
几个关键注意事项
  • 确保你的OpenVPN客户端配置里有redirect-gateway def1(你说所有流量都走VPN,应该已经加了),这个配置会把默认路由指向tun0,而我们的标记规则优先级更高,所以能让指定流量绕开
  • 测试的时候用traceroute 目标IP看看,第一跳如果是你的网关而不是VPN服务器的IP,就说明配置成功了
  • 如果需要支持IPv6,要对应创建IPv6类型的集合,规则里换成ip6 daddr

内容的提问来源于stack exchange,提问作者archie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:16:04