Skip to main content
Bounty Ended with 50 reputation awarded by Agustin
Rewritten complete answer with detailed solution
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205
          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24   192.168.50.2
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \        /
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │           subnet
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │        192.168.50.0/24
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.4.1   from MODEM)
        from RPi)

The ip addresses from the endpoints of the vpn tunnel must be on the same subnet. Here I use the subnet 10.8.0.0/24, so I give the vpn tunnel the shown ip addresses. These addresses are only used for routing to the vpn tunnel. They are not used by any other interface. Due to my test environment I have used some different subnets than yours.

YouStarting with a fresh flashed Raspbian Buster Lite you should setup the VPN router in three steps so you can test each step independently.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel (it's not setup at this point).

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

♦ Setup the modem connection

Setup the modem connection so you get the **ppp0** interface and you can `ping google.com`. Nothing else is connected to the hotspot RasPi. I don't have a 4G modem so I used USB tethering with my smartphone to test it. This will give me the interface **usb0**. But the settings with **ppp0** should look similar to this at this time:
rpi ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 12:8e:37:b5:a9:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.218/24 brd 192.168.42.255 scope global noprefixroute usb0
       valid_lft forever preferred_lft forever
    inet6 fe80::c1dd:14fa:9aab:41a6/64 scope link
       valid_lft forever preferred_lft forever

rpi ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.218 metric 204
192.168.42.0/24 dev usb0 proto dhcp scope link src 192.168.42.218 metric 204

rpi ~$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.42.129

Now it's all together. All hosts on the local network should be able to get into the internet and connect to the remote VPN server. There is only one issue with routing on the VPN server. It will receive ip packets with source address from subnet 192.168.4.0/24 and it doesn't know where to send back the responses. So we have to set a static route on it. If it is a Linux host then the routing entry looks like this:

♦ Setup the bridge and the internet connection

Setup the bridge and the internet connection as shown in [How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?](https://raspberrypi.stackexchange.com/a/99598/79866). In that setup just replace all strings `*usb0*` with `*ppp0*`. Also replace ip address `192.168.4.1` just with that you want to use, e.g. with `192.168.50.1` but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel(it's not setup at this point). The settings are:
rpi ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbec/64 scope link
       valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:1e:14:46:ba:8d brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.1/24 brd 192.168.4.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc1e:14ff:fe46:ba8d/64 scope link
       valid_lft forever preferred_lft forever
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbed/64 scope link
       valid_lft forever preferred_lft forever
6: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether fe:89:43:14:4f:41 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.245/24 brd 192.168.42.255 scope global dynamic usb0
       valid_lft 3595sec preferred_lft 3595sec
    inet6 fe80::fc89:43ff:fe14:4f41/64 scope link
       valid_lft forever preferred_lft forever

rpi ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.245 metric 1024
192.168.4.0/24 dev br0 proto kernel scope link src 192.168.4.1
192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.245
192.168.42.129 dev usb0 proto dhcp scope link src 192.168.42.245 metric 1024

rpi ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 192.168.42.129

♦ Setup VPN connection

I have used this [Simple openVPN with static keys](https://raspberrypi.stackexchange.com/a/98186/79866) setup to test the configuration. Here in short only the needed setup.

I assume you have a working internet connection from the hotspot RasPi to the VPN server. I use port forwarding but how to setup it is out of scope here. For this example I use the public ip address 84.152.97.94 to connect to the router, that forwarded default openvpn port 1194 to the VPN server. You should be able to ping from the hotspot RasPi the remote address of the VPN server, in my example ping 84.152.97.94.

Install OpenVPN on the VPN server

# Install OpenVPNserver ~$ sudo-Esserver ~# apt install openvpn openvpn-systemd-resolved
vpnserver# disable classic networking
server ~# systemctl mask networking.service dhcpcd.service
server ~# mv /etc/network/interfaces /etc/network/interfaces~
server ~# sed -i '1i resolvconf=NO' /etc/resolvconf.conf

# enable systemd-networkd
server ~# systemctl enable systemd-networkd.service systemd-resolved.service
server ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

Setup network interface eth0. Because I configured port forwarding on the internet router (192.168.50.1) I have to set a static ip address so the internet router can forward traffic on default OpenVPN port 1194 to this ip address.

server ~# cat > /etc/systemd/network/04-eth.network <<EOF
[Match]
Name=e*
[Network]
Address=192.168.50.2/24
Gateway=192.168.50.1
DNS=84.200.69.80 1.1.1.1
IPForward=yes
EOF

Then generate a static secret key:

server ~# openvpn --genkey --secret /etc/openvpn/static.key

Create a client config file:

server ~# cat > /etc/openvpn/server.conf <<EOF
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
cipher AES-256-CBC
auth-nocache
route 192.168.4.0 255.255.255.0
EOF

Please note that the server will never connect to the client so it does not have a remote entry. The connection is always initiated by the client. Enable the VPN server:

server ~# systemctl enable [email protected]

Reboot. The setting should now look like this:

server ~$ sudoip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:0e:3c:6f brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.2/24 brd 192.168.50.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fe0e:3c6f/64 scope link
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b8:27:eb:5b:69:3a brd ff:ff:ff:ff:ff:ff
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::2a9e:7d49:c632:62a3/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

server ~$ ip route
default addvia 192.168.50.1 dev eth0 proto static
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1
192.168.4.0/24 via 10.8.0.2 dev tun0
192.168.50.0/24 dev eth0 proto kernel scope link src 192.168.50.

server ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 84.200.69.80
nameserver 1.1.1.1

Install OpenVPN on the hotspot RasPi

Here we will install an OpenVPN configuration, named "client" on the hotspot RasPi.
client ~$ sudo -Es
client ~# apt install openvpn openvpn-systemd-resolved

Copy /etc/openvpn/static.key from the VPN server to /etc/openvpn/static.key here and set its permission with sudo chmod 600 /etc/openvpn/static.key. Create a client config file:

client ~# cat > /etc/openvpn/client.conf <<EOF
dev tun
remote 84.152.97.94
ifconfig 10.8.0.2 10.8.0.1
route 192.168.50.0 255.255.255.0
secret static.key
cipher AES-256-CBC
auth-nocache
EOF

Start the VPN client:

client ~# systemctl enable --now [email protected]
client ~# exit
client ~$

Now you should be able to ping the VPN server:

client ~$ ping 10.8.0.1
client ~$ ping 192.168.50.2
client ~$ ping google.com

This will establish a connection. After that you should also be able to ping the hotspot RasPi from the VPN server:

server ~$ ping 10.8.0.2
server ~$ ping 192.168.4.1
client ~$ ping google.com

You should also be able to ping any device connected wired or wireless to the hotspot RasPi. Please keep in mind that the VPN server will not connect to the client. First ping the server from the client (hotspot RasPi).

The setup should look like this:

client ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbec/64 scope link
       valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:1e:14:46:ba:8d brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.1/24 brd 192.168.4.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc1e:14ff:fe46:ba8d/64 scope link
       valid_lft forever preferred_lft forever
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbed/64 scope link
       valid_lft forever preferred_lft forever
5: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 8a:ef:e0:df:7e:1e brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.92/24 brd 192.168.42.255 scope global dynamic usb0
       valid_lft 2707sec preferred_lft 2707sec
    inet6 fe80::88ef:e0ff:fedf:7e1e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.8.0.2 peer 10.8.0.1/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::4cf3:3f85:c0f7:3cd6/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

client ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.92 metric 1024
10.8.0.1 dev tun0 proto kernel scope link src 10.8.0.2
192.168.4.0/24 dev br0 proto kernel scope link src 192.168.4.1
192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.92
192.168.42.129 dev usb0 proto dhcp scope link src 192.168.42.92 metric 1024
192.168.50.0/24 via 10.8.0.1 dev tun0

client ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 192.168.42.129

Setup routing on the VPN server

If you try from the hotspot RasPi to ping devices connected to the VPN server on its subnet 192.168.50.0/24 you will see that it doesn't work now. The reason is that they don't know where the subnet 192.168.4.1 of the hotspot RasPi is. We have to tell it with an additional routing information. You can configure each client with a static route, or you can configure its DHCP server to give that route to the clients, if it can. But the easiest is to disable the running DHCP server on subnet 192.168.50.0/24 and enable the DHCP server on the VPN Server. It will do all work automagically. Just append this to `04-eth.network`:
server ~$ sudo -Es
server ~# cat >> /etc/systemd/network/04-eth.network <<EOF
DHCPServer=yes
[DHCPServer]
DNS=84.200.69.80 1.1.1.1
EOF

Don't forget to disable the "old" running DHCP server before enable this:

server ~# systemctl daemon-reload
server ~# systemctl restart systemd-networkd.service
server ~# exit
server ~$
          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.4.1   from MODEM)
        from RPi)

The ip addresses from the endpoints of the vpn tunnel must be on the same subnet. Here I use the subnet 10.8.0.0/24, so I give the vpn tunnel the shown ip addresses. These addresses are only used for routing to the vpn tunnel. They are not used by any other interface.

You should setup the VPN router in three steps so you can test each step independently.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel (it's not setup at this point).

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

Now it's all together. All hosts on the local network should be able to get into the internet and connect to the remote VPN server. There is only one issue with routing on the VPN server. It will receive ip packets with source address from subnet 192.168.4.0/24 and it doesn't know where to send back the responses. So we have to set a static route on it. If it is a Linux host then the routing entry looks like this:

vpnserver ~$ sudo ip route add 192.168.4.0/24 via 10.8.0.2 dev tun0 proto static src 10.8.0.1
          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24   192.168.50.2
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \        /
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │           subnet
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │        192.168.50.0/24
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.4.1   from MODEM)
        from RPi)

The ip addresses from the endpoints of the vpn tunnel must be on the same subnet. Here I use the subnet 10.8.0.0/24, so I give the vpn tunnel the shown ip addresses. These addresses are only used for routing to the vpn tunnel. They are not used by any other interface. Due to my test environment I have used some different subnets than yours.

Starting with a fresh flashed Raspbian Buster Lite you should setup the VPN router in three steps so you can test each step independently.

♦ Setup the modem connection

Setup the modem connection so you get the **ppp0** interface and you can `ping google.com`. Nothing else is connected to the hotspot RasPi. I don't have a 4G modem so I used USB tethering with my smartphone to test it. This will give me the interface **usb0**. But the settings with **ppp0** should look similar to this at this time:
rpi ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 12:8e:37:b5:a9:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.218/24 brd 192.168.42.255 scope global noprefixroute usb0
       valid_lft forever preferred_lft forever
    inet6 fe80::c1dd:14fa:9aab:41a6/64 scope link
       valid_lft forever preferred_lft forever

rpi ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.218 metric 204
192.168.42.0/24 dev usb0 proto dhcp scope link src 192.168.42.218 metric 204

rpi ~$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.42.129

♦ Setup the bridge and the internet connection

Setup the bridge and the internet connection as shown in [How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?](https://raspberrypi.stackexchange.com/a/99598/79866). In that setup just replace all strings `*usb0*` with `*ppp0*`. Also replace ip address `192.168.4.1` just with that you want to use, e.g. with `192.168.50.1` but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel(it's not setup at this point). The settings are:
rpi ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbec/64 scope link
       valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:1e:14:46:ba:8d brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.1/24 brd 192.168.4.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc1e:14ff:fe46:ba8d/64 scope link
       valid_lft forever preferred_lft forever
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbed/64 scope link
       valid_lft forever preferred_lft forever
6: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether fe:89:43:14:4f:41 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.245/24 brd 192.168.42.255 scope global dynamic usb0
       valid_lft 3595sec preferred_lft 3595sec
    inet6 fe80::fc89:43ff:fe14:4f41/64 scope link
       valid_lft forever preferred_lft forever

rpi ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.245 metric 1024
192.168.4.0/24 dev br0 proto kernel scope link src 192.168.4.1
192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.245
192.168.42.129 dev usb0 proto dhcp scope link src 192.168.42.245 metric 1024

rpi ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 192.168.42.129

♦ Setup VPN connection

I have used this [Simple openVPN with static keys](https://raspberrypi.stackexchange.com/a/98186/79866) setup to test the configuration. Here in short only the needed setup.

I assume you have a working internet connection from the hotspot RasPi to the VPN server. I use port forwarding but how to setup it is out of scope here. For this example I use the public ip address 84.152.97.94 to connect to the router, that forwarded default openvpn port 1194 to the VPN server. You should be able to ping from the hotspot RasPi the remote address of the VPN server, in my example ping 84.152.97.94.

Install OpenVPN on the VPN server

# Install OpenVPNserver ~$ sudo-Esserver ~# apt install openvpn openvpn-systemd-resolved
# disable classic networking
server ~# systemctl mask networking.service dhcpcd.service
server ~# mv /etc/network/interfaces /etc/network/interfaces~
server ~# sed -i '1i resolvconf=NO' /etc/resolvconf.conf

# enable systemd-networkd
server ~# systemctl enable systemd-networkd.service systemd-resolved.service
server ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

Setup network interface eth0. Because I configured port forwarding on the internet router (192.168.50.1) I have to set a static ip address so the internet router can forward traffic on default OpenVPN port 1194 to this ip address.

server ~# cat > /etc/systemd/network/04-eth.network <<EOF
[Match]
Name=e*
[Network]
Address=192.168.50.2/24
Gateway=192.168.50.1
DNS=84.200.69.80 1.1.1.1
IPForward=yes
EOF

Then generate a static secret key:

server ~# openvpn --genkey --secret /etc/openvpn/static.key

Create a client config file:

server ~# cat > /etc/openvpn/server.conf <<EOF
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
cipher AES-256-CBC
auth-nocache
route 192.168.4.0 255.255.255.0
EOF

Please note that the server will never connect to the client so it does not have a remote entry. The connection is always initiated by the client. Enable the VPN server:

server ~# systemctl enable [email protected]

Reboot. The setting should now look like this:

server ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:0e:3c:6f brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.2/24 brd 192.168.50.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fe0e:3c6f/64 scope link
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b8:27:eb:5b:69:3a brd ff:ff:ff:ff:ff:ff
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::2a9e:7d49:c632:62a3/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

server ~$ ip route
default via 192.168.50.1 dev eth0 proto static
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1
192.168.4.0/24 via 10.8.0.2 dev tun0
192.168.50.0/24 dev eth0 proto kernel scope link src 192.168.50.

server ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 84.200.69.80
nameserver 1.1.1.1

Install OpenVPN on the hotspot RasPi

Here we will install an OpenVPN configuration, named "client" on the hotspot RasPi.
client ~$ sudo -Es
client ~# apt install openvpn openvpn-systemd-resolved

Copy /etc/openvpn/static.key from the VPN server to /etc/openvpn/static.key here and set its permission with sudo chmod 600 /etc/openvpn/static.key. Create a client config file:

client ~# cat > /etc/openvpn/client.conf <<EOF
dev tun
remote 84.152.97.94
ifconfig 10.8.0.2 10.8.0.1
route 192.168.50.0 255.255.255.0
secret static.key
cipher AES-256-CBC
auth-nocache
EOF

Start the VPN client:

client ~# systemctl enable --now [email protected]
client ~# exit
client ~$

Now you should be able to ping the VPN server:

client ~$ ping 10.8.0.1
client ~$ ping 192.168.50.2
client ~$ ping google.com

This will establish a connection. After that you should also be able to ping the hotspot RasPi from the VPN server:

server ~$ ping 10.8.0.2
server ~$ ping 192.168.4.1
client ~$ ping google.com

You should also be able to ping any device connected wired or wireless to the hotspot RasPi. Please keep in mind that the VPN server will not connect to the client. First ping the server from the client (hotspot RasPi).

The setup should look like this:

client ~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ec brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbec/64 scope link
       valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:1e:14:46:ba:8d brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.1/24 brd 192.168.4.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc1e:14ff:fe46:ba8d/64 scope link
       valid_lft forever preferred_lft forever
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether dc:a6:32:01:db:ed brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dea6:32ff:fe01:dbed/64 scope link
       valid_lft forever preferred_lft forever
5: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 8a:ef:e0:df:7e:1e brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.92/24 brd 192.168.42.255 scope global dynamic usb0
       valid_lft 2707sec preferred_lft 2707sec
    inet6 fe80::88ef:e0ff:fedf:7e1e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.8.0.2 peer 10.8.0.1/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::4cf3:3f85:c0f7:3cd6/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

client ~$ ip route
default via 192.168.42.129 dev usb0 proto dhcp src 192.168.42.92 metric 1024
10.8.0.1 dev tun0 proto kernel scope link src 10.8.0.2
192.168.4.0/24 dev br0 proto kernel scope link src 192.168.4.1
192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.92
192.168.42.129 dev usb0 proto dhcp scope link src 192.168.42.92 metric 1024
192.168.50.0/24 via 10.8.0.1 dev tun0

client ~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
--- snip ---
nameserver 192.168.42.129

Setup routing on the VPN server

If you try from the hotspot RasPi to ping devices connected to the VPN server on its subnet 192.168.50.0/24 you will see that it doesn't work now. The reason is that they don't know where the subnet 192.168.4.1 of the hotspot RasPi is. We have to tell it with an additional routing information. You can configure each client with a static route, or you can configure its DHCP server to give that route to the clients, if it can. But the easiest is to disable the running DHCP server on subnet 192.168.50.0/24 and enable the DHCP server on the VPN Server. It will do all work automagically. Just append this to `04-eth.network`:
server ~$ sudo -Es
server ~# cat >> /etc/systemd/network/04-eth.network <<EOF
DHCPServer=yes
[DHCPServer]
DNS=84.200.69.80 1.1.1.1
EOF

Don't forget to disable the "old" running DHCP server before enable this:

server ~# systemctl daemon-reload
server ~# systemctl restart systemd-networkd.service
server ~# exit
server ~$
Clarified info about pinging everything.
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205
  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel (it's not setup at this point).

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now.

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now, except interfaces from the VPN tunnel (it's not setup at this point).

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

Finished setup
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205

Having a remote OpenVPN server at your home and connect to it with the RasPi is a good alternativesolution if you cannot use port forwarding on the modem. Here is an example setup for what you have described:

          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.50.1  from MODEM)
        from RPi)
          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.4.1   from MODEM)
        from RPi)

(Will You should setup the VPN router in three steps so you can test each step independently.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now.

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

Now it's all together. All hosts on the local network should be continued)able to get into the internet and connect to the remote VPN server. There is only one issue with routing on the VPN server. It will receive ip packets with source address from subnet 192.168.4.0/24 and it doesn't know where to send back the responses. So we have to set a static route on it. If it is a Linux host then the routing entry looks like this:

vpnserver ~$ sudo ip route add 192.168.4.0/24 via 10.8.0.2 dev tun0 proto static src 10.8.0.1

Having a remote OpenVPN server at your home and connect to it with the RasPi is a good alternative if you cannot use port forwarding on the modem. Here is an example setup for what you have described:

          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.50.1  from MODEM)
        from RPi)

(Will be continued)

Having a remote OpenVPN server at your home and connect to it with the RasPi is a good solution if you cannot use port forwarding on the modem. Here is an example setup for what you have described:

          (dhcp
        from RPi)        bridge      10.8.0.2/24               ┌──────────┐   10.8.0.1/24
           ╱    wifi    ┌───────┐       /       vpn-tunnel     │          │       \
mobile-phone <~.~.~.~.> │(wlan0)│   (tun0) ═════════╗ ╔══════════════════════════ VPN-SERVER
                        │    br0│RPi(ppp0) <-----> MODEM <---> │ INTERNET │
      laptop <────────> |(eth0) │╲      \    usb          wan  │          │
           ╲    wired   └───────┘╱     (dhcp                   └──────────┘
         (dhcp           192.168.4.1   from MODEM)
        from RPi)

You should setup the VPN router in three steps so you can test each step independently.

  1. Setup the modem connection so you get the ppp0 interface and you can ping google.com.

  2. Setup the bridge and the internet connection as shown in How can I set my pi 3 up to be WiFi AND ethernet router simultaneously?. In that setup just replace all strings *usb0* with *ppp0*. I don't have a 4G modem so I used USB tethering with my smartphone to test it. Also replace ip address 192.168.4.1 just with that you want to use, e.g. with 192.168.50.1 but have an attention it isn't from the ip range that is used by the modem. When finished then you should have a running setup as shown in the drawing above but just without the vpn tunnel. You should be able to ping everything from everywhere now.

  3. Setup your VPN connection. I have used this Simple openVPN with static keys setup to test the configuration. You should be able to ping your remote VPN server with e.g. ping 10.8.0.1.

Now it's all together. All hosts on the local network should be able to get into the internet and connect to the remote VPN server. There is only one issue with routing on the VPN server. It will receive ip packets with source address from subnet 192.168.4.0/24 and it doesn't know where to send back the responses. So we have to set a static route on it. If it is a Linux host then the routing entry looks like this:

vpnserver ~$ sudo ip route add 192.168.4.0/24 via 10.8.0.2 dev tun0 proto static src 10.8.0.1
Added bridge
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205
Loading
Updated ip addresses for the vpn tunnel.
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205
Loading
Source Link
Ingo
  • 42.7k
  • 20
  • 85
  • 205
Loading