phil@dler

Raspberry Pi WiFi AP, (without weird errors)

Followers of my blog will know that I have already been having some misadventures with the Raspberry Pi. Having failed to carry off being a recording device, I tried the Rapsberry Pi 3 out as a wireless access point.

It should be noted that a wireless access point is subtly different, but related to, a router. I was going to begin by trying to clarify that difference, but actually it turns out that these things are generally defined fairly poorly, and there’s a lot of confusing terminology flying around. Suffice it to say that being a router implies some level of decision making in where information is sent, and being an access point does not, although neither of those statements is strictly true overall.

In concrete terms and for our purposes, the Raspberry Pi does not need to know how to assign addresses to computers, it simply needs to be able to speak to computers using the wi-fi adapter, and share its ethernet cable connection with those computers. This process is commonly called bridging.

However, I pieced together the following recipe for how to do this for most linux systems from a guide by “Sir Lags”, which actually contained some superfluous settings, which for me only added confusion, and didn’t contain some key points – the setup described there is prone to simply stopping working after a short time, and giving the thoroughly unhelpful error message in the logs: kevent 0 may have dropped.

We are, since we are talking about the Raspberry Pi 3, going to assume that this is the device we are using as a wireless access point. These things are always subject to change over time, of course, but this should be an accurate description of proceedings for the raspbian distribution codenamed “Jessie”.

So, we shall begin by installing some necessary software components by typing sudo apt-get install bridge-utils hostapd at the command line

For those who have gotten used to running their Raspberry Pi over the network in a headless configuration and haven’t generally tinkered with the network settings before, it’s generally best to do this with a keyboard and monitor plugged into the Pi itself. And a mouse if you’re the kind of person who likes clicking on things because you live in the 21st century (unlike me).

The configuration for your network interfaces lives inside the file /etc/network/interfaces (imaginitively).

Now, if memory serves, the default looks something like:

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

allow-hotplug wlan1
iface wlan1 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

So what do we have here? Each line that begins with iface defines a network interface. eth0, for instance, is the ethernet port. wlan0 is the wireless adapter. I’ve not yet figured what wlan1 is about, since the model 3B pi only comes with one wireless adapter inbuilt as far as I can tell.

lo is the loopback interface, which isn’t a physical switch but tells the computer how to talk to itself. Quite why this is defined I’ve never fully understood, since I’ve always seen it set up the same way.

auto, followed by an interface identifier tells the networking software to activate (often referred to as bringing up) that interface when the computer boots.

allow-hotplug allows the interface to be activated by specific events registered by the system. Things like being plugged in for ethernet interfaces.

Then there is manual. Manual? Huh? But when we start the Pi, it configures the networks automagically. What’s going on?

Pay careful attention to the commented out lines at the top of the file telling you that this interfaces file is designed to work with dhcpcd (dhcp client daemon). Every interface defined as being a manual interface is set up by an external program, which is dhcpcd.

This actually causes us some problems with setting up the Pi as a wireless access point on the network, since most of the instructions, including the ones from which this post is adapted, require tinkering with the interfaces file in such a way that dhcpd does not assign ip addresses to interfaces marked as manual.

This is an archetype, by the way, of the kind of irritating design decision which plagues linux distributions. What should have happened is that dhcpcd be allowed to configure network interfaces marked dhcp, and then ignored everything else.

Sadly, we cannot simply ignore this, as we need to be able to control the interfaces using the interfaces file, rather than following other instructions and editing dhcpcd.conf. The latter lacks some features necessary for this task.

So, in order to disable dhcpcd, we enter sudo systemctl disable dhcpcd.service. This will disable the daemon and stop it from interfering with the process.

If you have tried this process following other guides and had seemingly random cutouts, this missing step may be why. Failing to perform this step also seems to give rise to the infuriatingly unhelpful error message kevent 0 may have dropped in the daemon and system log files.

Having disabled this service, we can get to the business of configuring our interfaces properly, mine looks (something) like this:

auto lo
iface lo inet loopback
address 127.0.0.1

iface eth0 inet static
address 192.168.1.254
gateway 192.168.1.253
netmask 255.255.255.0
broadcast 192.168.1.255
dns-nameserver 192.168.1.251

#allow-hotplug wlan0
iface wlan0 inet static
address 192.168.1.250
# wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface br0 inet static
address 192.168.1.249
gateway 192.168.1.253
netmask 255.255.255.0
broadcast 192.168.1.255
dns-nameserver 192.168.1.251

allow-hotplug wlan1
iface wlan1 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

The precise details of what the IP addresses are will depend on your own home setup. One important point to register is that if you have a DHCP server or (more often) a router which hands out IP addresses on your network, you need to tell that server/router to assign these IP addresses to the raspberry pi. How you go about this varies from router to router, but most will require the MAC address of the interface. Note therefore, that this will be a different MAC for the wifi interface and the ethernet interface. To find out the interface MAC addresses you can type ifconfig at the command prompt, it will be listed as the physical address.

The IP address of your gateway is normally the address of the router provided by your ISP; you can normally find that address on the configuration application for the router. Please consult your manual.

The broadcast IP address is a special IP address for sending datat to the whole network. This will also normally be available from your router, but the last number is almost universally 255.

And before any clever person starts pointing out that I haven’t started configuring my network for ipv6, that’s because my ISP hasn’t yet either, so I haven’t figured that out yet.

The dns-nameserver is the server which the computer uses to turn addresses like “www.example.com” into IP addresses. Again, if you’re unsure about this, a viable value is normally available from your router. Google also provide this service, with an address of 8.8.8.8 and 8.8.4.4, you may specify more than one nameserver.

br0 is what is termed a bridge interface, and we will use it to allow the free transfer of traffic between eth0 and wlan0. That is to say, we will be bridging the adapters. This functionality was brought in by the bridge-utils package.

Save the file. We’ll now want to edit a system setting to allow ipv4 fowarding. In the file /etc/sysctl.conf, edit the line containing #net.ipv4.ip_forward net.ipv4.ip_forward to read net.ipv4.ip_forward net.ipv4.ip_forward = 1. Save that.

Now we need to set up hostapd (host access point daemon), which we installed earlier. To do this we open /etc/default/hostapd, and find a line starting with DAEMON_CONF and adjust it to read DAEMON_CONF="/etc/hostapd/hostapd.conf".

Then (surprise, surprise) edit /etc/hostapd/hostapd.conf such that it reads:

interface=wlan0 # Listen on the wireless
bridge=br0
driver=nl80211

# WiFi configuration
ssid=yournetworknamehere
# The name of the network
hw_mode=g
# Wireless g, other modes are available.
channel=2
# Normally 1-11 or 1-14 depending on the region.
ht_capab=[HT40][SHORT-GI-20][DSS_CCK-40]
#Sets up the frequencies, apparently. Not sure how important this is tbh.
wpa=2 # This sets the security settings to WPA2
wpa_passphrase=raspiwlan #The password for the network
ignore_broadcast_ssid=0
#some people claim their network doesn’t show up without this.

wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
#We are requiring strong encryption,
#but we might want to change this to TKIP if we have difficulty.
rsn_pairwise=CCMP

Now reboot. I know linux can bring each thing up individually, but at this point it is easier.

Once rebooted, we open a command line and type:

ifup wlan0
ifup eth0
ifup br0
brctl add br0 eth0
brctl add br0 wlan0

This brings up the interfaces, and then adds the two physical interfaces to the bridge. And that should now work.