Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Raspberry Pi 3B/B+ Wireless Bridge using Ubuntu Server 18.04 ARM Image and Netplan

Raspberry Pi 3B/B+ Wireless Bridge using Ubuntu Server 18.04 ARM Image and Netplan

This could sound very easy to do at first but it wasn't... The reason of that is due to the lack of proper documentation on the practical usage of netplan. Many peoples decided to drop it and go back to the previous way to setup the network.

But I'm someone obstinate, so I decided to challenge myself and being able to do with netplan and not go back to ifupdown even if, close to the end, I though I could never got it working... Finaly it worked and much better than the replaced equipment.

Initial project goal

The initial goal of this project was to use the raspberry pi in place of my Wireless Range Extender and then going from 3 wireless networks (2.4ghz, 2.4ghz extended, 5ghz) at home to only 2 (2.4ghz and 5ghz). This way I'm reducing the exposition to radio waves for the whole familly at home.

Let's go technical

Ok, enough drama for now, let's go technical. ๐Ÿ˜

Setup

To make your Wireless Bridge, you'll need to have few hours as free time and the following hardware:

OS Install

Just write the downloaded image on the SD card and follow this procedure.

The image for the 3B+ can be used on a 3B but this would need to include DTB files on the boot partition.

Using the new image, both ethernet and wireless network interfaces are available

If you need to patch firmware files, it is explained here: https://wiki.ubuntu.com/ARM/RaspberryPi#WiFi

  1. Power your screen on
  2. Plug the HDMI cable
  3. Plug the network cable
  4. Put the Micro SD card
  5. Plug the power cable
  6. Wait the initial boot to finish
  7. Define your password (Default one is: user: ubuntu / pass: ubuntu)

For Raspberry Pi 3b+ only: It seems like the image was modified and the sudo don't ask for password... there are also few local package diversions that were added. I'll explain how to remove them later in this gist.

Partition resize

I forgot to resize the sd card partition, so the system got crashed, don't forget to do that...

Follow the procedure explained here: https://raspberrypi.stackexchange.com/questions/499/how-can-i-resize-my-root-partition

Not required for the Raspberry Pi 3B+ image, run df -h to see how much free space you have to decide if you need to resize your root partition.

Using netplan to setup the network interfaces

Now check your interfaces names with ip link show or iwconfig. You'll need them to create the configuration required for netplan.

So, edit the file /etc/netplan/your-config-file.yaml and add or change the following:

# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    renderer: networkd
    #renderer: NetworkManager
    ethernets:
        eth0:
            optional: true
            dhcp4: false
    wifis:
        wlan0:
            optional: true
            access-points:
                "YOUR-SSID-NAME":
                    password: "YOUR-PASSWORD"
            dhcp4: true
            #dhcp-identifier: mac # uncomment this line if you're using a Microsoft DHCP Server

Try to run the test again while commenting out the lines

Once done, test, generate and apply the config that way:

  • Testing: sudo netplan --debug try (continue even if successful)
  • Generate: sudo netplan --debug generate (will give you more details in case of issues with the previous command)
  • Apply: sudo netplan --debug apply (if no issues during the previous commands, you can start to enjoy ๐Ÿ˜)

Define the wireless country code!!

I've forgotten to do that at first try and trust me I wasted around 5 hours before thinking about that...

Edit the file /etc/default/crda and change it that way:

# Define your country code here as explained above or in this format if not explained:
# ISO/IEC 3166-1 alpha2 country code
REGDOMAIN=CH

Then save the file.

Note that it is only required when using NetworkManager as renderer in the netplan config file.

The is only required if you don't have them already installed. you might need to adapt your netplan config file in order to have an internet connection before continuing.

Remove local-diversions (for Raspberry Pi 3B+ image only)

The image creator might had trouble with the wireless card or wired card drivers so he/she fixed the package files versions by using dpkg-divert. This will keep your file version but will also break any package upddate tentatives.

You can remove them by running these commands:

# Become root
sudo su

# List all 'local' diversions
dpkg-divert --list | grep local

# Run this loop to remove them all
for FILE in $(dpkg-divert --list | grep local | cut -d' ' -f4); do dpkg-divert --remove $FILE; done

I still need to find out how to restore the 'normal' sudo behavior and restore the password asking method.

OS Update

Now that your network config is done, the first thing to do is to update the whole system. Nothing really difficult, just run these commands:

sudo apt update && sudo apt dist-upgrade

If case of outdated package definitions, replace the command by this one: sudo apt update --fix-missing -y && sudo apt dist-upgrade

Install required packages

You will need to install some packages which are not included by default in Ubuntu Server 18.04.

sudo apt install wireless-tools wpasupplicant openssh-server

Now install the required bridging packages:

sudo apt install parprouted dhcp-helper avahi-daemon

Enable DHCP relay: /etc/default/dhcp-helper

# relay dhcp requests as broadcast to wlan0
DHCPHELPER_OPTS="-b wlan0"

Edit /etc/avahi/avahi-daemon.conf to enable mDNS relaying:

[reflector]
enable-reflector=yes

Now... The nasty stuffs... ๐Ÿ˜…

You'll have to create an extra systemd service file and place it in /lib/systemd/system/.

Add some debug stuff into the wpa_supplicant service file

To make sure that everything is running correctly and having more info in case of issues, create a log file for the WPA process.

Open the file /lib/systemd/system/wpa_supplicant.service and this -dd -f /tmp/wpa.log to the end of the ExecStart line:

# ExecStart=/sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
ExecStart=/sbin/wpa_supplicant -u -s -O /run/wpa_supplicant -dd -f /tmp/wpa.log

This does not seems to work with netplan, you might need to kill the existing process and reload it with the given parameters above.

Do this only in case you have wireless network issues or for debugging purpose.

I've to /tmp/wpa.log to avoid useless storage space consumption.

ARP Bridge service files

Create the service file and name it /lib/systemd/system/arp-bridge.service then put this content:

[Unit]
Description=ARP Bridge over Wireless Interface
Wants=network-online.target
After=network-online.target

[Service]
Type=idle
RemainAfterExit=yes
ExecStart=/lib/systemd/system/set-arp-routing

[Install]
WantedBy=multi-user.target

Create the starting script and name it /lib/systemd/system/set-arp-routing then put this content:

#!/bin/bash

## Start Process
ETHERNET_IFACE=eth0
WIRELESS_IFACE=wlan0

## Setup system forwarding
echo "Enable IP forwarding"
echo 1 > /proc/sys/net/ipv4/ip_forward
## Uncomment lines below if you don't want to use parprouted.
#echo "Enable ARP forwarding"
# Comment for all interfaces
#echo 1 > /proc/sys/net/ipv4/conf/${WIRELESS_IFACE}/proxy_arp
# Uncomment for all interfaces
#echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp

## Fix the 'eth0' interface that don't want to mount at boot on 3b+
## Uncomment this part if the 'eth0' interface is not mounted at boot
#/usr/sbin/netplan apply

## A little sleep
sleep 5

## Assign address
echo "Cloning IP from ${WIRELESS_IFACE} to ${ETHERNET_IFACE}"
/sbin/ip addr add $(/sbin/ip addr show $WIRELESS_IFACE | perl -wne 'm|^\s+inet (.*)/| && print $1')/32 dev $ETHERNET_IFACE

## Uncomment lines below in case you're encountering the same issues
#echo "Removing bad APIPA IP from ${ETHERNET_IFACE}"
#/sbin/ip addr del $(/sbin/ip addr show $ETHERNET_IFACE | perl -wne 'm|^\s+inet (169.254.*)/| && print $1')/16 dev $ETHERNET_IFACE
#echo "Removing bad APIPA route from ${ETHERNET_IFACE}"
#/sbin/ip route del 169.254.0.0/16 dev $ETHERNET_IFACE

## Make sure that the eth0 interface is up
echo "Setting up lan interface"
/sbin/ip link set $ETHERNET_IFACE up

## Setup ARP forwarding
echo "Starting paraprouted"
/usr/bin/killall -KILL parprouted 2> /dev/null
/usr/sbin/parprouted $ETHERNET_IFACE $WIRELESS_IFACE

## Reloading DHCP Relay
echo "Start / Reload DHCP Relay"
/bin/systemctl restart dhcp-helper

## A little sleep
sleep 5

## Refresh local ARP cache
/sbin/ip -s -s neigh flush all

## Disable wireless power management
## Uncomment if your wireless speed is too low
#/sbin/iwconfig $WIRELESS_IFACE power off

## Not related to network at all but useful for me,
## as my keyboard does not have an English layout.
## Uncomment if you find it useful too.
#sudo loadkeys ch

## End Process

set starting script as executable:

sudo chmod -v +x /lib/systemd/system/set-arp-routing

Now save everything and check if everything is correctly setup:

sudo systemctl daemon-reload
sudo systemctl restart wpa_supplicant.service
sudo systemctl enable arp-bridge.service
sudo systemctl start arp-bridge.service
sudo systemctl restart dhcp-helper.service
systemctl status wpa_supplicant.service arp-bridge.service dhcp-helper.service
tail -f /tmp/wpa.log

or cat /tmp/wpa.log

Try to ping any host you know and if that works then you can reboot to verify if all the proces is mounted correctly at boot time.

sudo reboot

Watch the boot process to check if you got some issues...

If you don't and everything is working for you, trust me, you're ... lucky ๐Ÿ‘.

Now log into the bridge using SSH if you're working remotely now or normally from screen. ๐Ÿ˜

Bonus: Speedtest!

If you want to test the speed of your wireless bridge, you can use the script speedtest-cli that way:

python <(curl -Ss https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py) --secure

The --secure argument is to use HTTPS instead HTTP during the test, feel free to remove it.

Main issue: ethernet not up

Sometimes the LAN interface is not started, the following might solve this issue:

  • sudo netplan --debug apply or,
  • sudo ip link set eth0 up (change eth0 by your interface)

Really useful commands for debugging

During my debugging process I used these commands to help me to solve all encountered issues:

sudo loadkeys keyboard_country_code
sudo lshw
ifconfig
iwconfig
iw list
iw dev
iw phy
sudo iw dev wlan0 scan sched_stop
sudo iw dev wlan0 scan
ip link show
ip a
ip route
sudo rfkill list
sudo rfkill unblock wifi
networkctl
journalctl -b
journalctl -f
dmesg
dmesg -w
sudo wpa_cli status
sudo wpa_cli interface_list
sudo netstat -s | egrep -i 'loss|retran'
host -a google.com
host -a ubuntu.com
iwlist 
iwlist wlan0
sudo iwlist wlan0 scan
sudo iwlist wlan0 scan | grep ESSID
locate wpa
sudo ip link set wlan0 down
sudo ip link set wlan0 up
sudo iw reg get
sudo iw reg set CH
sudo nmcli radio wifi on
sudo nmtui
nmcli dev show wlan0
nmcli device wifi
nmcli device wifi rescan
sudo iwlist wlan0 scan
arp -avn
sudo su -c 'echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp'
sudo su -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
sudo sysctl -a | grep forward
sudo sysctl -a | grep proxy
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.all.proxy_arp=1

Used debug script

During my research, I've found this debugging script: https://github.com/UbuntuForums/wireless-info/raw/master/wireless-info

Use it as follow:

wget https://github.com/UbuntuForums/wireless-info/raw/master/wireless-info && chmod +x wireless-info && ./wireless-info

Reply 'no' to not upload results outside

Show the report:

less wireless-info.txt

You should not plug 2 wireless bridges on the same switch, Never!

It was another hard lesson that I've learned during this project / gist, never plug several bridges on the same switch, it will just create massive TPC/UDP retransmission and ARP flood... ๐Ÿ˜“

Story

Well... I must tell you that I've passed around 3 days in reading, testing, debugging and getting crazy then finaly make it working ๐Ÿ˜….

And even more to understand why my not all of my DHCP requests were not relayed to the my main DHCP Server on the router... But after many days of testing and research I was finally able to find why. More details here https://twitter.com/Jiab77/status/1107535593741922304

I really hope that you'll be able to make the whole process working on your side.

Feel free to comment this gist for improvements or if you're having troubles ๐Ÿ‘.

References

During my research it was really difficult to find up-to-date, clean and working documentation so I had to grab and mix many of them to write this gist. (no specific order)

  1. https://wiki.ubuntu.com/ARM/RaspberryPi
  2. https://ubuntuforums.org/showthread.php?t=2274207
  3. https://wiki.debian.org/BridgeNetworkConnectionsProxyArp
  4. https://github.com/balena-io-playground/balena-bridge/blob/master/start.sh
  5. https://www.freedesktop.org/software/systemd/man/systemd.exec.html
  6. https://www.freedesktop.org/software/systemd/man/systemd.service.html
  7. https://unix.stackexchange.com/questions/348450/confused-by-execstartpre-entries-in-systemd-unit-file
  8. https://netplan.io/faq#use-pre-up-post-up-etc-hook-scripts
  9. https://hk.saowen.com/a/873f9d84ef3c295c9ea73174de8758f972d73e32434d6c332ddd72bd2a4e4441
  10. https://unix.stackexchange.com/questions/126009/cause-a-script-to-execute-after-networking-has-started
  11. https://websiteforstudents.com/configure-static-ip-addresses-on-ubuntu-18-04-beta/
  12. https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6
  13. https://bbs.archlinux.org/viewtopic.php?id=230785
  14. https://www.tecmint.com/create-new-service-units-in-systemd/
  15. https://unix.stackexchange.com/questions/319267/systemd-how-to-make-a-systemd-service-start-after-network-fully-connected/319330
  16. https://superuser.com/questions/544399/how-do-you-make-a-systemd-service-as-the-last-service-on-boot
  17. https://www.cyberciti.biz/faq/howto-set-sysctl-variables/
  18. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_MRG/1.3/html/Realtime_Tuning_Guide/sect-Realtime_Tuning_Guide-General_System_Tuning-Setting_persistent_tuning_parameters.html
  19. https://linuxize.com/post/how-to-change-hostname-on-ubuntu-18-04/
  20. https://cloudinit.readthedocs.io/en/latest/topics/network-config.html
  21. https://pimylifeup.com/raspberry-pi-wifi-bridge/
  22. https://medium.com/a-swift-misadventure/how-to-setup-your-raspberry-pi-2-3-with-ubuntu-16-04-without-cables-headlessly-9e3eaad32c01
  23. https://askubuntu.com/questions/1045389/ubuntu-18-on-raspberry-pi-3b-stuck-on-networking-service-after-converting-the-o
  24. https://askubuntu.com/questions/1071517/trying-to-install-18-04-classic-on-pi-3-b-close-but-not-quite-there?rq=1
  25. https://ubuntu-mate.community/t/aarch64-on-raspberry-pi-2-rev-1-2-3b-3b/16853 (very important for model 3b+)
  26. https://1drv.ms/u/s!AvHY_kl4hMB4gQIR4CLRKQzh-GP0 (xubuntu image file used for model 3b+)
  27. https://raspberrypi.stackexchange.com/questions/499/how-can-i-resize-my-root-partition
  28. https://github.com/AbelCS/ubuntu-server-bionic-rpi-3-b-plus (new testing image)
  29. https://community.arubanetworks.com/t5/Controller-Based-WLANs/DHCP-packet-flow-with-bootp-flag-set-to-broadcast-vs-unicast/ta-p/425012
  30. https://superuser.com/questions/472594/dhcp-broadcast-flag/472607#472607
  31. https://www.ietf.org/rfc/rfc2131.txt

Made with โค๏ธ and A LOT of โ˜•๏ธ!! by @jiab77

#!/bin/bash
## Start Process
ETHERNET_IFACE=eth0
WIRELESS_IFACE=wlan0
## Setup system forwarding
echo "Enable IP forwarding"
echo 1 > /proc/sys/net/ipv4/ip_forward
## Uncomment lines below if you don't want to use parprouted.
#echo "Enable ARP forwarding"
# Comment for all interfaces
#echo 1 > /proc/sys/net/ipv4/conf/${WIRELESS_IFACE}/proxy_arp
# Uncomment for all interfaces
#echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
## Fix the 'eth0' interface that don't want to mount at boot on 3b+
## Uncomment this part if the 'eth0' interface is not mounted at boot
#/usr/sbin/netplan apply
## A little sleep
sleep 5
## Assign address
echo "Cloning IP from ${WIRELESS_IFACE} to ${ETHERNET_IFACE}"
/sbin/ip addr add $(/sbin/ip addr show $WIRELESS_IFACE | perl -wne 'm|^\s+inet (.*)/| && print $1')/32 dev $ETHERNET_IFACE
## Uncomment lines below in case you're encountering the same issues
#echo "Removing bad APIPA IP from ${ETHERNET_IFACE}"
#/sbin/ip addr del $(/sbin/ip addr show $ETHERNET_IFACE | perl -wne 'm|^\s+inet (169.254.*)/| && print $1')/16 dev $ETHERNET_IFACE
#echo "Removing bad APIPA route from ${ETHERNET_IFACE}"
#/sbin/ip route del 169.254.0.0/16 dev $ETHERNET_IFACE
## Make sure that the eth0 interface is up
echo "Setting up lan interface"
/sbin/ip link set $ETHERNET_IFACE up
## Setup ARP forwarding
echo "Starting paraprouted"
/usr/bin/killall -KILL parprouted 2> /dev/null
/usr/sbin/parprouted $ETHERNET_IFACE $WIRELESS_IFACE
## Reloading DHCP Relay
echo "Start / Reload DHCP Relay"
/bin/systemctl restart dhcp-helper
## A little sleep
sleep 5
## Refresh local ARP cache
/sbin/ip -s -s neigh flush all
## Disable wireless power management
## Uncomment if your wireless speed is too low
#/sbin/iwconfig $WIRELESS_IFACE power off
## Not related to network at all but useful for me,
## as my keyboard does not have an English layout.
## Uncomment if you find it useful too.
#sudo loadkeys ch
## End Process
@Jiab77

This comment has been minimized.

Copy link
Owner Author

commented Nov 4, 2018

In case you wanted used files directly, check the revisions. I just removed them for better indexing... ๐Ÿ™„

@Jiab77

This comment has been minimized.

Copy link
Owner Author

commented Jul 2, 2019

The routing script has been updated and now use interfaces as variables to it will ease the further changes.

@fahadsiddiqui

This comment has been minimized.

Copy link

commented Jul 27, 2019

Wow, perfect!

@Jiab77

This comment has been minimized.

Copy link
Owner Author

commented Aug 8, 2019

@fahadsiddiqui glad you liked it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You canโ€™t perform that action at this time.