1

I want to use my Pi as a fully fledged wifi and ethernet router. I'll connect an external modem/phone with tethering to it and want to share that internet connection with all devices connected to the same ethernet switch as the Pi as well as to all devices connected to the Pi via its own wifi hotspot. The devices also need to be able to communicate amongst each other and the Pi still needs to be online itself. I know that this has to work, but I keep failing when taking different approaches:

I'm using a Pi 3B with the latest Debian Stretch image, fully updated.

  1. USB tethering works out of the box - the Pi is online.
  2. Using a slightly modified version of this script (basically using usb0 instead of wlan0) allows me to share the connection with other systems on the same network - great!
  3. Now comes the difficult part. I have managed to successfully set up an access point using the many instructions online and hostapd, however I still need a dhcp server without messing up the dhcp client that gets the IP from the tethered phone initially. For example, when preparing to set up the dhcp server, I need to set wlan0 interface to be configured with a static IP, but once I do that, the dhcp client refuses to work and I lose the internet connection.
3
  • Are you connecting the PI to the phone via USB or via WLAN? You write that USB tethering works and brings the PI online, but changing the wlan0 configuration breaks your connection. You may want to set up an Ethernet Bridge and leave the DHCP to the phone. – RalfFriedl Jun 13 '19 at 20:34
  • I'm connecting the phone using USB. The problem I found is a general one, that the DHCP client dhcpcd will refuse to get an IP address from the phone once ANY interface ist configured to use a static IP (“Not running dhcpcd because /etc/network/interfaces defines some interfaces that will use a DHCP client or static address”), and I have to give the wlan0 interface a static IP so that it can act as an access point. If I understand correctly, you are suggesting to let the phone be the DHCP for the entire network, which sounds fine, but how to do that? – Andreas Hartmann Jun 13 '19 at 20:45
  • Have you tried searching for that message? I found unix.stackexchange.com/questions/501309/… and raspberrypi.stackexchange.com/questions/49502/…. – RalfFriedl Jun 13 '19 at 20:59
3
+50

Seems there are to many components that have to play together: dhcpcd, ifupdown, hostapd and maybe dnsmasq and bridge-utils. I have a suggestion to reduce complexity with using systemd-networkd. It is available by default on Raspbian and has everything built-in, no need to install any additional helpers.

Last tested on a Raspberry Pi 4B with
Raspberry Pi OS (32-bit) 2020-12-02 based on Buster updated on 2020-12-23.
Updates done with sudo apt update && sudo apt full-upgrade && sudo reboot.

Here is a setup with a bridge:

     (dhcp
    from RPi)       bridge
      ╱    wifi    ┌───────┐
station <~.~.~.~.> │(wlan0)│          usb tether              wan
                   │    br0│RPi(usb0) <--------> modem/phone <───> INTERNET
 laptop <────────> |(eth0) │╲       ╲
      ╲    wired   └───────┘╱      (dhcp
    (dhcp             192.168.4.1  from modem/phone)
   from RPi)

Here in short the steps. First switch over to systemd-networkd. Just follow to

Use systemd-networkd for general networking.
You can use section "♦ Quick Step". Then come back here.

Configure wpa_supplicant as access point. Create this file with your settings for country=, ssid=, psk= and maybe frequency=. You can just copy and paste this in one block to your command line beginning with cat and including both EOF (delimiter EOF will not get part of the file):

rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
update_config=1
p2p_disabled=1
country=DE

network={
    ssid="RPiNet"
    mode=2
    key_mgmt=WPA-PSK
    proto=RSN WPA
    psk="password"
    frequency=2437
}
EOF

rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable wpa_supplicant@wlan0.service
rpi ~# rfkill unblock wlan

Configure interfaces by creating these files:

rpi ~# cat > /etc/systemd/network/02-br0.netdev <<EOF
[NetDev]
Name=br0
Kind=bridge
EOF

rpi ~# cat > /etc/systemd/network/04-br0_add-eth0.network <<EOF
[Match]
Name=eth0
[Network]
Bridge=br0
EOF

rpi ~# cat > /etc/systemd/network/10-usb0.network <<EOF
[Match]
Name=usb0
[Network]
DHCP=ipv4
EOF

rpi ~# cat > /etc/systemd/network/12-br0_up.network <<EOF
[Match]
Name=br0

[Network]
LLMNR=no
MulticastDNS=yes
IPMasquerade=yes
Address=192.168.4.1/24
DHCPServer=yes

[DHCPServer]
DNS=84.200.69.80 1.1.1.1
EOF

Please ensure that the ip address(range) 192.168.4.0/24 (or whatever do you use) does not match the same subnet that you get from your USB tethering device.

Now we have to tell wpa_supplicant to use a bridge. We do it by modifying its service with:

rpi ~# systemctl edit wpa_supplicant@wlan0.service

In the empty editor insert these statements, save them and quit the editor:

[Service]
ExecStartPre=/sbin/iw dev %i set type __ap
ExecStartPre=/bin/ip link set %i 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 %i nomaster
ExecStopPost=-/sbin/iw dev %i set type managed

Reboot and it should do.

References:
Setting up a Raspberry Pi as an access point - the easy way
Access point as WiFi repeater, optional with bridge

3
  • Wow, thanks for the effort! I'll try it and report back. – Andreas Hartmann Jun 14 '19 at 14:53
  • @AndreasHartmann It is mostly copy and paste and a bit testing :-) Look at the references. – Ingo Jun 14 '19 at 14:55
  • Thanks, it worked perfectly. I didn't even know systemd could do that. Will reward an extra bounty for this in 24 hours when it's possible. – Andreas Hartmann Jun 16 '19 at 19:32

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.