Part two with configs for Raspberry Pi 3 Access point.

Part 1 of the two part post I covered the basics for getting a Raspberry Pi 3 Access Point up and running. As promised the required packages, network config, and hostapd config below with some additional tips and tricks.

*** Note: The below config DOES NOT require modifying the internal firewall/iptables NAT setup.

After installing Raspbian on the SD card and booting up your Pi with Ethernet configured, make sure you do a full update that might take 20 minutes or so. I loaded the non-GUI Raspbian as I have no need for it since this will be a completely autonomous access point powered over Ethernet. Don’t forget to do an initial setup with the Raspbian handy utility.

sudo raspi-config
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install wireless-tools hostapd bridge-utils

Some handy additional installs for managing processes (htop), USB devices (lsusb), and WiFi devices (iw). You can concatenate these to the above command and do them in one go if you would like.

sudo apt-get install htop lsusb iw

For the record, and the YMMV disclaimer, the version of kernel I am running is (This is important when talking about drivers that may, or may not be, included in your kernel for USB WiFi dongles and such):

pi@piap:~ $ uname -a
Linux piap 4.4.21-v7+ #911 SMP Thu Sep 15 14:22:38 BST 2016 armv7l GNU/Linux

Do yourself a favor and if you ARE NOT using the Raspberry Pi 3 internal WiFi for this go ahead and blacklist the internal WiFi and Bluetooth kernel drivers as this will give you better overall WiFi strength from your USB WiFi as the signals will not be competing so much with each other.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Edit the file to (You will need to remove these entries, and reboot, to use the on-board WiFi and Bluetooth again):

#WiFi
blacklist brcmfmac
blacklist brcmutil

#Bluetooth
blacklist btbcm
blacklist hci_uart

Reboot so you will no longer load on-board WiFi and Bluetooth:

sudo reboot

Now connect your WiFi USB device and if you now run a quick lsusb command you will see your USB WiFi chipset. Mine is the Ralink RT5370 below. This comes in handy for troubleshooting the exact config required for hostapd if you run into trouble, especially with the correct driver for hostapd if it doesn’t automatically pick it up.

pi@piap:~ $ lsusb
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

For example you MAY need to load a similar package for your particular chipset (Ralink reported already up to date in Raspbian):

sudo apt-get install firmware-ralink

Make sure your device can become a access point. You are looking for the “AP” entry:

pi@piap:~ $ iw list | grep "Supported interface modes" -A 8
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * WDS
                 * monitor
                 * mesh point
        Band 1:

Next we will build a hostapd config file. Hostapd is the daemon responsible for broadcasting and running the access point. With bridge-utils installed, it can also associate a physical NIC to the access point; exactly what we want to do:

sudo nano /etc/hostapd/hostapd.conf

Edit the file to (Replace <<>> with your entries and removing the << and >>):

interface=wlan0   #Should be set to your physical NIC interface
bridge=br0        #Should be set to your bridge interface
#driver=rt2800usb #May be required for correct hostapd operation
country_code=US
#ieee80211d=1     #Optional broadcast Country Code
ieee80211n=1      #Do you want/can you use 802.11n?
hw_mode=g         #g for 2.4 GHz
channel=9         #Pick a channel not in use too much in your area 
wmm_enabled=1     #Usually required for correct 802.11n operation
ignore_broadcast_ssid=0
ssid=<<Your SSID for your Access Point>>
auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=<<Your WPA2 Passphrase>>

And make it executable:

sudo chmod 600 /etc/hostapd/hostapd.conf

Now make sure to point the daemon to the correct config file:

sudo nano /etc/default/hostapd

Find the line:

#DAEMON_CONF=""

And edit it so it says:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

Don’t forget to remove the # in front to activate it!

Likewise, run:

sudo nano /etc/init.d/hostapd

And find the line:

DAEMON_CONF=

And change it to:

DAEMON_CONF=/etc/hostapd/hostapd.conf

Now lets edit our network configuration. There are two ways to do this…

The first way: If you would like to be able to plug the Ethernet cable from any network, that has a DHCP server running on it, and have your Pi get a random DHCP IP address and extend that network for you on WiFi with a specific SSID that you can then connect devices up to. This comes in handy if you are say at a hotel and the provided WiFi has a ton of people on it, the speed sucks because the AP’s are overloaded, and you would rather not have to share bandwidth on the WiFi network’s APs with everyone else in the hotel that is trying to stream Netflix. You can simply plug YOUR AP into an Ethernet drop provided in your room and only allow YOUR devices to associate with it on a specific SSID, password, and channel far from the channel the hotel’s AP’s are using for maximum speed. The downside here is that you have no idea what IP address the Pi now has and if you need to make any changes you will have to unplug it and reconnect with your laptop. Not a huge inconvenience given when we are done here you should be able to plug it in (selecting DHCP when editing the below file) and power up the Pi, and about 20 seconds later see the Pi’s AP pop up in your available WiFi list on your device.

The second way: If you want to say use the Pi for a AP in your home and you already have a range of IP addresses on your home network set aside for things like this, and you would like a static IP address assigned to it so that you can remotely manage it. The downside here is that if you are wanting to use the first use case above and you have a static IP set in the network configuration, you may be able to connect to your device over WiFi but you will have no route to the Internet. You will need to go back in and reset the Pi to DHCP or a static IP on the target network and just hope it isn’t already in use (unless of course you know the network you are connecting to because you are a network admin on it or something similar).

sudo nano /etc/network/interfaces

*** Note: Don’t try to get OCD here and change the order of the lines. For example the “auto lo br0” MUST come first. This tells the system to bring “online” the bridge interface and this is a requirement for hostapd to bind to this interface with the “bridge=br0” config parameter we dictated above. It also creates a loopback on the bridge and there will be an internal route created inside the Pi to allow traffic to move from the wifi AP in/out of the eth0 NIC. If you run a ifconfig during normal AP operation you will see some odd addresses on the eth0 and wlan0 interfaces usually at 169.254.0.0/16. This is OK as your bridge interface has the IP that is identifying your Pi to the outside world.

Edit it to one of the options below and comment out the other’s config lines with a #:

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo br0
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet manual
    post-up iw dev $IFACE set power_save off   #Save yourself some trouble and disable USB sleep after interface has come up 

#Option 1 uncomment below two lines by removing the hash and comment out all of option 2 lines
#iface br0 inet dhcp
        #bridge_ports eth0 wlan0

#Option 2 uncomment all lines below by removing the hash and comment out all of option 1 lines
#I use this as my default as my access point is being used in a permanent location
iface br0 inet static
        bridge_ports eth0 wlan0
        address 192.168.1.100        #Pick an IP address for your AP
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        dns-nameservers 192.168.1.1

Last but not least, set hostapd to start on boot:

sudo update-rc.d hostapd enable

Now reboot your Pi and you should have yourself a brand new access point!

To check the status, start, stop, or restart the hostapd service (You can now use the new systemd based commands too: “sudo systemctl status hostapd.service”):

pi@piap:~ $ sudo service hostapd status
● hostapd.service - LSB: Advanced IEEE 802.11 management daemon
   Loaded: loaded (/etc/init.d/hostapd)
   Active: active (running) since Wed 2016-10-12 16:04:11 EDT; 2h 1min ago
  Process: 770 ExecStart=/etc/init.d/hostapd start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/hostapd.service
           └─799 /usr/sbin/hostapd -B -P /run/hostapd.pid /etc/hostapd/hostapd.conf

If you have devices connected to your AP, you should see the following below the status output:

Oct 12 17:57:59 piap hostapd[799]: wlan0: STA fc:db:b3:23:c5:8f IEEE 802.11: authenticated
Oct 12 17:57:59 piap hostapd[799]: wlan0: STA fc:db:b3:23:c5:8f IEEE 802.11: associated (aid 6)
Oct 12 17:57:59 piap hostapd[799]: wlan0: STA fc:db:b3:23:c5:8f RADIUS: starting accounting session 57FE973B-00000009
Oct 12 17:57:59 piap hostapd[799]: wlan0: STA fc:db:b3:23:c5:8f WPA: pairwise key handshake completed (RSN)
Oct 12 18:04:19 piap hostapd[799]: wlan0: STA a4:77:33:72:ac:26 WPA: group key handshake completed (RSN)
Oct 12 18:04:19 piap hostapd[799]: wlan0: STA 6c:ad:f8:5a:bd:da WPA: group key handshake completed (RSN)
Oct 12 18:04:19 piap hostapd[799]: wlan0: STA 74:75:48:27:8d:8b WPA: group key handshake completed (RSN)
Oct 12 18:04:19 piap hostapd[799]: wlan0: STA 00:04:4b:57:e5:3d WPA: group key handshake completed (RSN)
Oct 12 18:04:19 piap hostapd[799]: wlan0: STA 9c:b6:d0:10:21:61 WPA: group key handshake completed (RSN)
Oct 12 18:04:21 piap hostapd[799]: wlan0: STA fc:db:b3:23:c5:8f WPA: group key handshake completed (RSN)

Helpful troubleshooting/tailing commands:

sudo journalctl -u hostapd.service -f
sudo journalctl | grep hostapd

You MAY be able to adjust the transmission power of your USB WiFi device. Be careful though as there is only so much power you can draw over USB, especially if using PoE. Also the above hostapd config sets the Country Code which will limit your transmit power, and additionally if you have set the region within your OS/kernel the kernel will also, as a second measure of protection, also limit your transmit power. Lastly, be careful you don’t melt your dongle or permanently damage it!

Commands for reference (Don’t run the comment “#” part):

iw reg get #Get your country code
iw reg set #This is what hostapd is doing already
sudo iwconfig wlan0 txpower 30 #TX power of 30dBm is = 1000mW max for US

See these useful links:

Max WiFi TX power settings and their regions/countries and codes

Editing the Kernel’s database and removing country limits

A good forum read if you are having trouble setting TX Power

Another one if you are having trouble setting TX Power