Score:0

Routing one machine's traffic through GRE tunnel to a remote NAT

vn flag

I had to solve the following dilemma for a friend and thought I'd document how we did it here...

Here's the situation:

  • His home network 192.168.1.0/24 and it sits behind a Linux router that performs NAT and has public IP address A.A.A.A. The Linux router runs openSUSE 15.3.
  • On the home network there is one particular device of interest at address 192.168.1.17.
  • He has a remote Linux machine that sits by itself on the Internet at address B.B.B.B. This machine is a hosted server and lives in another part of the country. This machine also runs openSUSE 15.3.

What he wants is for all of 192.168.1.17's traffic to be routed through, and NAT'd by, the remote machine B.B.B.B, but for all the other machines on the home network to be unaffected (i.e., still routed through the home router A.A.A.A as usual).

The effect is that to the outside world all of 192.168.1.17's traffic will appear to be coming from B.B.B.B instead of A.A.A.A.

This as the NAT/networking equivalent of "throwing your voice" for one particular machine on your network.

Score:0
vn flag

Here's how we did this.

We set up a GRE tunnel between A.A.A.A and B.B.B.B (interface gre1 on both servers), with internal point-to-point tunnel IP addresses 10.0.0.1 and 10.0.0.2 (respectively). Note there's no need for encryption because the packets in the tunnel are just going to be unwrapped and sent over the Internet as-is anyway.

Next, we have to configure B.B.B.B to enable NAT on its external interface eth0. This is done via firewalld. We then have to add a custom rule to firewalld to not block the incoming GRE packets. We put the gre1 interface into the trusted zone so all of the packets arriving inside the tunnel are allowed, and will get NAT'd.

On the home network, we were already setup via firewalld as a NAT router so the only things left to do were (a) create the other side of the GRE tunnel, and (b) make Linux divert 192.168.1.17's outgoing traffic into the tunnel. This last step is the slightly tricky part.

Details below...

Setup on B.B.B.B (Remote Server)

Add interface gre1:

    # /etc/sysconfig/network/ifcfg-gre1
    STARTMODE='onboot'
    BOOTPROTO='static'
    TUNNEL='gre'
    TUNNEL_LOCAL_IPADDR='B.B.B.B'
    TUNNEL_REMOTE_IPADDR='A.A.A.A'
    IPADDR='10.0.0.2'
    REMOTE_IPADDR='10.0.0.1'
    TUNNEL_TTL='64'
    ZONE=trusted

Add route to home network and remote side of P2P link via gre1:

    # /etc/sysconfig/network/ifroute-gre1 
    # Destination   Gateway     Netmask     Interface   Options
    192.168.1.0/24  -           -           -
    10.0.0.1        -           -           -

Configure firewalld via yast2 firewall

  • Put interface eth0 in zone external
  • Put interface gre1 in zone trusted
  • Add a custom firewall rule to zone external allowing incoming GRE packets from A.A.A.A
  • Add custom firewall rules to clamp TCP MSS to both external and trusted zones (requires firewalld >= 1.0.0)

Zone files in /etc/firewalld/zones:

    # /etc/firewalld/zones/external.xml    
    <zone>
        <short>External</short>
        <service name="ssh"/>
        ...
        <masquerade/>
        <rule family="ipv4">
          <source address="A.A.A.A"/>
          <accept/>
        </rule>
        <rule>
          <tcp-mss-clamp value="1420"/><!-- requires firewalld >= 1.0.0 -->
        </rule>
        <interface name="eth0"/>
    </zone>
    # /etc/firewalld/zones/trusted.xml    
    <zone target="ACCEPT">
      <short>Trusted</short>
      <description>All network connections are accepted.</description>
      <rule>
          <tcp-mss-clamp value="1420"/><!-- requires firewalld >= 1.0.0 -->
      </rule>
      <interface name="gre1"/>
    </zone>

Setup on A.A.A.A (Home Network Server)

This assumes that A.A.A.A is already setup to NAT the 192.168.1.0/24 network, etc.

Add interface gre1:

    # /etc/sysconfig/network/ifcfg-gre1
    STARTMODE='onboot'
    BOOTPROTO='static'
    TUNNEL='gre'
    TUNNEL_LOCAL_IPADDR='A.A.A.A'
    TUNNEL_REMOTE_IPADDR='B.B.B.B'
    IPADDR='10.0.0.1'
    REMOTE_IPADDR='10.0.0.2'
    TUNNEL_TTL='64'
    ZONE='trusted'

Add route to remote side of P2P link via gre1:

    # /etc/sysconfig/network/ifroute-gre1 
    # Destination   Gateway     Netmask     Interface   Options
    10.0.0.2        -           -           -

Configure firewalld via yast2 firewall:

  • Put interface gre1 in zone trusted
  • Interface eth0 should already be in zone external

Activating The Rerouting

This is the final "tricky part" which causes 192.168.1.17's outbound traffic to be diverted through the GRE tunnel.

To turn on the redirection, run these commands on A.A.A.A:

$ ip route flush table 10
$ ip route add table 10 to default via 10.0.0.2 dev gre1
$ ip rule add from 192.168.1.17 table 10 priority 10

To undo the above commands:

$ ip rule del from 192.168.1.17 table 10 priority 10
$ ip route flush table 10
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.