This post describes a LAN bridge built with a Pi 3 wifi client and an OpenVPN tunnel. This setup is for private use only.
Code: Select all
++ House +--------------------+ ++ Shed +------------+
| +--------+ | | +-----+ |
| |Router | )))) WiFi (((( |RPI 3| |
| |WiFi AP | | | |Ovpn | |
| |DHCP | | | .150 +--+--+ |
| 192.168.1.1 +----+---+ | | bridge | Ethernet |
| | Ethernet | | | |
| +-----------+ | | | |
| bridge | | | | | |
| +--+--+ +--+--+ | | +--+--+ |
| |PC A | |PC B | | | |PC C | |
| |Ovpn | .20 +-----+ | | .30 +-----+ |
| .10 +-----+ | | |
+-----------------------------+ +--------------------+
On each side of the wifi Access Point, a computer runs OpenVPN bridged to its ethernet port ("PC A", "RPI 3".)
"PC A" is the OpenVPN server, it runs in the background and waits for the client to connect. "RPI 3" is the OpenVPN client, it tries to reach the server over wifi as soon as possible.
Installing on "PC A" and "RPI 3"
- "PC A" happens to be a Debian Jessie (virtual) machine; DHCP client over ethernet.
- "RPI 3" runs a stock Raspbian Stretch Lite installation; DHCP client over wifi.
To install the required software I simply ran on both machines:Code: Select all
sudo apt-get update && sudo apt-get upgrade sudo apt-get install bridge-utils openvpn
This covers networking and OpenVPN, please adapt to your OS.
- Make sure the OpenVPN server starts at boot.
- Custom /etc/network/interfaces file:
Note:
Code: Select all
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # Bridge - Same MAC as eth0 auto br0 iface br0 inet dhcp pre-up ip tuntap add dev tap0 mode tap pre-up ip link set dev tap0 address fe:01:ae:eb:12:34 pre-up ip link set dev tap0 up pre-up ip link set dev eth0 up bridge-stp on bridge-bridgeprio 65534 bridge-maxwait 2 bridge-fd 2 bridge-ports eth0 tap0 # IP address used by the OpenVPN client and server. post-up ip link add name ovpn0 type dummy post-up ip addr add 10.10.10.10/32 dev ovpn0
- I use MAC-based IP reservations with DHCP; Setting tap0 to use a MAC address starting with "fe:" guarantees the bridge br0 will adopt the MAC address of eth0. So the DHCP server will give to br0 the address previously configured for eth0.
- If OpenVPN listens on the IP address of br0, clients like "PC C" won't be able to ping "PC A" (not sure why.) Using an IP on a free network (10.10.10.10/32) works around the issue.
- OpenVPN config file /etc/openvpn/bridge-svr.conf:
Note: To minimize overhead and simplify installation the OpenVPN tunnel is without authentication and encryption (and runs in "p2p" mode). It is assumed that the wifi link is encrypted. Do not use this setup over a public or unencrypted link.
Code: Select all
# Server config local 10.10.10.10 # Our interface address dev tap0 ifconfig-nowarn passtos fast-io persist-tun ping-timer-rem keepalive 10 30 cipher none # We rely on WPA mute 10 verb 1 writepid /run/openvpn/bridge-srv.pid
This covers the complete setup for a current install of Raspbian Lite.
- Make sure the OpenVPN server starts at boot by editing file /etc/default/openvpn to read:
Code: Select all
AUTOSTART="all"
- Edit file /etc/dhcpcd.conf so that the first lines read...
... and leave the rest of the file unchanged.
Code: Select all
# A sample configuration for dhcpcd. # See dhcpcd.conf(5) for details. denyinterfaces br0 tap0 eth0
- To obtain a static route to the OpenVPN server, create file /lib/dhcpcd/dhcpcd-hooks/40-ovpn-static-route:
Code: Select all
# Route to the local OpenVPN server if [ "$interface" = "wlan0" ]; then ip route add 10.10.10.10/32 dev "$interface" fi
- Custom /etc/network/interfaces file:
Code: Select all
# interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: source-directory /etc/network/interfaces.d # Transparent bridge - No IP address auto br0 iface br0 inet manual pre-up ip tuntap add dev tap0 mode tap post-down ip tuntap del dev tap0 mode tap pre-up ip link set dev tap0 up pre-up ip link set dev eth0 up bridge-stp on bridge-bridgeprio 65535 bridge-maxwait 2 bridge-fd 2 bridge-ports eth0 tap0 # Route to the OpenVPN server: see # /lib/dhcpcd/dhcpcd-hooks/40-ovpn-static-route
- OpenVPN config file /etc/openvpn/bridge-clt.conf:
Note: If the wifi link is less than very good or is not reliable, the LAN bridge won't work so well... Client and server exchange pings every 10 seconds and try to restart the tunnel if pings fail for 30 seconds.
Code: Select all
# Client config remote 10.10.10.10 # Address defined at server side dev tap0 ifconfig-nowarn passtos fast-io resolv-retry infinite persist-tun keepalive 10 30 cipher none # We rely on WPA mute 10 verb 1 writepid /run/openvpn/bridge-clt.pid
Reboot both machines and hopefully they will come back online.
- This is what you could see on the server, "PC A"...
Code: Select all
$ sudo brctl show br0 $ brctl show br0 bridge name bridge id STP enabled interfaces br0 fffe.525400138d13 yes eth0 tap0 $ netstat -4an | grep 1194 udp 0 0 10.10.10.10:1194 0.0.0.0:* $ ip -4 addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default inet 192.168.1.10/24 brd 192.168.1.255 scope global br0 valid_lft forever preferred_lft forever 6: ovpn0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default inet 10.10.10.10/32 scope global ovpn0 valid_lft forever preferred_lft forever $ ip route show default via 192.168.1.1 dev br0 192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.10
- ... and on the client "RPI 3":
Code: Select all
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 9.3 (stretch) Release: 9.3 Codename: stretch $ uname -a Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l GNU/Linux $ dpkg-query --show openvpn openvpn 2.4.0-6+deb9u2 $ brctl show br0 bridge name bridge id STP enabled interfaces br0 ffff.5a41791f6e6e yes eth0 tap0 $ netstat -4an | grep 1194 udp 0 0 0.0.0.0:1194 0.0.0.0:* $ ip -4 addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.168.1.150/24 brd 192.168.1.255 scope global wlan0 valid_lft forever preferred_lft forever $ ip route show default via 192.168.1.1 dev wlan0 src 192.168.1.150 metric 303 10.10.10.10 dev wlan0 scope link 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.150 metric 303
I've tested this setup a little bit. YMMV according to wifi link quality, but for me reliability and latency were adequate for a few clients behind the Pi to stream music and video concurrently.
On the Pi, system load seems reasonable and CPU temperature does not rise. The formula should also work with a full Raspbian Desktop on the Pi (Not tested.)
Be sure to use an adequate PSU as this setup taxes both wifi and ethernet network adapters at the same time.
HTH and have fun.