MikroTik Solutions

Bridged Container VETH
Login

Motivation

The recommended container networking setup in MikroTik’s docs has you putting your containers on a separate subnet and then setting up a source NAT scheme to convert those in-container IP addresses to LAN-side addresses. This has a number of downsides:

  1. NAT has inherent issues and limitations.

  2. If the container host is a router, it may have another NAT layer above this, which then means that if the container is exposed to the outer network (e.g. port-forwarded to the Internet) you’ve likely bought yourself one or more of the common double NAT problems.

  3. NAT takes a tiny amount of processing power to manage. Your RouterOS device and configuration may allow it to be hardware-offloaded, but even then, there are cases where we want zero overhead, as when the container is running a speed test program.

Given this list, you may be wondering why MikroTik recommends that you put a container’s veth behind NAT in the first place?

It’s my belief that it is because Docker does this,1 and although RouterOS’s container feature is not based on any Docker code, they’ve mimicked this aspect of its design without considering whether that makes sense on a router or a switch, where we have complete control over the local network design. The NAT default on Docker has better justification since it is running on a desktop or server computer with a preexisting network setup, and they want it to “just work” out of the box.

That logic may play to some extent as a RouterOS container default, but it is my opinion that if you’re going to run a container on a router or a switch, you’d best be thinking about network configuration details regardless.

Solution

The alternative is simpler to configure and doesn’t have any of these problems:

$ ssh myrouter
> /interface/veth
  add address=192.168.88.2/24 gateway=192.168.88.1 name=veth1
> /interface bridge port
  add bridge=bridge1 interface=veth1

That is, we put veth1 directly on the bridge, giving it an IP in the same scheme as the rest of the bridged ports. We’re using RouterOS’s default LAN-side IP scheme of 192.168.88.0/24 for the purposes of this example, but it can be anything you like.

Consequences

I’m aware of only one downside to this scheme, which falls out of the fact that each veth interface gets a random MAC address each time it starts up. If you run that bridge in auto-mac mode, there’s a chance on each reboot that the OS will choose to give this random MAC to the bridge, because auto-mac apparently uses the lowest-numbered MAC available, meaning you can never reliably predict whether the VETH will even be the bridge MAC, much less what that MAC will be.

That in turn can play havoc with configurations requiring a predictable MAC address, such as when assigning device IPs with static DHCP reservations.

If you’re going to put veth interfaces on the bridge, I recommend turning off its auto-mac setting.

License

This work is © 2024 by Warren Young and is licensed under CC BY-NC-SA 4.0


  1. ^ …evidenced by their use of 172.17.0.0/24 for this, a subset of Docker’s default NAT IP scheme.