My access point spawns a wireless local area network. Now I want to connect it to my other private network over the internet with openvpn so it gets direct part of the remote network in a common broadcast domain using the same ip address range and the DHCP server on the remote network. I know I have to use a tap interface instead of a tun interface on openvpn for this but how to setup the other components?
1 Answer
Example for this setup:
bridge ┌──────────┐ bridge
┌───────┐ vpn-tunnel │ │ ┌───────┐ 192.168.179.1
│ (tap0)│════════════════════════╗ ╔═══════╪══════════╪═══════╗ ╔═════════════════│(tap0) │╱
wifi │ br0│RPi(wlan1) <.~.~.~.~.> router <───>│ INTERNET │<───> router <─> (eth0)VPN- │ br0│ wifi
phone <~.~.~.>|(wlan0)│ ╲ wifi ╱ wan │ │ wan ╱ server|(wlan0)│<~.~.~.> DHCP-
╲ └───────┘ 192.168.50.X 192.168.50.1 │ │ <public-ip> └───────┘ server
192.168.179.X (dhcp local) ╰──────────╯
(dhcp remote network)
The advantage of openvpn is that it is independent from the underlaying network setup, no matter if you use dhcpcd, /etc/network/interfaces or systemd-networkd. It only needs a connection to the VPN-server and interfaces that can be added to a bridge as slaves. For this example I will use systemd-networkd because it has everything built-in and we do not need additional programs. To show the setup of the VPN-server I will use a RPi 3B so you can take it as template for setting up your own VPN-server based on an other hardware.
This example is made for Raspberry Pi to be used in a home environment to be as simple as possible. It uses a peer to peer VPN tunnel (mode p2p) with static preshared encryption keys. This simplyfies the setup a lot but you can only connect one client to the VPN-server. If you need a second one you can setup a second instance of the VPN-server (maybe a third one?). But if you need more clients to connect to the VPN-server, e.g. in an enterprise environment, you have to setup a PKI (public key infrastructure) with a master Certificate Authority (CA) to be used for a client/server VPN tunnel (mode server). This is much more complicated and not an issue here 2.
You need a connection from the RasPi to the VPN-server. Configuring it, for example with DynDNS, port forwarding and routing is out of scope here. You should have setup it before starting.
For reference I use Raspbian Stretch Lite 2018-11-13, updated with sudo apt update && sudo apt full-upgrade && sudo reboot
on 2019-04-01.
♦ Set up the VPN-server
Do ♦ General Setup then create this file to configure openvpn:
rpi ~# cat > /etc/openvpn/server.conf <<EOF
dev tap0
mode p2p
secret static.key
cipher AES-256-CBC
EOF
Create these files to setup the bridge:
rpi ~# cat > /etc/systemd/network/02-br0.netdev <<EOF
[NetDev]
Name=br0
Kind=bridge
EOF
rpi ~# cat > /etc/systemd/network/04-eth0.network <<EOF
[Match]
Name=eth0
[Network]
# Use your own static ip addresses for the VPN-server
Address=192.168.50.2/24
Gateway=192.168.50.1
DNS=84.200.69.80 84.200.70.40
EOF
rpi ~# cat > /etc/systemd/network/12-br0_add-slaves.network <<EOF
[Match]
Name=tap0
[Network]
Bridge=br0
EOF
rpi ~# cat > /etc/systemd/network/16-br0_up.network <<EOF
[Match]
Name=br0
[Network]
Address=192.168.179.1
# Don't use the next lines if there is already a dhcp server running
DHCPServer=yes
[DHCPServer]
PoolOffset=129
DNS=84.200.69.80 84.200.70.40
EOF
To configure wpa_supplicant to be used as access point create this file:
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="RemoteNet"
mode=2
key_mgmt=WPA-PSK
proto=RSN WPA
psk="verySecretPassword"
frequency=2437
}
EOF
rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl enable [email protected]
Now we have to tell wpa_supplicant to use a bridge. We do it by modifying its service with:
rpi ~# systemctl edit [email protected]
In the empty editor insert these statements, save them and quit the editor:
[Service]
ExecStartPre=/sbin/iw dev wlan0 set type __ap
ExecStartPre=/bin/ip link set wlan0 master br0
ExecStart=
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I -bbr0
ExecStopPost=-/bin/ip link set wlan0 nomaster
ExecStopPost=-/sbin/iw dev wlan0 set type managed
Reboot.
♦ Setup the VPN-client
Before starting with setup you should first check if you can connect from the RasPi to the VPN-server on the internet. Your VPN-server has the <public-ip>
(e.g. 93.93.128.230):
rpi ~$ ping -c4 <public-ip>
# check if openvpn is reachable on its default UDP port 1194
rpi ~$ nc -vz -u <public-ip> 1194
Connection to <public-ip> 1194 port [udp/openvpn] succeeded!
rpi ~$
Then do ♦ General Setup and create this file to configure openvpn:
rpi ~# cat > /etc/openvpn/client.conf <<EOF
dev tap0
mode p2p
remote <public-ip> 1194 udp
secret static.key
cipher AES-256-CBC
EOF
Create these files to configure the interfaces:
rpi ~# cat > /etc/systemd/network/08-wlan1.network <<EOF
[Match]
Name=wlan1
[Network]
DHCP=yes
#[DHCP]
#UseRoutes=no
EOF
rpi ~# cat > /etc/systemd/network/12-tap0.network <<EOF
[Match]
Name=tap0
[Network]
DHCP=yes
[DHCP]
UseRoutes=no
EOF
In the example above the default route is set to the local router, so the internet traffic isn't routed through the VPN tunnel. If you want to send internet traffic through the tunnel to use an internet router on the remote side, then just toggle commenting of [DHCP]
and UseRoutes=no
.
To setup the client connection of wpa_supplicant create this file:
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan1.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="TestNet"
psk="verySecretPassword"
}
EOF
rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan1.conf
rpi ~# systemctl enable [email protected]
Reboot.
Now the tap interface has an ip address from the subnet 192.168.179.0/24 and you can ping 192.168.179.1:
rpi ~$ ip -4 addr show dev tap0
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
inet 192.168.179.211/24 brd 192.168.179.255 scope global dynamic tap0
valid_lft 2387sec preferred_lft 2387sec
♦ Bridge client access point to the VPN tunnel
Create these files to setup the bridge:
rpi ~$ sudo -Es
rpi ~# cat > /etc/systemd/network/02-br0.netdev <<EOF
[NetDev]
Name=br0
Kind=bridge
EOF
rpi ~# cat > /etc/systemd/network/12-tap0.network <<EOF
[Match]
Name=tap0
[Network]
Bridge=br0
EOF
rpi ~# cat > /etc/systemd/network/16-br0_up.network <<EOF
[Match]
Name=br0
[Link]
MACAddress=22:6f:e8:92:70:04
[Network]
DHCP=yes
[DHCP]
UseRoutes=no
EOF
Because a bridge is always given the same MAC address, we need to give br0 another unique one to differ it from the bridge on the VPN server.
In the example above the default route is set to the local router, so the internet traffic isn't routed through the VPN tunnel. If you want to send internet traffic through the tunnel to use an internet router on the remote side, then just toggle commenting of [DHCP]
and UseRoutes=no
in 08-wlan1.network and 16-br0_up.network.
To configure wpa_supplicant to be used as access point create this file:
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="ClientNet"
mode=2
key_mgmt=WPA-PSK
proto=RSN WPA
psk="verySecretPassword"
frequency=2437
}
EOF
rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl enable [email protected]
Now we have to tell wpa_supplicant to use a bridge. We do it by modifying its service with:
rpi ~# systemctl edit [email protected]
In the empty editor insert these statements, save them and quit the editor:
[Service]
ExecStartPre=/sbin/iw dev wlan0 set type __ap
ExecStartPre=/bin/ip link set wlan0 master br0
ExecStart=
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I -bbr0
ExecStopPost=-/bin/ip link set wlan0 nomaster
ExecStopPost=-/sbin/iw dev wlan0 set type managed
Reboot.
Now you can connect to the access point ClientNet with your phone and get an ip address from the DHCP server on the RemoteNet far away. The phone is now member of the broadcast domain RemoteNet with all its resources so as it would be direct connected to it.
♦ General Setup
Switch over to systemd-networkd
Execute these commands:
# Install openvpn and helper to speed up getting random numbers for encryption
rpi ~$ sudo -Es
rpi ~# apt install openvpn openvpn-systemd-resolved rng-tools
# disable classic networking
rpi ~# systemctl mask networking.service dhcpcd.service
rpi ~# mv /etc/network/interfaces /etc/network/interfaces~
rpi ~# sed -i '1i resolvconf=NO' /etc/resolvconf.conf
# enable systemd-networkd
rpi ~# systemctl enable systemd-networkd.service systemd-resolved.service
rpi ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Create static key for encryption
On a openvpn device (client or server) generate a static secret key. Don't generate it two times. Use only one static.key.
rpi ~# openvpn --genkey --secret /etc/openvpn/static.key
Copy /etc/openvpn/static.key
over to the openvpn device on the other end (client or server) to /etc/openvpn/static.key
with same permission (sudo chmod 600 /etc/openvpn/static.key
) so you have the same key available on the client and server.
Go back where you come from and continue the setup.
References:
(1): My-Tiny.Net - Virtual Private Networks
(2): openvpn - How To
(3): openvpn - Static Key Mini-HOWTO
(4): openvpn - Ethernet Bridging
-
-
at the beginning where you switch over to systemd-networkd, would this be for both hotspot and server? my hotspot is already using systemd-networkd but not my raspberry server. Also, the instructions under the "Set up VPN-Server" you create the wpa_supplicant file for the client? shouldn't this part be ni the "set up the VPN-client"? unless your hotspot is also the server?– AgustinCommented Nov 11, 2019 at 0:13
-
@Agustin Both the server setup section and the client setup section refer to use General Setup first. I have reordered the sections to make it clearer. The client connects to its router with a WiFi client connection. The server presents also a hotspot. That is the setup shown in the drawing. When I refer to your question Setting up Bridged VPN using: RPi 3G Hotspot router + openvpn client to connect to home RPi OpenVPN server it may not direct fit your needs.– IngoCommented Nov 11, 2019 at 10:19
-
@Agustin This bridging setup here is a complete different task and a bit more complex. You should first finish your first setup using routing.– IngoCommented Nov 11, 2019 at 10:29
-
@Agustin You have asked for the server configuration at raspberrypi.stackexchange.com/questions/108217/…. The hotspot on the server side (right side of the drawing) is only an example. You can also use a wired subnet there. Because we "merge" two subnets (left side with right side of the drawing) I need to have a subnet on the server for demonstration. I chose a wireless one. About the connection to UDP port 1194: have you tested it wit
nc
as described in section ♦ Setup the VPN-client?.– IngoCommented Feb 17, 2020 at 9:59