aoakley.com

Raspberry Pi Networking - Switching between wired and wireless networks in Raspbian & Debian

Quite often I want to run my Raspberry Pis "headless" - that is to say, without a keyboard, mouse or monitor. That means I have to manage without the desktop tools to configure the network; I have to use the command-line network tools over an SSH connection.

Another problem I have is that I want the Raspberry Pi to use a static IP if it's in my house - with no monitor, I can't read the IP address off the screen, so the IP address needs to stay the same so I know where to connect to. However if I'm taking it elsewhere, I want to be able to quickly and easily configure it for another wireless network.

Here's my assumptions:

Static IP on some WiFi connections but dynamic on others

Let's deal with the easy problem first; static IPs on some WiFi connections but dynamic on others. This is done by setting an id_str in the /etc/wpa_supplicant/wpa_supplicant.conf file:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
 
network={
ssid="aoakley-home"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="PASSWORD"
id_str="aoakley-home"
}
 
network={
ssid="PlusnetWireless9AAAA9"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="PASSWORD"
id_str="inlaws"
}
 
network={
ssid="aoakley-mifi"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="PASSWORD"
id_str="aoakley-mifi"
}

In the wpa_supplicant.conf file above, we have three known WiFi networks, all with WPA-PSK security; aoakley-home , PlusnetWireless9AAAA9 and aoakley-mifi . Each has been given an id_str so they can be identified in the /etc/network/interfaces file. For aoakley-home and aoakley-mifi I've set the id_str the same as the ssid , but for ease of identification, I've set the id_str of the Plusnet connection at my wife's parents' house to id_str="inlaws" (there are a lot of Plusnet WiFi routers out there - no doubt another will join my list soon).

You'll need to customise this wpa_supplicant.conf file to represent your known WiFi networks. If your Pi never leaves home, then you'll probably just have one WiFi network listed - but make sure it has an id_str.

We can then refer to this id_str in the /etc/network/interfaces file:

auto lo
iface lo inet loopback
 

(your eth0 setup stays here)
 
auto wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
iface aoakley-home inet static
address 192.168.0.5
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.254

You'll notice in the settings above, that I have defined a static IP for aoakley-home , but nothing for any of the other id_strs. Any id_str which is not mentioned in /etc/network/interfaces will use the default setting, which in my config is DHCP: iface default inet dhcp

You'll need to customise the address, netmask, network, broadcast and gateway settings so that they are suitable for your home LAN. For example, your LAN might use 192.168.1.xxx rather than 192.168.0.xxx . You can usually find this information in your broadband router manual.

Reboot with shutdown -r now and it's job done. We now have a static IP for the aoakley-home WiFi network, but dynamic IP everywhere else, and we can quickly and easily add new WiFi networks to wpa_supplicant.conf without having to reconfigure anything else.

Turning off WiFi when a wired network cable is plugged in

I want the same static IP at home regardless of whether I'm using WiFi or a wired network cable. However, if both the eth0 and wlan0 interfaces try to use the same IP address at the same time, this can cause a lot of problems; usually an unresponsive network.

There are a gazillion ways around this problem. Look up "Linux route metrics" if you want to learn the hard-core way of doing it. My solution is a lot more simple: turn off WiFi if a wired network cable is inserted.

The ifplugd daemon provides a neat foundation that we can build on. If your eth0 interface is declared as hot-pluggable, ifplugd runs a special script whenever a cable is inserted or removed. We can customise this script to turn the wlan0 interface off or on.

Recent distributions of Raspbian have ifplugd installed by default. If you don't have it (for example, if type ifplugd tells you "not found"), you can use apt-get install ifplugd to install it. If the installer prompts you to configure it, accept the default configuration values of auto for static interfaces and all for hotplugged interfaces. If you mess this up, you can use dpkg-reconfigure ifplugd to correct the configuration at any time.

Let's start by customising the /etc/ifplugd/action.d/ifupdown script:

#!/bin/sh
set -e
 
case "$2" in
up)
  /sbin/ifup $1
  if [ "$1" == eth0 ]; then /sbin/ifdown wlan0 ; fi
# This is a new bit
  ;;
down)
  /sbin/ifdown $1
  if [ "$1" == eth0 ]; then /sbin/ifup wlan0 ; fi
# Another new bit
  ;;
esac

Next, we need to make sure that eth0 is defined as allow-hotplug in /etc/network/interfaces file, and set up the static IP address for eth0 to be the same as the wlan0 interface.

auto lo
iface lo inet loopback
 
allow-hotplug eth0
iface eth0 inet static
address 192.168.0.5
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.254
 
auto wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
iface aoakley-home inet static
address 192.168.0.5
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.254

I'll repeat my previous bit of advice here: don't set the wlan0 interface as hot-pluggable, as in any case, most attempts to remove or re-insert a USB WiFi adaptor whilst your Raspberry Pi is switched on, will probably result in your Pi rebooting (or worse, not rebooting... ever... and a puff of magic smoke). My guess is that this is because a USB WiFi adaptor consumes a lot more milliamps than a mouse or a keyboard, and the Pi is already pretty sensitive to amperage fluctuations. It's a twenty-five quid computer; if you need to remove or insert the WiFi adaptor, just shut down the Pi first. The auto parameter for wlan0 defines the WiFi interface as something that should be brought up at boot time and not disconnected until shutdown. However if the dongle isn't there, the Pi will continue to boot without it.

Reboot with shutdown -r now , and you should be done.

If it all goes wrong, restore your backup, or connect a screen to see what's happening, or put the SD card in a desktop/laptop Linux PC and examine the /etc files there.

By the way, this setup has also been tested on a Raspberry Pi Model A which doesn't have an eth0 interface at all. It'll boot up and connect to WiFi just fine, so if you have lots of Raspberry Pis, you can use this recipe for all of them.

Public Domain - Andrew Oakley - 2013-07-31

Top - More Computing Articles - Article Index - aoakley.com