0

My server has two interfaces.

First interface is directly connected to local ISP and second interface is connected to other region that connected with GRE tunnel.

So it looks like:

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

Each ISP, we announce same prefix(anycast) so each interface has same IP address. (x.x.x.1) Our default route is ISP 1, so currently, all traffic is routed to ISP 1(Interface 1), regardless of incoming interface is Interface 1 or Interface 2.
I want to configure it so that packets coming in from Interface 1 are sent out through Interface 2, and packets coming in from Interface 2 are sent out through Interface 2. (Like sticky session in load balancer)

Our operating system is CentOS 7. Is there any way to configure this? I tried to import route table from ISP 2 and override route to ISP 2 that matches ISP 2 route table, but it failed, because ISP 2's route table is asymmetric. (So I sent packet to ISP 1 but it returns from ISP 2.)

5
  • Asymmetric routing is fairly normal in such situations. What problems did it cause? Commented Mar 14, 2023 at 7:00
  • @user1686 Each ISP operates a stateful firewall at the top (beyond our control). If traffic becomes asymmetric, the firewall at each end cannot determine the state and will drop the packet. Commented Mar 14, 2023 at 7:55
  • That sounds… a bit stupid to be honest; why would they have a stateful firewall for multi-homed customers? "Sticky sessions" can only solve this halfway – what will happen when you make an outbound connection and the remote host's replies arrive to you through a different ISP? Commented Mar 14, 2023 at 8:04
  • Your question makes little sense. What is the server doing if you are wanting to push traffic from ISP1 to ISP2? Did you mean packets coming in from Interface 1, or replies to packets which came in from Interface 1? Regardless, if your ISPs are operating stateful firewalls you can't fix this on your router.
    – davidgo
    Commented Mar 14, 2023 at 8:14
  • @user1686 I know it's a stupid configuration. The purpose of our configuration is to build a multi-homed network for DDoS defense. Since network fees in Korea are quite expensive, Remote DDoS Protection providers often do not build Korean PoPs, so we use a Remote DDoS Protection provider (ISP 2) and a Local ISP (ISP 1) for Korean communication. Commented Mar 15, 2023 at 3:04

1 Answer 1

0

For outgoing replies to incoming requests, you can set up policy routing:

  1. Import default routes from each ISP into separate kernel routing tables.

    For example, in Bird:

    ipv4 table ispone4;
    
    protocol bgp 'ispone' {
        ipv4 {
            table ispone4;
            igp table master4;
            [...]
        };
    };
    
    protocol kernel 'krt_ispone4' {
        ipv4 {
            table ispone4;
        };
        kernel table 10;
    };
    
  2. Create policy routing rules (e.g. via ip rule) to use the kernel tables depending on the packet mark (aka fwmark):

    ip -4 rule add fwmark 0x10 lookup 10
    

    For example, in systemd-networkd:

    [RoutingPolicyRule]
    Family=both
    Priority=501
    FirewallMark=82
    Table=82
    
  3. Create iptables or nftables rules that would mark incoming packets depending on the interface they arrive on, and would store the packet mark as conntrack mark for incoming packets, and restore it from conntrack for outgoing ones.

However, this will do absolutely nothing for incoming replies to the requests that your server has made on its own (e.g. DNS queries). The only reliable way to avoid asymmetric routing there is to not advertise the same prefix through both ISPs.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .