Is it possible to enable port isolation on Linux bridges?

8,499

Solution 1

you can try using ebtables and create own rules involving input/output bridge port.

i dont have server with bridge at hand but i'd do something like this:

ebtables -P FORWARD DROP
ebtables -F FORWARD
ebtables -A FORWARD -i $uplinkPort -j ACCEPT # let the traffic flow from uplink to any ports
ebtables -A FORWARD -o $uplinkPort -j ACCEPT # let the traffic flow from any ports to uplink

Solution 2

As requested by @pQd here's a working example for port isolation with VMs (here: based on Proxmox VE) when the host is the uplink and all VMs should be isolated from each other. I use this for an internal service network (DNS, Updates, etc). The bridge is vmbr1, the virtual Ethernet devices are vethNNN.1 (where NNN is the VID). If you only want isolation, this should be enough:

ebtables --append FORWARD --logical-in vmbr1 --jump DROP

If multiple bridges are to be configured and other VMs should be Uplinks as well (here: veth100.1 and veth102.1), something like this is more appropriate (untested):

for br in $(seq 0 1); do
    br=vmbr$br
    ebtables --new-chain $br
    ebtables --policy $br DROP
    ebtables --append FORWARD --logical-in $br --jump $br
done
for if in 100.1 102.1; do
    br=vmbr$(echo $if | cut -d. -f2)
    if=veth$if
    ebtables --append $br --in-if $if
    ebtables --append $br --out-if $if
done

If the host shouldn't be an uplink, this should work (I didn't try it as well though):

ebtables --append INPUT --logical-in vmbr1 --jump vmbr1
ebtables --append OUTPUT --logical-out vmbr1 --jump vmbr1

Solution 3

Since this question was asked (in 2012), a newer method became available (in 2018) with Linux kernel >= 4.18 and related recent enough iproute2 tools: bridge port isolation.

It's described in KernelNewbies for Linux 4.18:

  • bridge: add support for port isolation. Isolated ports cannot communicate between each other, but they can still communicate with non-isolated ports commit

If an interface, (typically named tapX for a VM or vethX for a container) has been set as bridge port of a bridge named bridge0 like this:

# ip link set dev tap0 master bridge0

one can set it isolated with the bridge command like this:

# bridge link set dev tap0 isolated on

this won't have any visible effect until at least a second port of the same bridge is also isolated:

# bridge link set dev tap1 isolated on

Now the bridge ports tap0 and tap1 won't be able to send or receive any packet to or from the other port, but will still communicate normally with any other port of the bridge. You can choose to isolate all ports except one, used in the role of default promiscuous/uplink port.

Notes:

  • as described in the commit, it's per port. If there are multiple VLANs on an isolated bridge port, all are affected,
  • it's not clear if the bridge's self interface (bridge0 here) can be isolated itself (even with the correct syntax: appending the self keyword when the device is the bridge name itself),
  • All newer advanced features available through (rt)netlink with the ip link and bridge commands have no equivalent through the older ioctl API, so brctl can't be used for this.
Share:
8,499

Related videos on Youtube

mss
Author by

mss

Updated on September 18, 2022

Comments

  • mss
    mss almost 2 years

    On most managed switches you can enable Layer 2 Port Isolation. The implementation and terminology is different from vendor to vendor but generally speaking you keep one or more ports in the default Promiscuous (Cisco) or Uplink (HP) state and configure other ports as Isolated (Cisco) or Private (HP). Afterwards, isolated ports can only talk to promiscuous ones but not to each other.

    Is there any way to implement this with Linux bridges to eg. isolate VMs from each other? Maybe via ebtables?

    • mss
      mss about 12 years
      I just learned that this is also called a Private VLAN and defined in RFC 5517.
  • mss
    mss about 12 years
    That's what I thought (cf. last sentence of my question) but I have no clue how to do this... well, that's a lie, I googled a bit since I asked that question and might have found a solution but haven't tried it yet. Anybody posting working ebtables rules is welcome :)
  • pQd
    pQd about 12 years
    i've added something that maybepossibly should work. feedback is welcome.
  • mss
    mss about 12 years
    You pointed me to the right direction. For the (common) simple case where you've got a virtual bridge like vmbr0 and want to isolate all VMs from each other, a simple ebtables -A FORWARD --logical-in vmbr0 -j DROP on the host is enough. If you want to define other VMs as uplinks as well, you should instead jump to an extra chain with the policy DROP. There you can add rules eg. based on the interfaces (remember to add both -i and -o rules though).
  • pQd
    pQd about 12 years
    @mss could you post your whole config - either at pastebin.com or here as separate answer. thx.