如何让数据包的入接口和出接口一致?

如何让数据包的入接口和出接口一致?

我的服务器有两个接口。

第一个接口直接连接到本地 ISP,第二个接口通过 GRE 隧道连接到其他区域。

看起来是这样的:

┌──────────────────┐ ────────────────── ISP 1
│ Server (x.x.x.1) │ 
└──────────────────┘ ─── GRE Tunnel ─── ISP 2

每个 ISP,我们都宣布相同的前缀(任播),因此每个接口都有相同的 IP 地址。(xxx1)我们的默认路由是 ISP 1,因此目前,所有流量都路由到 ISP 1(接口 1),无论传入接口是接口 1 还是接口 2。
我想对其进行配置,以便从接口 1 进入的数据包通过接口 2 发送出去,从接口 2 进入的数据包通过接口 2 发送出去。(就像负载均衡器中的粘性会话)

我们的操作系统是 CentOS 7。有什么方法可以配置吗?我尝试从 ISP 2 导入路由表并覆盖与 ISP 2 路由表匹配的 ISP 2 路由,但失败了,因为 ISP 2 的路由表不对称。(所以我将数据包发送到 ISP 1,但它从 ISP 2 返回。)

答案1

为了传出回复传入的请求,您可以设置策略路由:

  1. 将每个 ISP 的默认路由导入到单独的内核路由表中。

    例如,在《Bird》中:

    ipv4 table ispone4;
    
    protocol bgp 'ispone' {
        ipv4 {
            table ispone4;
            igp table master4;
            [...]
        };
    };
    
    protocol kernel 'krt_ispone4' {
        ipv4 {
            table ispone4;
        };
        kernel table 10;
    };
    
  2. 创建策略路由规则(例如通过ip rule)以根据数据包标记(又名 fwmark)使用内核表:

    ip -4 rule add fwmark 0x10 lookup 10
    

    例如,在 systemd-networkd 中:

    [RoutingPolicyRule]
    Family=both
    Priority=501
    FirewallMark=82
    Table=82
    
  3. 创建 iptables 或 nftables 规则,根据到达的接口标记传入的数据包,并将数据包标记存储为连接跟踪标记对于传入数据包,并从 conntrack 中恢复传出的数据包。

然而,这对传入回复服务器自己发出的请求(例如 DNS 查询)。避免非对称路由的唯一可靠方法是不通告相同的前缀通过两个 ISP。

相关内容