Pages

20/03/2017

Using a Raspberry Pi 3 as a WiFi Client and Access Point simultaneously.

The Raspberry Pi 3 has a built in Wifi chip, which supports client mode (Connecting to a network) and access point mode (Hosting the network other clients connect to). It can also do these simultaneously, allowing the Pi to connect to a network via Wifi (Or Ethernet, or 3G) and share its connection with other devices.

This can be useful in the case of public Wifi that requires some kind of login or registration. As I run my Pi 'headless', I can't authenticate via the Pi itself, but I can now connect to the Pi's access point and go through the registration process. It also means on networks that block client-to-client communication, a device can still access services hosted on the Pi and still access the internet.


Please find the instructions below.

Disclaimer

The following configuration doesn't utilise a firewall. Be careful when access public WiFi networks, as other users may be able to access services running on the Raspberry Pi. It may be possible to create a list of trusted and untrusted networks and use a script to add firewall rules appropriately. 

Elevating privileges

First of all you will need to login to your Raspberry Pi and elevate your privileges-
sudo su

Configuring the interfaces 

If you haven't already done it, now's a good time to configure your Pi to connect to a Wifi network as a client-
nano /etc/wpa_supplicant/wpa_supplicant.conf

Then add the following, editing the SSID and psk (password) as required for the network you want to connect to-
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="SSID_OF_NETWORK"
    psk="NETWORK_PASSWORD"
}

It's now necessary to configure the interface that will act as the access point-
nano /etc/network/interfaces

And add the following at the end of the file-
iface uap0 inet static
  address 192.168.50.1
  netmask 255.255.255.0
  network 192.168.50.0
  broadcast 192.168.50.255
  gateway 192.168.50.1

Configuring hostapd

Now the interfaces have been configured it's time to setup the software that will manage the access point.

First of all we install hostapd to manage the access point
apt-get install hostapd

Now it's installed we can tell hostapd where to find it's config file-
sudo nano /etc/default/hostapd

And add the following line-
DAEMON_CONF="/etc/hostapd/hostapd.conf"

We also need to create a start up script that sets everything up correctly-
nano /usr/local/bin/hostapdstart

Add the following script to start the interface and setup the networking. I found I had to also force it to delete the default route for the access point interface-
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
iw dev wlan0 interface add uap0 type __ap
service dnsmasq restart
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 192.168.50.0/24 ! -d 192.168.50.0/24 -j MASQUERADE
ifup uap0
/sbin/route del default dev uap0
sleep 5
hostapd /etc/hostapd/hostapd.conf

Now make the script executable-
chmod 775 /usr/local/bin/hostapdstart

We also need to setup the SSID and PSK (Password) for the access point-

nano /etc/hostapd/hostapd.conf

Add the following, adjusting the SSID and PSK to suit. Make sure you add the 'driver' line as I found the performance was terrible without it-
interface=uap0
ssid=YOURSSID
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=YOURPASSWORD
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
driver=nl80211

To get hostapd on boot its necessary to create a systemd service-
nano /lib/systemd/system/accesspoint.service

Add the following-
[Unit]
Description=Access Point Service
After=multi-user.target

[Service]
User=root
ExecStart=/bin/bash /usr/local/bin/hostapdstart
ExecStop=/bin/true

[Install]
WantedBy=multi-user.target

And then enable it-

systemctl daemon-reload
systemctl enable accesspoint.service

Configuring dnsmasq

When a client connects to the access point it's necessary to give them an IP address and tell them which gateway to use. We use dnsmasq to handle this.

Firstly, open the dnsmasq.conf file-
nano /etc/dnsmasq.conf

Add the following-
interface=lo,uap0
no-dhcp-interface=lo,wlan0,eth0
local-service
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=192.168.50.50,192.168.50.150,12h

Using the access point

You should now be able to reboot the Raspberry Pi and connect to the access point from your device like you would a standard Wifi access point.

No comments:

Post a Comment