Living with Wiperf

A while back I debuted a new tool that I had been helping @WiFiNigel to develop called Wiperf. You can read all about WiPerf here on Nigel’s blog or on github. What I haven’t really discussed is the fact that I have been using Wiperf privately for over 6 months now, and it is incredibly useful and powerful, but dealing with remote sensors isn’t always as straight forward as you might think and sometimes it’s pretty hard keeping them online.

One of the massive benefits of ‘vendor’ sensor solutions is that they have a management platform, and in it’s simplest form, although a brilliant piece of work, Wiperf is a collection of scripts to test the network – there is no simple way of managing remote Pi’s that I have yet discovered.

As you all know, the wireless community is very active with some pretty bright and clever people, so some of todays problems probably won’t exist in the future; I will do my best to keep this up to date as the collective finds solutions.

Provisioning

First off, provisioning is a challenge. Whilst with a bit of attention and time you could probably code it, all the probes need configuring. First you have to get the SD card provisioned, then you have to get it on a network. If you’re local to a sensor, thats easy, but if you’re remote, you’re going to struggle.

My method at the moment of provisioning devices is using a private GitHub repo with the required config files – as an example:

sudo apt-get update && sudo apt-get upgrade -y
curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg' | gpg --import && \ if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | sudo bash; fi
sudo zerotier-cli join <ztkey>
sudo apt-get install python3 python3-pip iperf3 git watchdog unattended-upgrades msmtp msmtp-mta bsd-mailx -y
sudo pip3 install iperf3 speedtest-cli configparser
sudo pip3 install git+git://github.com/georgestarcher/Splunk-Class-httpevent.git
cd ~
sudo git clone https://github.com/wifinigel/wiperf.git
sudo curl -s https://<gitkey>@raw.githubusercontent.com/<myprofile>/<supersecretrepo>/master/config.ini -o ~/wiperf/config.ini
sudo curl -s https://<gitkey>@raw.githubusercontent.com/<myprofile>/<supersecretrepo>/master/watchdog.conf -o /etc/watchdog.conf
sudo apt-get update && sudo apt-get upgrade -y
sudo systemctl enable watchdog
sudo curl -s https://<gitkey>@raw.githubusercontent.com/<myprofile>/<supersecretrepo>/master/mycron -o mycron
sudo crontab mycron
sudo curl -s https://<gitkey>@raw.githubusercontent.com/<myprofile>/<supersecretrepo>/master/50unattended-upgrades -o /etc/apt/apt.conf.d/50unattended-upgrades     
sudo tee -a /etc/msmtprc > /dev/null <<EOT
account        mailgun
host           smtp.eu.mailgun.org
port           587
from           $HOSTNAME@<supersecretdomain>
user           postmaster@<supersecretdomain>
password       <supersecretpassword>
auth           on
tls            on
tls_starttls   on
tls_certcheck  on
logfile        ~/.msmtp.log
account default : mailgun
EOT
echo "This is the email body" > /tmp/body.txt && sudo mailx -s "This is the subject" me@<supersecretdomain> < /tmp/body.txt; rm /tmp/body.txt
sudo reboot

The above script isn’t really a script, it’s just a collection of commands – until I pick up a book and find some time, it’s how I provision. The benefit is that the only things I have to do is get a network connection locally and give a hostname – then copy and paste that into the Pi and we’re all good.
From top to bottom, this is what’s going on:

  1. Update and Upgrade via apt
  2. Install ZeroTier and join my Network
  3. Install the Wiperf pre-reqs, Watchdog, unattended-upgrades and an SMTP client (more on these later)
  4. Install Wiperf pre-reqs from Pip
  5. Clone the Wiperf repo
  6. Grab my Wiperf config
  7. Grab my Watchdog config
  8. Update and Upgrade via apt, again, just for good measure
  9. Enable Watchdog as a service
  10. Grab my crontab config
  11. Grab my unattended-upgrade config
  12. Configure SMTP using Mailgun
  13. Test Mailgun
  14. Reboot

All being well, your sensor is rocking and rolling by this point – it’s rough, nasty and crude but it works. Eventually I want to build an automated provision where you just feed a seed file to the Pi, but I’m not that clever.

Oh, and if you have a captive portal, you need to put additional thought into how you log in.

watchdog

Nigel has done a brilliant job of making Wiperf resilient, so Watchdog may not give you anything, but for me it’s ‘another line of defence’. Wiperf already reboots the sensor given certain conditions, and Watchdog pretty much does the same. Basically, it’s a daemon which runs and conducts predefined tests, depending on the outcome of those tests it can re-initiate a reboot. I use it quite simply, if a Pi cannot contact the Splunk server over ZeroTier it will reboot, but you can set many more tests, as defined here.
My config is pretty straight forward, I just amend the top section:

ping                    = zt.ip.add.here
#ping                   = 172.26.1.255
interface               = ztinterface
#file                   = /var/log/messages
#change                 = 1407

Unattended Upgrades

So, you have all your Pi’s around your network, across countries or whatever, how do you update them? Doing this manually would be a nightmare. Unattended-Upgrades just updates packages via apt automatically – again, it’s configurable – this guide roughly describes it.
For me, email updates were key. I opted to use mailgun’s free tier to email me with the changelog and notify of any updates. You can do this by editing the following section of the config file:

// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
Unattended-Upgrade::Mail "email@goes.here";

On top of that, you need the capability to send email from your Pi, thats the msmtp msmtp-mta bsd-mailx bit of my apt-get install above. On top, I configure the msmtp file, which is the last section of my ‘script’ above – finally, it sends a test email using the hostname@domain.

ZT MTU & CRONTAB

ZeroTier derives its MTU from the physical NIC, which you will often see is 2600 bytes. This works, most of the time, but as soon as you start tunnelling this via CAPWAP/EoIP or IPSec you may see performance problems. I haven’t found an elegant way of fixing the MTU permanently, so I do this via cron:

*/2 * * * * /usr/bin/python3 /home/user/wiperf/wi-perf.py >> /home/user/wiperf/wi-perf.log 2>&1
*/5 * * * * /sbin/ifconfig ztnfapqn4s mtu 1200
@reboot /sbin/ifconfig ztnfapqn4s mtu 1200

Device types

So far, I’ve experimented with various models of Raspberry Pi – some of them never work as well as others. The most stable I have found is the RPI 4B+ 4GB model without an external NIC, and RPI 3B+ with a Comfast CF-912ac.
I have tried 3A+s, Zeros, etc, none of them seem as performant and stable. To put it one way, I have had 3x 3B+s online with the Comfast NICs permanently for over 6 months, they have never missed a beat – my 3A+ worked fine for a few days before it started struggling. I guess the point is you need to pick your Pi wisely and test it – when these are deployed remotely it can be difficult to rectify any errors. The below is a view of my 3A+, which is quite clearly struggling.

The other thing to consider is client capability, even the best RPI is a 1×1:1 device, so don’t expect anything a better MCS rate than MCS8 (86.6Mbps on a 20MHz channel with SGI)

Recovery Processes

If you rush into deploying these without any real recovery process you’re going to end up with some stranded Pi’s, and nobody likes a stranded Pi. We’ve heard people running into every problem you can imagine – building closures, dodgy config changes, things going missing, corrupt SD cards, each of which has left people wandering around remote buildings trying to figure out where they had actually put them and trying to get them online. Even the model of device is important, if you forget you’ve deployed an RPI 4B+ and rock up with a micro-USB cable, you’re not going to have a difficult time. It can be a pain. If you want to deploy Wiperf sensors in anger make sure you document their location and have a process for manual recovery!

Cyber Security

If you’re deploying these sensors, tell your Cyber Security team, otherwise they may end up being picked up and confused as a Russian spying device. One approach was to run purely over a guest wireless network using ZeroTier, so no data sent actually transits the network or internet natively and the underlaying wireless network almost becomes irrelevant – it’s just another client doing a network test and sending it over the internet, just like Ookla and Speedtest.net, who also collect stats from the tests. If you are working for an organisation which is security sensitive make sure they are involved and happy to sign off their deployment.

Conclusion

These sensors are very useful for an extremely low cost point, but I guess the whole point of this blog is that you need to have a think about how you want to design your solution. I would not recommend buying 10s of sensors without ensuring there is a management wrap around them, and without testing. Once you get it right, they can make a big difference to how you manage your network, both from day to day operations to assessing impact of change. Rushing into deploying sensors like this will cause you issues.
As mentioned in the intro, as the tools mature we will discover new tools and between us we will design more elegant solutions to provision and manage the devices – I have tried some linux MDM solutions but none of them really blew me away or offered anything, but it is still early days and there is a lot of water to flow under the bridge before I would class Wiperf as an ‘enterprise ready’ solution.

Splunking on Pi – DIY Active Sensors [UPDATE: Now working with the WLANPi!]

Update: Now WLANPi compatible

I’d love to take the credit, but I can’t, @WifiNigel has been hard at work making his WiPerf tool work cross platform, and therefore on the WLANPi. Please scroll down to updated instructions, they header is nice and red so should stand out!
It’s getting a bit cumbersome keeping this blog up to date, so for latest read me’s head to https://github.com/wifinigel/wiperf

There are a few different flavour of sensor on the market; you have sensors which perform active tests, you have sensors which sniff frames, you have sensors which capture spectrum data, you even have sensors which sit on your wired network and try figure out how your network is performing.. blah, blah blah.

Don’t get me wrong, some are really good, but they all have a few things in common:
1) Fairly substantial up front cost
2) Subscription based
3) Proprietary
4) Require substantial change, whether it be appliances, cablers, downtime, etc.

So, what if I told you that there was a way to get an active sensor without a subscription? What if I told you you could get sensors that had an upfront cost of less than £50/$50? What if I told you that it wasn’t proprietary, and could be built on by the community to bring in new features? What if I told you the leg work had already been done, and the instructions are right here, in this blog?

Huh? Have I got your attention? Good, read on!

Here’s a bit of background.. shortly after I published my latest blog I got chatting to WiFiNigel. See, Nigel had a nifty bit of code that ran speed test outputs to a file, however he didn’t have an elegant way of logging that data to visualise – In my eyes, Splunk was the perfect tool to do that. So, Nigel did the easy bit (coding) and I did the hard bit (made pretty graphs). Very soon we saw the potential of Mr Bowdens labour, and we soon realised just how beneficial this could be.

Utilising a range of tools, we ultimately designed a sensor solution that ran on Raspberry Pi’s, and could connect over a VPN (ZeroTier) to log data to a central Splunk server (under my desk in my home office). We tested for a while in a production environment and I introduced some additional tools, such as Watchdog (to auto-reboot devices on network/other failure) and Apache Guacamole (which can be used to remotely and securely access devices outside of the ZeroTier VPN). Nigel’s python skills meant that we have quickly been able to implement several tests, such as:

  1. Speed test
  2. Ping Test of multiple hosts
  3. UDP iPerf Test
  4. TCP iPerf Test
  5. DNS resolution timer of multiple hosts
  6. DHCP timer
  7. Data Rate, RSSI, TX retransmits (for your Pi) and BSSID, SSID, etc

All of these tests can be turned on and off individually, and configured to test your favourite hosts, exportable in either JSON or CSV – and the code is on GitHub for you to pull/clone/branch/merge to your hearts content – WiPerf.
And I guess thats the key thing, the reason this has excited us as much as it has is because of the success of the WLANPi, the community have built a home grown tool that rivals any vendor tool, and the potential of a community built and driven distributed sensor network is huge.

So, what am I waiting for? Well.. here’s what you need

  1. RPI 3B+ or 4B (Older models are 2.4GHz only, you can still use with an external NIC)
  2. A device capable of running a Splunk Free server (https://docs.splunk.com/Documentation/Splunk/8.0.0/Installation/Systemrequirements)
  3. Thats it 🙂

New: Cross Platform Instructions for WLANPi/RPI

  1. Install Splunk on a server/laptop/desktop. By default it will install Splunk Enterprise, you can convert to Splunk Free (500MB/day data cap) once installed.
    1. Link to Download: https://www.splunk.com/en_us/download/splunk-enterprise.html
    2. Link to Install Manual: https://docs.splunk.com/Documentation/Splunk/7.2.4/Installation/Whatsinthismanual
    3. After installation, go to Settings > Data Inputs
    4. Click HTTP Event Collector
    5. Click Global Settings and configure as per the below:
      All Tokens: Enabled
      Default Source Type: _JSON
      Default Index: Default
      Default Output Group: None
      Use Deployment Server: Unticked
      Enable SSL: Ticked
      HTTP Port Number: Up to you, but default is 8088 >> This is needed for your wiperf config file
    6. Click Save, then click New Token, with the following settings on the initial page:
      Name: Anything you want, haven’t worked out what this is used for
      All Other Fields: Blank/Default
    7. Click Next for the secondary page, and configure as follows:
      Source Type: Automatic
      App Context: Searching & Reporting
      Index: Add all
      Default Index: Main
    8. Click Review, then Submit. On the next screen it will display your HEC Token >> This is needed for your wiperf config file

      Your Splunk server is now configured, you can re-use your Token for all your sensors!
  2. Install Your Pi OS: Raspberry Pi
    1. Link to Download: https://www.raspberrypi.org/downloads/raspbian/
    2. Link to Install Manual: https://www.raspberrypi.org/documentation/installation/installing-images/README.md
    3. Important, before putting the SD Card into the Pi, create a file in the boot folder of the media called ssh (no extension). This will allow SSH access as soon as it is connected to a network.
  3. Install your Pi OS: WLANPi
    1. Visit http://wlanpi.com to get the image and write to an SD card.
  4. Insert the SD Card, plug into a network and power.
  5. Go to the WiPerf github repo and follow the README to install the scripts: https://github.com/wifinigel/wiperf
  6. Set the general section of the config.ini file, set your architecture to the correct platform, set data_format to _json, set data_transport to hec, and data_host to your Splunk server IP, and data_port and splunk_token to the relevant information from your Splunk server captured above.
  7. HEC will use your devices hostname as the default host in Splunk, so set this to something unique and meaningful otherwise all your data will be from host=raspberrypi

    Thats it, you should now be receiving data into Splunk. Scroll down past the UFW instructions for more Splunky goodness

Instructions for Slunk UFW
This is still a valid method, however more complex to install and does not work on the WLANPi

  1. Install Splunk on a server/laptop/desktop. By default it will install Splunk Enterprise, you can convert to Splunk Free (500MB/day data cap) once installed.
    1. Link to Download: https://www.splunk.com/en_us/download/splunk-enterprise.html
    2. Link to Install Manual: https://docs.splunk.com/Documentation/Splunk/7.2.4/Installation/Whatsinthismanual
    3. After installation, you need to add a Receiving Port: Click Settings > Forwarding & Receiving > under Configure Receiving click Add New, and enter a port number (I used the suggested port, 9997)
  2. Install Raspbian Lite on RPI
    1. Link to Download: https://www.raspberrypi.org/downloads/raspbian/
    2. Link to Install Manual: https://www.raspberrypi.org/documentation/installation/installing-images/README.md
    3. Important, before putting the SD Card into the Pi, create a file in the boot folder of the media called ssh (no extension). This will allow SSH access as soon as it is connected to a network.
  3. Insert the SD Card, plug into a network and power.
  4. Install the Splunk Universal Forwarder on the RPI (ARMv6) – this is the software used to forward data into Splunk: Link to Download: https://www.splunk.com/en_us/download/universal-forwarder.html (hint, once you start the download you can view a wget link on the right – you can copy this and download directly onto your RPI)
  5. This is the most problematic install, but this got it working for me – just run these commands:sudo tar xvzf splunkforwarder.....64.tgz -C /opt
  6. Run sudo ./splunk start from /opt/splunkforwarder/bin
  7. Hopefully, it should ask you to accept an EULA and set a username and password, if that works, you’re in!
  8. Go to the WiPerf github repo and follow the README to install the scripts: https://github.com/wifinigel/wiperf
  9. Set the WiPerf config.ini to write JSON files
  10. Head over to https://github.com/Krisalexroberts/wiperf-splunk-config and copy the .conf files into /opt/splunkforwarder/etc/system/local
  11. Set a unique sensor name on row 2 of inputs.conf and insert your Splunk server IP address in outputs.conf. If you don’t set a unique name for your sensor, all the data you receive will look like it came from the same host!
  12. In /opt/splunkforwarder/bin run sudo ./splunk enable boot-start
  13. Reboot!

That should be enough to get data into Splunk. Now the interesting bit is actually displaying the data – if you head over to Splunking on Pi you can see some example searches and how to display data, these searches can be inserted in Dashboard Panels.

The great thing about this is it barely uses any data, with Splunk free you get 500MB of data a day, with 5 sensors running tests every 2 minutes I’m using 0.1% of that allocation!

Anyway… thats how you get one sensor talking to Splunk. How about.. I don’t know.. 100?

ZeroTier

If you haven’t used ZeroTier before, you’re missing out.. so, what is it? Well, think of it as a big switch in the sky. It’s basically an overlay network which allows nodes to talk to eachother securely with minimal config, and for 100 nodes in a network, it’s free.

  1. Head over to https://zerotier.com/ and create an account
  2. Despite being free, you need to give your card details – but you’re not going to be charged, don’t worry!
  3. Click Networks, and Create a Network
  4. Once created, you will see it populate in the list, click on it – it will display a Network ID – thats the important bit.
  5. Click on Download and on your Sensors and your server, download the agent. Once downloaded and installed, on each node type sudo zerotier-cli join networkID or enter it in the relevant ZeroTier GUI on your server
  6. Back on the ZeroTier website, navigate back to your networks and scroll down, you’ll see a list of all the devices that want to join, tick the box and you’re done – everything’s talking. Remember to give devices a meaningful name!
  7. On your Splunk server, run ifconfig and you should see a new interface for your VPN, take a note of its IP address – you need to head back over to outputs.conf on your Sensors and replace the previous IP with the ZT IP.
  8. Once you’ve changed outputs.conf, navigate to /opt/splunkforwarder/bin and run ./splunk restart

Again.. thats it, that will allow up to 100 nodes to talk to each other – easy as pi! One problem I did run across was the encapsulation overhead on some networks makes it difficult to access the sensors via CLI. I had to set up a cronjob to set the ZeroTier MTU down to 1200 bytes (sudo ifconfig zerotierinterface mtu 1200) – thats obviously network independent though – just watch your toxic tails!

One thing to watch out for is that the DHCP reset in WiPerf doesn’t work well with ZeroTier as it has to re-establish a tunnel afterwards.

Watchdog

One thing I spotted pretty quickly was that the sensors went offline sometimes.. and quite randomly. I quickly worked out that RPIs aren’t great at handling network disconnections, so decided to install Watchdog to automatically reboot in preconfigured conditions.

  1. On your Pi run sudo apt-get install watchdog
  2. Edit the config file (sudo nano /etc/watchdog.conf)
  3. You can set watchdog to ping a host, and time out after x failures by setting the ping field to an IP/Host, interface to your wlan interface, and retry-timeout to whatever value you want – I found that anything less than 60 caused frequent reboots.

Apache Guacamole

Apache Guacamole is one thing that gets me excited, see the project here: https://guacamole.apache.org/

What is it? Well, it’s a web server that will let you SSH/RDP/etc to hosts from a web interface. Whilst it’s not really necessary for this project, I found that having multiple devices to manage was cumbersome. You’re best spinning up a CentOS server and joining it direct to ZeroTier, then running the install script found here: https://github.com/Zer0CoolX/guacamole-install-rhel

If you configure TOPT (2FA) and LetsEncrypt (SSL/TLS) via the script, you get really easy and straight forward secure access to a number of devices

As of today, this doesn’t work on the WLANPi – we simply can’t get Splunk installed, but there are plans to output the WiPerf data as Syslog which should allow you to output to Splunk (hence the unused transport config items in config.ini).

As the RPI runs a similar architecture to the WLANPi, you could in theory run most applications you can on a WLANPi on an RPI, eg Kismet – it’s pretty much a blank canvas though and we encourage you to share ideas and develop your own code and use cases!

Cisco Blog Awards
Vote for Nigel!

Personally, I think this is super cool, and the possibilities are endless and could quite easily rival a vendor tool – imagine kicking off a HORST capture when a threshold is breached, or mapping your sensors based on available BSSIDs using wigle.net – and they’re just the two I’ve thought of whilst writing this conclusion! I haven’t even begun to think about any integration between your WLC data and the data from the sensors!

Most of the effort here is from WiFiNigel – like I said, all I did was make pretty graphs. Nigel has been nominated in the Cisco 2019 IT Blog Awards, please repay him for not only his effort here, but his effort in all things wireless, by voting here, and of course read his blog here

Thanks!