A Raspberry Pi as a wireless bridge for old hardware
This is something I did a couple of months back, but figure it's worth documenting, to maybe help anyone with a similar problem search for it.
One use for my Raspberry Pi is as a wireless bridge, and this is mainly for a now ancient Xbox 360. Yes, the one without built-in wifi, it just has an Ethernet port for networking; not much good when your router is nowhere near a TV.
Originally, and as is often customary when solving technology problems, I used instructions that I cobbled together from various places.
I'd been slack on upgrading my Raspberry Pi's Raspbian. It was working perfectly fine for what it was doing, so there was no immediate need to touch it. Because of this, it has languished on a distribution based on the now aging Debian Wheezy.
More recently, with the recent WPA2 exploit in October, and the then lack of any as-yet patch even for Debian Wheezy (which has since been patched, not sure about Raspbian itself), I thought I should finally upgrade, so the Pi was patched against this and any other future security issues.
I didn't particularly want to go to the trouble of doing a fresh install, so I tried an in-place operating system upgrade, deciding that the worst that could happen is the upgrade fails and I'd have to do a fresh install anyway.
The upgrade process
I actually upgraded in two stages. First from Wheezy to Jessie, and then I figured if that went OK, I could try upgrading again, from Jessie to Stretch too.
Upgrading the distribution actually worked well. With my Raspbian Wheezy install, I upgraded to Jessie as described on the Raspberry Pi forum. Everything seemed to work, including the Xbox's internet connection.
Since I was feeling brave, I decided to upgrade again. However, I didn't
feel so brave that I would do that without first backing up the working
system, so I backed up the SD card with
dd
to a gzipped
image in case something went wrong and I could recover a working system
quickly.
Next, I upgraded from Jessie to Stretch. This is the same process as for Wheezy to Jessie, just with different repository sources used.
Once again, the upgrade worked fine, the Pi booted up, and I could connect to it wirelessly.
A stretch too far
But, the Xbox's internet connection no longer worked. Checking the Pi, I spotted what looked like error messages appearing at boot time.
The first problem is checking the boot log messages that quickly
disappear from the screen. Since Debian now uses systemd, you need sudo
systemctl
to review those messages.
What I spotted there is that there was an error that indicated that
commands I had in rc.local
were not running correctly. As mentioned,
in my description of my Xbox and Pi
configuration, I was
using rc.local
to run the commands on boot that ensured the bridge
worked, instead of having to run anything by hand every boot.
That seemed strange. More so when running the script by hand caused it to work as normal, which allowed the Xbox to once again connect to the internet as it did on Raspbian Jessie.
Why did this script fail on boot via rc.local
? As mentioned on the
Raspberry Pi
forums,
the difference presumably is that the Pi's networking isn't configured
at the time of the script trying to run. Trying to then change this
configuration when it's not ready will then fail.
So there are no guarantees about when rc.local
is run. If you have
dependencies on other things, the moral of this longish story is that
you should create a systemd service and have systemd launch it after
everything else; this fixed the problem and everything finally was
working again.
Configuration
For reference, here's what I have configured:
wireless_bridge.sh
is saved in /usr/local/sbin
, with 755 file
permissions, root as owner and group, and contains:
#!/bin/sh -e
/usr/sbin/ifplugd eth0 --kill
/sbin/sysctl -w net.ipv4.ip_forward=1
/sbin/ifconfig eth0 192.168.1.1
/sbin/iptables -t nat -A POSTROUTING -o wlan0 -s 192.168.1.0/24 -j MASQUERADE
wireless-bridge.service
is saved in /etc/systemd/system
, with 644
file permissions, root as owner and group, and contains:
[Unit]
Description=Wireless Bridge Service
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/local/sbin/wireless_bridge.sh
[Install]
WantedBy=multi-user.target
You could possibly change multi-user.target
to one of systemd's
network
targets,
but I didn't bother testing this out, as the configuration above just
seemed to work (with, I suppose, the possible cost of the bridged
connection not being available until slightly later).
I also have the Xbox network settings as:
IP address: 192.168.1.2
Subnet mask: 255.255.255.0
Gateway: 192.168.1.1
and the primary DNS server set to my router's IP address.