4

I need to connect my phone to office network while at home. Installing a vpn client on the phone is not an option. I followed this tutorial to get an access point working with an rpi :

Configure a raspberry pi to act as an access point : https://www.raspberrypi.org/documentation/configuration/wireless/access-point.md

Instead of creating a bridge ( br0 between wlan0 and eth0 ) as directed in the tutorial, I used iptables to do the forwarding :

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

This works pretty well, but it does not work when I connect to the vpn. I have tried various combinations of the iptables command, but nothing seems to be working perfectly. Here are some combinations I have tried :

enter image description here

What I want to achieve is :

enter image description here

  • "vpn works" here means a device connected to rpi ( access point ) is able to access office websites.
  • "internet works" here means a device connected to rpi ( access point ) is able to access internet in general.
  • I am using vpnc to connect to vpn.

$ route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 tun0
default         ralink.dlink.co 0.0.0.0         UG    202    0        0 eth0
10.20.30.40     *               255.255.255.255 UH    0      0        0 tun0
192.168.0.0     *               255.255.255.0   U     202    0        0 eth0
192.168.1.0     *               255.255.255.0   U     303    0        0 wlan0
as-40816.abc    ralink.dlink.co 255.255.255.255 UGH   0      0        0 eth0

[05/05/2018] Updated routing table after the setup started working :

This was when I changed the vpn server to another host

$ route -n ( host2 )

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.0.1     0.0.0.0         UG    202    0        0 eth0
10.0.0.0        *               255.0.0.0       U     0      0        0 tun0
10.104.26.116   *               255.255.255.255 UH    0      0        0 tun0
150.11.0.101    *               255.255.255.255 UH    0      0        0 tun0
150.11.0.102    *               255.255.255.255 UH    0      0        0 tun0
102.191.24.21   192.168.0.1     255.255.255.255 UGH   0      0        0 eth0
192.168.0.0     *               255.255.255.0   U     202    0        0 eth0
192.168.1.0     *               255.255.255.0   U     303    0        0 wlan0
  • 1
    maybe helpful: raspberrypi.stackexchange.com/q/7487/78211 – Fabian Apr 28 '18 at 12:14
  • @Fabian Thank's for the hint to this question (danke ;-). This is a somewhat sophisticated question. I need my test environment but I'm just not at home. I will try next days. Seems it has something to do with routing and metric. tun0 is dynamic created and removed with the vpn tunnel. We have different subnets 192.168.0.0/24 for eth0 and 192.168.1.0/24 for wlan0. That is good, so we could establish clean routing and maybe do not need MASQUERADE at all. – Ingo May 4 '18 at 12:49
  • Hi Fabian, Ingo, thanks for looking into this. I was able to set it up this morning after I changed the server endpoint to another host. Which indicates that the issue might have been due to the routing rules pushed by the first server. Would be great if you could confirm if my understanding is correct or any other suggestions to improve the settings. I also had to add "sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE" – Gautam May 5 '18 at 10:27
  • @Gautam Please reference me with @Ingo just as I did it with you. Otherwise I don't get a message about your comment. I'm interested in this configuration so I will investigate some time and confirm. – Ingo May 6 '18 at 9:34
  • @Gautam Can you please give the route output with route -n (no name resolution)? – Ingo May 6 '18 at 9:41
3
+50

Your example shows a tun device, so we exclusively have to use routing. I use Raspbian Stretch Lite 2018-04-18. The idea is to set up a static minimal configuration without any extras e.g. dhcp server or so. If routing works it could be extended step by step.

Default networking on Raspbian is often confusing particular with more complex setups [1]. So I use systemd-networkd that is designed for server setups. Because it's difficult for me to guess all ip addresses of your interfaces I have set up my test with this ip addresses:

                             10.10.10.2                       +----------+   10.10.10.1
                                /           vpn-tunnel        |          |       \
                             (tun0) =============\\    //======================> VPN-SERVER
PHONE ~.~.~.~.~.~> (wlan0)RPI(eth0) ------------> ROUTER ---> | INTERNET |
     \    wifi       /          \    ethernet    /       wan  |          |
192.168.1.2   192.168.1.1   192.168.0.2    192.168.0.1        +----------+

Another problem for me is, that I don't have a cisco3000 VPN Concentrator so I cannot use vpnc. Instead I used openvpn but it should do the same things in routing. But setting up an openvpn infrastructure is out of scope here.

You can look at howto migrate from networking to systemd-networkd if you like to use that but you only have to use Step 1 to Step 3 on that with this files:

rpi ~$ sudo cat >/etc/systemd/network/04-eth.network <<EOF
[Match]
Name=e*
[Network]
Address=192.168.0.2/24
Gateway=192.168.0.1
EOF

rpi ~$ sudo cat >/etc/systemd/network/08-wifi.network <<EOF
[Match]
Name=wl*
[Network]
Address=192.168.1.1/24
IPForward=yes
EOF

ip forwarding is essential.

Don't setup wpa_supplicant. Instead install hostapd [2]:

rpi ~$ sudo -Es
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# apt update
rpi ~# apt full-upgrade
rpi ~# apt install hostapd
rpi ~# systemctl stop hostapd.service

Configure the access point host software (hostapd) with this file:

rpi ~# cat >/etc/hostapd/hostapd.conf <<EOF
interface=wlan0
driver=nl80211
ssid=MyTestAP
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=VerySecretPw
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF

rpi ~# chmod 600 /etc/hostapd/hostapd.conf

Set DAEMON_CONF="/etc/hostapd/hostapd.conf" in /etc/default/hostapd with:

rpi ~# sed -i 's/^#DAEMON_CONF=.*$/DAEMON_CONF="\/etc\/hostapd\/hostapd.conf"/' /etc/default/hostapd
rpi ~# systemctl reboot

Then you have to set a static route in your internet router so it can find the route over the raspi to your mobile phone. On most internet router you can set a static route but how to do that varies from model to model. It's up to you to find it out. On a Raspberry Pi it would look like this (don't set it on your Raspi router!)

rpi ~$ sudo ip route add 192.168.1.0/24 via 192.168.0.2 dev ethX

That means for the internet router: "send all packets belonging to subnet 192.168.1.0/24 (destination network) to the next router on my subnet, your raspi-router 192.168.0.2 (gateway). It knows where to go on."

If you have no access to the internet router you can fake it with nat to tell it a lie that all packets are coming from your raspi. Set this on your Raspberry Pi:

rpi ~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

But this should only be the second choise because it's not clean routing and has limitations and may be confusing.

If you connect now your mobile phone to MyTestAP configure it with a static ip address 192.168.1.2, gateway 192.168.1.1. Then you should be able to connect to the internet.

The setting is:

rpi ~$ ip addr   # stripped to relevant information
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.0.2/24 brd 192.168.0.255 scope global eth0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.1.1/24 brd 192.168.1.255 scope global wlan0

rpi ~$ ip route
default via 192.168.0.1 dev eth0 proto static
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1

Now I establish a vpn connection e.g. with:

rpi ~$ sudo openvpn myVpn.conf

The setting then is:

rpi ~$ ip addr   # stripped to relevant information
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.0.2/24 brd 192.168.0.255 scope global eth0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.1.1/24 brd 192.168.1.255 scope global wlan0
11: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.10.10.2 peer 10.10.10.1/32 scope global tun0

rpi ~$ ip route
default via 192.168.0.1 dev eth0 proto static
10.0.0.0/8 via 10.10.10.1 dev tun0
10.10.10.1 dev tun0 proto kernel scope link src 10.10.10.2
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1

Here we should also set static routes in the remote vpn server but I think we don't have any chance to do that. So we only can fake the server with a nat. On the raspi set:

rpi ~$ sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Now I was able to get always into the internet with my mobile phone through the wifi, but only to the vpn network if its connection was established.


references:
[1] dhcpcd vs /etc/network/interfaces
[2] Setting up a Raspberry Pi as an access point

  • +1 for $ sudo -Es – Fabian May 8 '18 at 6:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.