Using Raspberry Pi 3 to allow Pepper Robot to connect to WPA2 Enterprise Network…


This procedure allows you to create a router/AP using a Pi3 that connects to a WPA2 Enterprise network over it’s external wireless interface (wlan1) and allows clients to connect through it’s wired ethernet (eth0) and internal wireless ethernet (wlan0) to access the internet through the NAT interface.

So here are the requirements:

  1. Pepper Robot has wireless and wired connections. Wireless connections can be made to AP’s using WPA2/PSK (Pre-shared Keys) networks. Wired connections are standard and can be configured with DHCP (plugin to the bot’s head). In our scenario we can not use the built in wireless functionality since our campus wide wireless network uses WPA2/Enterprise system (ie you need to supply login credentials, not a pre-shared key). So we opt to use the wired connection
  2. The developer needs to be able to connect to Pepper from his/her laptop through a wireless connection.
  3. Both of these (Pepper and the developer workstation) need access to the internet which requires a connection to our campus wide WPA2/Enterprise wireless network.

So the thought was to create a router using a Pi3 and a extra wireless USB dongle. Pepper (the robot) would connect to the Pi via Ethernet. The Pi would turn it’s internal wireless interface into AP mode (wlan0) to serve potential wireless clients (in this case the developer laptop). The Pi’s external USB wireless dongle (wlan1) would be programmed with known username/password credentials to automatically login to “RU-Secure” SSID (Campus wide WPA2/Ent. wireless network). Connections from eth0 (Pepper) and wlan0 (developer laptop) would be NAT’d through wlan1 to the internet. Additionally wlan0 (developer) would have full network access to eth0 (Pepper) and vice versa to program it and monitor it’s progress via his/her laptop.

  • First thing we need to do is configure wlan1 to auto connect to RU-Secure using WPA2/Ent. We do this by modifying /etc/network/interfaces file to make sure we have the following lines:
allow-hotplug wlan1
iface wlan1 inet manual
 wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
  • We need to download the ca-bundle.crt file from https://ai-apps.ryerson.ca/ccssoftware/allryerson/wireless/ca-bundle.crt and copy it to the Pi under /etc/ssl/certs/ folder. This is specific to “RU-Secure” SSID, so your mileage will vary.
  • Next we want to take care of /etc/wpa_supplicant/wpa_supplicant.conf file. This is the configuration file specific for RU-Secure. Most other WPA2/Ent. setups will be similar. Add the following stanza to the file:
network={
 ssid="RU-Secure"
 scan_ssid=1
 key_mgmt=WPA-EAP
 pairwise=CCMP
 group=CCMP
 eap=PEAP
 identity="YourUSERNAME"
 password="YourPASSWORD"
 ca_cert="/etc/ssl/certs/ca-bundle.crt"
 phase1="peaplabel=auto peapver=auto"
 phase2="MSCHAPV2"
 }
  • At this point we want to reboot and make certain that the Pi3 is connecting to our Wireless network. Stop here is you’re having problems.
  • Once we’ve confirmed that our wireless uplink (wlan1) works we can start configuring the rest of the items.
  • Lets make sure that our two other interfaces (wlan0 and eth0) do NOT ask for DHCP addresses anymore. We will be creating additional private networks behind these network interfaces so we have to make sure that the Pi’s DHCP client does not configure them at any point. We do this by adding the following to the end of /etc/dhcpcd.conf
    denyinterfaces wlan0 eth0
  • Now we move onto configuring the IP address of these two interfaces (wlan0 and eth0). Modify /etc/network/interfaces to configure these interfaces as follows:
    allow-hotplug eth0
    iface eth0 inet static
     address 192.168.2.1
     netmask 255.255.255.0
     network 192.168.2.0
     broadcast 192.168.2.255
    
    allow-hotplug wlan0
    iface wlan0 inet static 
     address 192.168.1.1
     netmask 255.255.255.0
     network 192.168.1.0
     broadcast 192.168.1.255
  • Now we need to install a couple of new applications. dnsmasq (which we’ll use as a DHCP server) and hostapd (which will allow us to turn the internal wlan0 interface into a Access Point for clients to connect to). Do this using apt-get install dnsmasq hostapd
  • We now have the software to create a soft-AP so let’s go ahead and do that. You need to create a new configuration file for hostapd and add the following to the file /etc/hostapd/hostapd.conf:
    # This is the name of the WiFi interface
    interface=wlan0
    # Use the nl80211 driver with the brcmfmac driver (Internal Wifi chip on Pi3)
    driver=nl80211
    # Use the 2.4GHz band
    hw_mode=g
    # Use channel 6
    channel=6
    # Enable 802.11n
    ieee80211n=1
    # Enable WMM
    wmm_enabled=1
    # Enable 40MHz channels with 20ns guard interval
    ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
    # Accept all MAC addresses
    macaddr_acl=0
    # Require clients to know the network name
    ignore_broadcast_ssid=0
    # Use WPA authentication
    auth_algs=1
    # Use WPA2
    wpa=2
    # Use a pre-shared key
    wpa_key_mgmt=WPA-PSK
    # Use AES, instead of TKIP
    rsn_pairwise=CCMP
    # Use AES, instead of TKIP
    wpa_pairwise=CCMP
    
    # Change these to your choice
    # This is the name of the network
    ssid=Pepper-AP
    # The network passphrase
    wpa_passphrase=YOUR_PASSWORD
  • Now we need to make sure we’re handing out DHCP addresses on our two private networks behind wlan0 and eth0. We will create a config file per interface in /etc/dnsmasq.d/ folder. But first we need to tell dnsmasq to look into that folder for additional configs. Edit /etc/dnsmasq.conf, the file contains a ton of config directive and they should all be commented out by default. Go to the very end and uncomment the line that reads like: “conf-dir=/etc/dnsmasq.d/,*.conf”. Now we can go ahead and create additional configs. So create /etc/dnsmasq.d/dnsmasq-eth0.conf and copy the following into it:
    interface=eth0 # Use interface eth0
    listen-address=192.168.2.1 # Specify the address to listen on
    bind-interfaces # Bind to the interface
    server=8.8.8.8 # Use Google DNS
    domain-needed # Don't forward short names
    bogus-priv # Drop the non-routed address spaces.
    dhcp-range=192.168.2.50,192.168.2.100,12h

    followed by /etc/dnsmasq.d/dnsmasq-wlan0.conf:

    interface=wlan0 # Use interface wlan0
    listen-address=192.168.1.1 # Specify the address to listen on
    bind-interfaces # Bind to the interface
    server=8.8.8.8 # Use Google DNS
    domain-needed # Don't forward short names
    bogus-priv # Drop the non-routed address spaces.
    dhcp-range=192.168.1.50,192.168.1.100,12h
  • So now we have two private address spaces for wlan0 (192.168.1.x) and eth0 (192.168.2.x) and dnsmasq will answer DHCP requests and assign address in the range of 50-100 to our clients on each respective interface.
  • Now we need to enable IP forwarding in the kernel by editing the file /etc/sysctl.conf and uncommenting this line:
    # Uncomment the next line to enable packet forwarding for IPv4
    net.ipv4.ip_forward=1
  • Activate the changes by issuing the command: “sysctl –system“.
  • Next we need to activate the NAT through wlan1 to let traffic from wlan0 and eth0 to get to the internet:
    sudo iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
  • Let’s save the iptables settings so we can reload it on boot:
    sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
  • To get the Pi to restore the iptables rule on reboot add the following line to /etc/rc.local just above the line exit 0 here is my rc.local file:
    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing.
    
    # Print the IP address
    _IP=$(hostname -I) || true
    if [ "$_IP" ]; then
     printf "My IP address is %s\n" "$_IP"
    fi
    
    /sbin/iptables-restore < /etc/iptables.ipv4.nat
    exit 0
  • We’re pretty much done at this point, let’s make sure that dnsmasq and hostapd services are started automatically at boot time:
    sudo service hostapd start  
    sudo service dnsmasq start
  • We’re ready to go. Reboot the Pi and test. Once the Pi is back up you should be able to connect to it’s wifi access point (in our case Pepper-AP) using a phone and the pi should give you an IP in the range 192.168.1.50-100. Try using a browser and going to google.com. Once that’s done, test eth0 by connecting a laptop to it (most laptops these days have auto cable detect and will internally cross-over the cable). You should get an IP in the range 192.168.2.50-100 and should also be able to get to the internet as well. Now try connecting from the wifi client to the wired client (ie phone to laptop) using ssh or telnet and make sure that works as well. We’re done.