Linux – Host unreachable if eth0 has no IPv4 in ethernet bridge

bridgeethernetlinuxopenvpnvpn

I am currently attempting to configure an ethernet bridging VPN with the use of OpenVPN. However, whenever I am trying to setup the ethernet bridge, the server (Raspberry Pi) looses connection from the internal network. I am using the following script to initialize my ethernet bridge

#!/bin/bash
# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
eth="eth0"
eth_ip="192.168.144.200"
eth_netmask="255.255.255.0"
eth_broadcast="192.168.144.255"
eth_gateway="192.168.144.1"
eth_mac="B8:27:EB:48:6D:E3"


# Define Bridge Interface
br="br0"

# Define list of TAP interfaces to be bridged together
tap="tap0"

#################################
# Set up Ethernet bridge on Linux
# Requires: bridge-utils
#################################

for t in $tap; do
    openvpn --mktun --dev $t
done

brctl addbr $br
brctl addif $br $eth

for t in $tap; do
    brctl addif $br $t
done

for t in $tap; do
    ifconfig $t 0.0.0.0 promisc up
    iptables -A INPUT -i $t -j ACCEPT
done

iptables -A INPUT -i $br -j ACCEPT
iptables -A FORWARD -i $br -j ACCEPT

ifconfig $eth 0.0.0.0 promisc up
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
ip link set $br address $eth_mac
dhclient $br
ifconfig $br promisc up
route add default gw 192.168.144.1

After debugging the entire story I figured out that the

ifconfig $eth 0.0.0.0 promisc up

results in a connection loss.
The interface config after bridging is

br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.144.200  netmask 255.255.255.0  broadcast   192.168.144.255
    inet6 fe80::7b9:e278:843e:6f22  prefixlen 64  scopeid 0x20<link>
    ether b8:27:eb:48:6d:e3  txqueuelen 1000  (Ethernet)
    RX packets 147  bytes 23549 (22.9 KiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 155  bytes 75012 (73.2 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
    inet6 fe80::3abb:5937:1299:3dc5  prefixlen 64  scopeid 0x20<link>
    ether b8:27:eb:48:6d:e3  txqueuelen 1000  (Ethernet)
    RX packets 1590  bytes 208685 (203.7 KiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 1422  bytes 314068 (306.7 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    inet 127.0.0.1  netmask 255.0.0.0
    inet6 ::1  prefixlen 128  scopeid 0x10<host>
    loop  txqueuelen 1000  (Local Loopback)
    RX packets 18  bytes 1244 (1.2 KiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 18  bytes 1244 (1.2 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tap0: flags=4355<UP,BROADCAST,PROMISC,MULTICAST>  mtu 1500
    ether 5e:f6:5f:df:6b:10  txqueuelen 100  (Ethernet)
    RX packets 0  bytes 0 (0.0 B)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 0  bytes 0 (0.0 B)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.144.150  netmask 255.255.255.0  broadcast 192.168.144.255
    inet6 fe80::9cd2:30b9:74fc:c92d  prefixlen 64  scopeid 0x20<link>
    ether b8:27:eb:1d:38:b6  txqueuelen 1000  (Ethernet)
    RX packets 366  bytes 111524 (108.9 KiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 156  bytes 30687 (29.9 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Any ideas how to solve this issue? Typically only the bridge interface should have an IP Address. But if I don't assign an IP address to eht0 the terminal connection aborts and I can't connect anymore.

Note: I already checked iptables and net.ipv4.ip_forward is set to 1.

Best Answer

This is how I managed to keep the connection up and running.

I used a script because I was connected remotely via eth0 - shutting it down would have caused the connection to close.

The changes I made, in comparison to the script in the question, were 1st to ensure that the DHCP service is not running to prevent it from (re-)assigning an IP address to eth0 and 2nd to flush eth0 to remove the addresses.

# Define Bridge Interface
br="br0"

# Define list of TAP interfaces to be bridged,
# for example tap="tap0 tap1 tap2".
tap="tap0"

# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
eth="eth0"
eth_ip="192.168.178.20"
eth_netmask="255.255.255.0"
eth_broadcast="192.168.178.255"
eth_gateway="192.168.178.1"

for t in $tap; do
  openvpn --mktun --dev $t
done

brctl addbr $br
brctl addif $br $eth

# Stop dhcpcd if running
systemctl stop dhcpcd

for t in $tap; do
  brctl addif $br $t
done

for t in $tap; do
  ifconfig $t 0.0.0.0 promisc up
done

#ip addr del $eth_ip dev $eth
ip addr flush dev $eth

ifconfig $eth 0.0.0.0 promisc up

ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
route add default gw $eth_gateway $br


for t in $tap; do
  ifconfig $t up
done
ifconfig $br up

Depending on your firewall rules (whether you have an active firewall), you might want to set the rules accordingly (as above).