Solved Interaction of Linux LAN members with OpenVPN clients across FreeBSD bridged tap

Hi all,

I've got OpenVPN running in bridged mode (with the "--dev tap" and "--server-bridge" options enabled) on a homemade FreeBSD 13.0 router.
When I attempt to ssh TO one of the OpenVPN clients from one of the non-clients inside my LAN, it works and it doesn't.

If the connection originates from BSD-based systems (MacOS, FreeBSD, and FreeNAS) or Win10 systems, I have no problems.
If the system is running a recent Linux kernel, I have problems.

ICMP and UDP work fine but when I sniff a TCP connection attempt from my various Linux machines (Arch, Manjaro, Debian, etc.), I see:
  • A SYN sent to the MAC address of the OpenVPN client's tap interface,
  • A SYN+ACK sent from the MAC address of the FreeBSD bridge interface, and
  • A RST sent to the MAC address of the OpenVPN client's tap interface.
On the other hand, my BSD-based and Win10 systems send an ACK and not a RST as the final step of the three-way handshake and complete the connection.
SSH is just one example. It seems any TCP service will exhibit the same behavior, wholly contingent on whether the originating system is running Linux or not.

I would surmise that modern Linuxen verify the MAC addresses of response frames to ensure that they are coming from expected hosts and refuse them if they do not.

It seems to me that the bridge may be misconfigured on the router.
It doesn't make sense to me that my LAN clients should ARP the MAC address of the OpenVPN client (and not the bridge) yet get the MAC address of the bridge (and not the OpenVPN client) when frames are returned.
Is that the correct and expected behavior?
Is there a way to pass through link-layer frames so that the source MAC address remains unaltered?
Or would I want to have OpenVPN alter the ARP table on the router so that the IP address of the OpenVPN client gets associated with the MAC address of the bridge? (I wouldn't think so, but if so, how can I accomplish that?)

The only other option I can think of is to disable the MAC verification feature on each Linux machine in my LAN. I've asked on the ArchLinux Forums how to do this and so far gotten no response.

Do I have any other options?
 
Aha! When I sniff the bridge interface, I see what is really happening.

Response frames from the OpenVPN client are being sent to the router's bridge MAC and then the router fires a new frame from the bridge MAC to the LAN machine MAC.
I have 2 OpenVPN clients set up thus far and only one of these clients is doing this.
The other client will generate response frames with the LAN machine MAC as the destination MAC from the get-go.
Therefore, my hypothesis is that this is an OpenVPN configuration issue and nothing to do with FreeBSD.

I will investigate and pass this on to the OpenVPN Forums if necessary.
 
If anyone is interested, the solution was to remove push "route lan_addr lan_netmask router_ip" from the OpenVPN server-side client config that was exhibiting the behavior.
The client still configures a route to the LAN, but instead of it being "lan_addr/cidr via router_ip dev tap0" it is "lan_addr/cidr dev tap0 proto kernel scope link src client_ip".

I suspect (but have not confirmed) that any LANs that the router knows about will also automaticaly be passed along to clients and if any are explicitly pushed, response frames to those LANs will experience the behavior I described in the first post of this thread.
 
Back
Top