Dienstag, 6. Januar 2015

Wireless AP on RaspberryPi / ArchLinux

I'm using one of my RaspberryPi devices as a "Development Environment" where i test new things on. Most of the times i'm doing this while being on the train from/to office. To be able to access the Pi without a cable connection i have set up a wireless software access point.
This post describes how to do that on the Pi under ArchLinux.

All you need is a working WLAN card that can act as AP, a working LAN network connection on the PI and some time to configure the software ;-)

Since i like to access the PI only i am not going into details of IP routing. Means LAN (eth0) and WLAN (wlan0) will be separated.
In the guide below it's assumed that eth0 (LAN port) get's a dynamic IP adress when connected to a network. wlan0 (wireless lan) has a fixed ip address of
172.16.0.1.
The host name of the Raspberry Pi device in this guide is "flypi".


With ip link we check if the wireless adapter is present and its device name:

[root@flypi ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether xx:xx:xx:xx:xx:c8 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether xx:xx:xx:xx:xx:5f brd ff:ff:ff:ff:ff:ff
[root@flypi ~]# 

In my case the device is registered as wlan0.

Set fixed IP address for the wireless network


This is done based on the 5.2 Static IP address - network configuration guide on arch linux wiki.

The steps below are described in section 5.2.2 Persistent configuration on boot using systemd to make the configuration permanent.

1) Create a configuration file for the systemd service, replace wlan0 with the proper network interface name if different:

/etc/conf.d/net-conf-wlan0
Content of net-config-wlan0
address=172.16.0.1
netmask=24
broadcast=172.16.0.255
gateway=172.16.0.1
2) Create a network start script: 
/usr/local/bin/net-up.sh
Content of net-up.sh
#!/bin/sh
ip link set dev "$1" up
ip addr add ${address}/${netmask} broadcast ${broadcast} dev "$1"

[[ -z ${gateway} ]] || { 
  ip route add default via ${gateway}
} 
3) Create a network stop script: 
/usr/local/bin/net-down.sh
Content of net-up.sh
#!/bin/sh
ip addr flush dev "$1"
ip route flush dev "$1"
ip link set dev "$1" down

4) Make both scripts executable:
chmod +x /usr/local/bin/net-{up,down}.sh

5) Create a systemd service file for starting/stopping the WLAN0 network.

/etc/systemd/system/network@.service
Content of network@.service
[Unit]
Description=Network connectivity (%i)
Wants=network.target
Before=network.target
BindsTo=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/conf.d/net-conf-%i
ExecStart=/usr/local/bin/net-up.sh %i
ExecStop=/usr/local/bin/net-down.sh %i

[Install]
WantedBy=multi-user.target 
 
6) Enable and start the network.
systemctl enable network@wlan0
systemctl start network@wlan0

If you ping now on the PI to 172.16.0.1 you should get a response.

DHCP/DNS Server on WLAN0

To be able to access the network from clients without fixed IP settings we need a dhcp server running on the PI.

dnsmasq is a lightweight tool that serves that functionality plus provides dns capability.

1) Install dnsmasq package with

pacman -S dnsmasq

2) do a backup of the dhcp config file with 

cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup

3) Edit the configuration file 

/etc/dnsmasq.conf

Content of dnsmasq.conf (changed lines only)

# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
interface=wlan0
# Or you can specify which interface _not_ to listen on
except-interface=eth0
 
# Uncomment this to enable the integrated DHCP server, you need
# to supply the range of addresses available for lease and optionally
# a lease time. If you have more than one network, you will need to
# repeat this for each network on which you want to supply DHCP
# service.
dhcp-range=172.16.0.100,172.16.0.150,12h

If you like to get for specific clients always the same IP adress you can mention this here. e.g.

# Always allocate the host with Ethernet address 11:22:33:44:55:66
# The IP address 192.168.0.60
dhcp-host=
11:22:33:44:55:66,172.16.0.100

4) change the hosts file to allow name resolution in the network.

/etc/hosts

Content of hosts file to do name resolution for the Rapberry Pi.
In my case i like to have is accessible with name "
flypi"

#
# /etc/hosts: static lookup table for host names
#

#<ip-address>    <hostname.domain.org>    <hostname>
127.0.0.1    localhost.localdomain    localhost
::1        localhost.localdomain    localhost
172.16.0.1    flypi.flyingpi        flypi
# End of file
 
5) enable / start dhcp (and dns)
systemctl enable dnsmasq
systemctl start dnsmasq

Set up WLAN software AP 

Hostapd provides the functionality to act as software WLAN AccesPoint.
To support WPA2 encryption the wpa_supplicant package is need.

Further information can be found on Archlinux Wiki - Software Access Point.
1) install hostapd and wpa_supplicant

pacman -S hostapd
pacman -S wpa_supplicant
Important to know for the configuration is that the SSID/password needs to be exactly the same in hostapd.conf and wpa_supplicant.conf and password needs to be at minimum 8 characters.

2) Edit the hostapd config file

/etc/hostapd/hostapd.conf


Content of hostapd.conf
 Adjust interface, ssid, channel, country_code and wpa_passphrase according your needs.

interface=wlan0
driver=nl80211
eapol_version=2

ssid=wlantest
#ignore_broadcast_ssid=1
#bridge=br0

#auth_algs=1
wpa=2
wpa_passphrase=wlantest1
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP

channel=11
# some laptops will only connect if the mode is set to b
#hw_mode=b
hw_mode=g
country_code=DE

#wme_enabled=1
#wmm_enabled=1
ieee80211n=1
# required for full speed
#ht_capab=[HT40+][SHORT-GI-40][DSSS_CCK-40]

3) Edit the wpa_supplicant config file

/etc/wpa_supplicant.conf
ssid needs to be the same than ssid , psk needs to be the same than wpa_passphrase in hostapd.conf.

Content of wpa_supplicant.conf

network={
        ssid="wlantest"
        psk="wlantest1"
}

4) Create a systemd service file to start hostapd automatically
/usr/lib/systemd/system/hostapd.service

Content of hostapd.service
[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticat$
After=network.target

[Service]
Type=forking
PIDFile=/run/hostapd.pid
ExecStart=/usr/bin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid -B

[Install]
WantedBy=multi-user.target

5) Enable and start hostapd with
systemctl enable hostapd.service
systemctl start hostapd.service 

Now you should be able to access the WLAN wlantest and connect to your PI on IP172.16.0.1

Have fun!

Gerald
- dk7xe -