Raspberry pi as AP

In this post, I’ll backup the process to turn raspberry pi in to smart AP.

The need is to figure wich device is connecting to the AP and manipulate on it.

In this guid I’ll use raspberry pi 3 mainly because I have one in hands…

Pre requires

Raspberry pi 3
Raspbian os

AP Installation:

start by update and install :

sudo apt-get update
sudo apt-get install hostapd isc-dhcp-server iptables-persistent

edit the dhcpd.conf file :

sudo vim /etc/dhcp/dhcpd.conf

change :

option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;

to :

#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

and change :

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
#authoritative;

to:

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

Add at the end :

subnet 192.168.42.0 netmask 255.255.255.0 {
 range 192.168.42.10 192.168.42.150;
 option broadcast-address 192.168.42.255;
 option routers 192.168.42.1;
 default-lease-time 600;
 max-lease-time 7200;
 option domain-name "local";
 option domain-name-servers 8.8.8.8, 8.8.4.4;
}

After that edit the dhcp-server :

sudo vim /etc/default/isc-dhcp-server

to :

<pre>GNU nano 2.2.6 File: /etc/default/isc-dhcp-server

# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="wlan0"

Set up wlan0 for static IP

sudo ifdown wlan0

edit /etc/network/interfaces :

sudo vim /etc/network/interfaces

with :

iface wlan0 inet static
  address 192.168.42.1
  netmask 255.255.255.0

After allow-hotplug wlan0

sudo ifconfig wlan0 192.168.42.1

Configure Access Point

sudo vim /etc/hostapd/hostapd.conf

change the ssid and passphrase

interface=wlan0
ssid=Pi_AP
country_code=US
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=Raspberry
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_group_rekey=86400
ieee80211n=1
wme_enabled=1

run :

sudo nano /etc/default/hostapd

change : #DAEMON_CONF=”” to DAEMON_CONF=”/etc/hostapd/hostapd.conf”
Don’t forget to remove the # in front to activate it!

run :

sudo nano /etc/init.d/hostapd

change : DAEMON_CONF= to DAEMON_CONF=/etc/hostapd/hostapd.conf

Configure Network Address Translation

sudo vim /etc/sysctl.conf

Scroll to the bottom and add

net.ipv4.ip_forward=1

Also run

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

Run the following commands to create the network translation between the ethernet port eth0 and the wifi port wlan0

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT

To make this happen on reboot (so you don’t have to type it every time) run

sudo sh -c "iptables-save > /etc/iptables/rules.v4"

First test!

run :

sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf

And see a new access point created

Finishing up!

sudo service hostapd start
sudo service isc-dhcp-server start
sudo update-rc.d hostapd enable
sudo update-rc.d isc-dhcp-server enable

Making it smart

Edit the oncommit in dhcpd.conf

sudo vim /etc/dhcp/dhcpd.conf 

and add oncommit :

subnet 192.168.42.0 netmask 255.255.255.0 {
 range 192.168.42.10 192.168.42.150;
 option broadcast-address 192.168.42.255;
 option routers 192.168.42.1;
 default-lease-time 600;
 max-lease-time 7200;
 option domain-name "local";
 option domain-name-servers 8.8.8.8, 8.8.4.4;
 on commit {
 set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
 set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
 log(concat("Commit: IP: ", ClientIP, " Mac: ", ClientMac));
 execute("/home/pi/connect.sh", ClientMac, ClientIP);
 }
}

and edit the connect.sh script :
* remember that this a is a blocking script so fork it asap.

#!/usr/bin/bash
# $1 is the mac address
# $2 is the ip
function() {
   echo "$1"
}

function $1 $2 &

resources :

adafruit

raspberrypi.org