25

NOTE: If client devices (computer B in this example) want to obtain internet through the gateway computer, maybe they still need to configure nameserver resolution. This is not explained here (a gateway does not necessarily serve internet).

I am trying to understand the fundamentals of networks routing.
So I am experimenting with my LAN (I don't need internet for now, just LAN communications).

I know the network configuration matters are a rather complex thing, but I am just trying to make a computer (say A) to act as a gateway for another (say B) (both running Ubuntu Linux).
I only need B to be capable to reach the router, that is only reachable for A.

This is the case:

Router for computer A  -->  192.168.0.1
Computer A - eth0      -->  192.168.0.2
Computer A - eth1      -->  192.168.1.1

Computer B - eth0      -->  192.168.1.2

Computer A connects fine to router.
Computer A and B connect fine (ping, SSH... etc) between them.
Computer B can not reach the router for computer A.

I was thinking that just adding on B Computer A as default gateway and activating IP Forwarding on A would make B to be able to reach the router for A:

luis@ComputerB:~$ sudo route add default gw 192.168.1.1
luis@ComputerB:~$ sudo routel

target            gateway      source        proto    scope  dev   tbl
127.0.0.0         broadcast    127.0.0.1     kernel   link   lo    local
127.0.0.0 8       local        127.0.0.1     kernel   host   lo    local
127.0.0.1         local        127.0.0.1     kernel   host   lo    local
127.255.255.255   broadcast    127.0.0.1     kernel   link   lo    local
192.168.1.0       broadcast    192.168.1.2   kernel   link   eth0  local
192.168.1.2       local        192.168.1.2   kernel   host   eth0  local
192.168.1.255     broadcast    192.168.1.2   kernel   link   eth0  local
default           192.168.1.1                                eth0
169.254.0.0 16                                        link   eth0
192.168.1.0 24                 192.168.1.2   kernel   link   eth0

And on Computer A (the intermediate gateway):

root@ComputerA:~$ echo 1 > /proc/sys/net/ipv4/ip_forward

Computer B can still ping computer A, but router for A does not answer:

luis@ComputerB:~$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
^C

(No ping response)

Is this the correct procedure to make a computer running Linux to act as a gateway for another computer in a simple manner?

0

2 Answers 2

39

You are almost there you just need to make sure traffic gets back to B. Right now you have forwarded traffic from B to the outside world but A doesn't know how to get traffic back to B. You need A to keep some state about the connections going through it. To do this you will want to enable NAT. You already have step one which is allow forwarding. Then you need to add a few firewall rules using iptables:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

This says: on the network address translation table, after we have figured out the routing of a packet on output eth0 (the external), replace the return address information with our own so the return packets come to us. Also, remember that we did this (like a lookup table that remembers this connection).

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

Allow packets that want to come from eth1 (the internal interface) to go out eth0 (the external interface).

iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT

Use that lookup table we had from before to see if the packet arriving on the external interface actually belongs to a connection that was already initiated from the internal.

4
  • A concise explanation, indeed. Must all the code blocks be executed on Computer A? Aug 9, 2015 at 4:51
  • 1
    @SopalajodeArrierez Yes these are all execued on the "gateway" computer. System B doesn't need to know anything about the routing other than if it want to reach any other machine, it send the packets to B (it's default GW). Aug 9, 2015 at 4:56
  • Tested working on Ubuntu v14 on desktop and Ubuntu v12 on Utilite Pro (an embedded evice from CompuLabs). Thanks you very much for expanding on what each line exactly does. I have researched and found many long-long-long explanations that were not working. I hope this Question-Answer thread could be useful for others in a future. Aug 9, 2015 at 5:09
  • 1
    @user1794469 is it the same when the gateway interface is virtual, i.e. a tap interface? can you have a look at here?
    – ram
    Jan 3, 2018 at 15:53
4

In order to have routing work correctly between two Linux computers acting as gateways, there are several things that need to be in place:

  • Both gateways need to have a physical link to each other (or virtual if you are linking virtual machines).
  • Routes must be added to both interfaces on the router.

    route add -net 192.168.0.0/24 gw 192.168.0.1
    route add -net 192.168.1.0/24 gw 192.168.1.1
    
  • A local gateway must be specified for the remote network on both gateways. This allows computers on the local network to know where to send packets for the remote network. The gateway should be the IP address of the computer that will send packets to the remote network.

  • Computers wishing to send traffic between the networks must also be made aware of what local gateway is handling traffic to and from the remote network. This is usually done via Dynamic Host Control Protocol (DHCP), however if you intend to use a separate gateway for the internet you will need to specify both on the computers needing access to both the Internet and the other network (e.g. the Internet gateway via DHCP and the other network's gateway via a route).
  • IP forwarding must be active for both gateways.
  • IP Masquerading must be enabled to allow NAT to function between the gateways.

    modprobe iptable_nat
    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    iptables -A FORWARD -i eth1 -j ACCEPT
    

    You may need to specify a source and destination since you are using the same interface for masquerading:

    iptables -t nat -A POSTROUTING -i eth0 -s 192.168.0.0/24 ! -d 192.168.1.0/24 -j MASQUERADE
    

    and the other gateway:

    iptables -t nat -A POSTROUTING -i eth1 -s 192.168.1.0/24 ! -d 192.168.0.0/24 -j MASQUERADE   
    

    For each gateway, the local network traffic should be accepted on the appropriate interface like this:

    iptables -A FORWARD -i eth0 -s 192.168.0.0/24 -j ACCEPT
    

    or

    iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT
    

There are numerous links and similar questions able to be referenced for solving the problems you are having.

What appears to be wrong in this particular case is that route and gateway setup is not complete on on both computers and Network Address Translation (NAT) has not been enabled using iptables, allowing the gateways to carry the request from a computer on the other subnet on their behalf.

Doing this is also critical when setting up an internet connection as you are responsible for one end of the connection (e.g. using a Linux computer as a gateway for a PPPoE connection).

You must log in to answer this question.

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