Ubuntu – Correct way to route between 2 interfaces with netplan in Ubuntu 18.04

18.04dhcpip-forwardnetplannetworking

Problem and Network Configuration

I am currently trying to allow communication between two interfaces, each with their own subnet, in Ubuntu 18.04 server using netplan but I am having a difficult time getting the configuration correct. Here is a graphical representation of what the network looks like:

Image of Network Layout


Network Explanation

In the image the center yellow device is a DHCP server for the clients on the left using the enp8s0 interface with static ip 192.168.254.254 and subnet mask of 255.255.255.240. The clients (orange boxes) get their ip from the DHCP server. Each client is also hosting a webpage via Nginx. All these devices are running Ubuntu 18.04 server. The addresses possibly changing on each client machine is not a concern.

On the right side, the yellow "server" has interface enp7s0 configured with a static ip of 172.16.0.1 and subnet mask of 255.255.255.252. This interface is then connected to my laptop that has its interface set to 172.16.0.2 with the same subnet mask.


Overall Goal

What I am trying to do is be able to view the website at any one of the clients from my laptop. There is no need for connection to the internet on any of these machines and all connections are done over ethernet cables.


Current Configuration

Netplan:

Yellow "server" netplan config file:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp7s0:
      addresses: [172.16.0.1/30]
      gateway4: 172.16.0.1
      routes:
        - to: 192.168.254.240/28
          via: 172.16.0.1
          on-link: true
    enp8s0:
      addresses: [192.168.254.254/28]
      gateway4: 192.168.254.254
      routes:
        - to: 172.16.0.0/30
          via: 192.168.254.254
          on-link: true

IP Forwarding:

The line net.ipv4.ip_forward=1 is uncommented in the /etc/sysctl.conf file.

Running cat /proc/sys/net/ipv4/ip_forward returns 1.

DHCP Server:

I have set INTERFACESv4 equal to enp8s0 in /etc/default/isc-dhcp-server.

Lastly, my /etc/dhcp/dhcpd.conf is configured as follows:

# option definitions common to all supported networks...

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# So DHCP server knows of other subnet
subnet 172.16.0.0 netmask 255.255.255.252 {
}

# DHCP server subnet
subnet 192.168.254.240 netmask 255.255.255.240 {
  range 192.168.254.241 192.168.254.253;
  option subnet-mask 255.255.255.240;
  option routers 192.168.254.254;
  option broadcast-address 192.168.254.255;
  default-lease-time 600;
  max-lease-time 7200;
}

Best Answer

I would not be using routes to try and route traffic properly between the two subnets. You might end up in a routing loop that'll break things.

What you should probably consider doing is actually making your system behave as a router and do all the forwarding with NAT. A quick and simple way to do this is to have NAT MASQUERADE on each of the interfaces. (But you'll also need to yank out the route rules you have in place, since they won't work properly.)

You need to add rules to the firewall that would handle the following cases:

  • 192.168.254.240/28 -> 172.16.0.0/30
  • 172.16.0.0/30 -> 192.168.254.240/28

With iptables you'd need to set it up like so (the commented lines with # at the beginning just explain what each rule does):

# Allow traffic to be forwarded from enp7s0 to enp8s0
iptables -A FORWARD -i enp7s0 -j ACCEPT
# Allow traffic to be forwarded from enp8s0 to enp7s0
iptables -A FORWARD -i enp8s0 -j ACCEPT

You also need to set up NAT rules, and this is not going to be very nice, but we have to let the 'router' be the one that we masquerade sources as.

iptables -t nat -A POSTROUTING -o enp7s0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o enp8s0 -j MASQUERADE

This should permit bidirectional NAT traversal between the subnets. Make sure you save these rules though for the future.

Let me know if this doesn't work, I'll go and dig into the issue more deeply if that happens.