I am setting up a bridge that will connect two or more disjoint physical networks in the single shared "ethernet space" (e.g. I want everything to work like it is plugged into one Ethernet switch). Both of my networks will be behind NAT and therefore I am setting up server in the cloud with the public IP that will accept connections from the clients (which will have further bridged tap0 and eth0 interfaces but I am not there yet).
EDIT (reason): I need working broadcast across client sites. It will significantly reduce the complexity of everything else people will do on these sites. (/EDIT).
Now, I figured out TAP bridging over VPN, I did it according to OpenVPN tutorial on bridging, (https://openvpn.net/community-resources/ethernet-bridging/). I have bridge-start and bridge-stop scripts on both two client testing nodes and the server. I dumbed-down the setup to 3 fixed private IPV4 IPs:
server: bridge br0 (one interface, tap0) 192.168.104.2 client1: bridge br0 (one interface, tap0) 192.168.104.3 client2: bridge br0 (one interfacem, tap0) 192.168.104.5
I can start the openvpn server, and client connects. After, I can nicely ping server from one client. Or the other client. BUT. In my configuration, the server accepts only one connection from the client that connects first! The second connection times out and server does not even print out a detected "connection" attempt (I used UDP for OpenVPN).
To me it looks like peer2peer mode of the server. Now, I dug myself even deeper in the OpenVPN reference, and I found the following:
Starting with OpenVPN 2.0, a multi-client TCP/UDP server mode is supported, and can be enabled with the --mode server option. In server mode, OpenVPN will listen on a single port for incoming client connections. All client connections will be routed through a single tun or tap interface.
Then further on, for bridging:
--server-bridge ['nogw'] A helper directive similar to --server which is designed to simplify the configuration of OpenVPN's server mode in ethernet bridging configurations.
Of course I use "server-bridge" directive in my server config. Note that the docs here don't say anything about "multi-client" mode! Now, my quesion: is multi-client TAP bridging actually supported in the OpenVPN server? Obviously server ceases listening to new conections when i use --server-bridge, and I cannot find any reason why.
Additional problem for me is IF multi-client would be supported, then I need to somehow tell the server to bring up NEW tapX interface for each connection (so they can be joined to bridge br0 on the server, e.g.:
server: bridge br0 (tap0, tap1, tap2, tap3 ... tapN) 192.168.104.2
I simply cannot find a way to do it, as the tutorial on bridging has some confusing config errors. For example:
dev tap
dev-node tap-bridge
What is "tap-bridge" here? Should this be br0 (as it is referred to in bridge-start script on the same tutorial page?
Currently I only see "take the bigger hammer solution"of having N servers running for N clients, providing tap0, tap1, tap2, ... tapN-1, all joined under br0 bridge on the server, and of course listening on N UDP ports.
Am I missing something? Below are my config files for server and both clients. Note that both clients are exactly the same, the only difference are the keys, which I do not post. Note that ok common names come up in server logs upon the connection, this is why I know that the one who connects first blocks the server.
Note also that there is redundant stuff left over from suggested route "first create working TUN setup and then modify config files", as suggested by the OpenVPN tutorial on bridging.
Server config:
server-bridge nogw
port 1195
proto udp
dev tap
user nobody
group nogroup
persist-key
persist-tun
keepalive 10 120
topology subnet
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
tls-crypt tls-crypt.key
crl-verify crl.pem
ca ca.crt
cert server_wKZztg0TXq0FsUvZ.crt
key server_wKZztg0TXq0FsUvZ.key
auth SHA256
cipher AES-128-GCM
ncp-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
client-config-dir /etc/openvpn/ccd
script-security 2
status /var/log/openvpn/status.log
up /etc/openvpn/server/bridge-start
down /etc/openvpn/server/bridge-stop
verb 3
client config 1:
client
proto udp
explicit-exit-notify
remote serverIPdeleted 1195
dev tap0
resolv-retry infinite
nobind
persist-key
remote-cert-tls server
verify-x509-name server_wKZztg0TXq0FsUvZ name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
pull-filter ignore redirect-gateway
script-security 2
up /etc/openvpn/client/bridge-start
down /etc/openvpn/client/bridge-stop
verb 3
client config 2:
client
proto udp
explicit-exit-notify
remote ServerIPDeleted 1195
dev tap0
resolv-retry infinite
nobind
persist-key
remote-cert-tls server
verify-x509-name server_wKZztg0TXq0FsUvZ name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
pull-filter ignore redirect-gateway
script-security 2
up /etc/openvpn/client/bridge-start
down /etc/openvpn/client/bridge-stop
verb 3
EDIT (by request): my bridge scripts with some added comments.
- Server bridge-start script
#!/bin/bash
#################################
# Set up Ethernet bridge on Linux
# Requires: bridge-utils
# adapted from tutorial
#################################
# Define Bridge Interface
br="br0"
# Define list of TAP interfaces to be bridged,
# for example tap="tap0 tap1 tap2".
tap="tap0 tap1 tap2 tap3 tap4"
# Commented because I want to bridge clients networks!
#eth="eth0"
eth_ip="192.168.104.2"
eth_netmask="255.255.255.0"
eth_broadcast="192.168.104.255"
for t in $tap; do
openvpn --mktun --dev $t
done
brctl addbr $br
# below is commented for a reason, see above
#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
done
# again commented with a reason above
#ifconfig $eth 0.0.0.0 promisc up
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
iptables -A INPUT -i tap0 -j ACCEPT
iptables -A INPUT -i tap1 -j ACCEPT
iptables -A INPUT -i tap2 -j ACCEPT
iptables -A INPUT -i tap3 -j ACCEPT
iptables -A INPUT -i tap4 -j ACCEPT
iptables -A INPUT -i br0 -j ACCEPT
iptables -A FORWARD -i br0 -j ACCEPT
- Server bridge-stop script
#!/bin/bash
####################################
# Tear Down Ethernet bridge on Linux
####################################
# Define Bridge Interface
br="br0"
# Define list of TAP interfaces to be bridged together
tap="tap0 tap1 tap2 tap3 tap4"
ifconfig $br down
brctl delbr $br
#for t in $tap; do
# openvpn --rmtun --dev $t
#done
- Client bridge-start script. Script for other client is different only in the IP and MAC address. I assigned MACs to later enable separate DHCP server. The clients work, the main question is why they don't both connect to the server. Any problems with MACs, IPs, learning routes would be discovered in server output IF the second client would connect AT ALL (it does not), so I believe these are not the issue. Both clients work well as long as I attempt to connect only with one client. The second one (whichever comes second) does not even connect.
#!/bin/bash
#################################
# Set up Ethernet bridge on Linux
# Requires: bridge-utils
#################################
# Define Bridge Interface
br="br0"
brmac="00:00:00:10:04:03"
ip="192.168.104.3"
# 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.
#The below line is commented FOR NOW until I get it
# to work!
#eth="eth0"
eth_ip=$ip
eth_netmask="255.255.255.0"
eth_broadcast="192.168.104.255"
#for t in $tap; do
# openvpn --mktun --dev $t
#done
brctl addbr $br
ip link set $br address $brmac
#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
done
# commented for now
#ifconfig $eth 0.0.0.0 promisc up
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
iptables -A INPUT -i tap0 -j ACCEPT
iptables -A INPUT -i br0 -j ACCEPT
iptables -A FORWARD -i br0 -j ACCEPT
- Client bridge-stop script.
#!/bin/bash
####################################
# Tear Down Ethernet bridge on Linux
####################################
# Define Bridge Interface
br="br0"
# Define list of TAP interfaces to be bridged together
tap="tap0"
ifconfig $br down
brctl delbr $br
#for t in $tap; do
# openvpn --rmtun --dev $t
#done
bridge-start
andbridge-stop
scripts for server and client. From what I read of the tutorial, the bridging scripts are meant to bridge a physical adapter (egeth0
) into the bridge (egbr0
). So I wonder if that’s what’s happening (just speculation). I didn’t downvote you but I am curious why a routed network would be inappropriate for you. Normally L2 bridging like this would be disadvantageous.