Joseph Zikusooka ~ Zik

A software engineer specializing in open source technologies | Very experienced in building and configuring UNIX/Linux systems and servers. Passionate about developing software applications and hardware for the smart home | Currently serving as the CEO of Jambula Labs and the project leader at JambulaTV, a smart home automation and entertainment platform - https://jambulatv.com | This blog focuses on the following areas: Linux How-Tos and Tutorials ::: IT Security News ::: Free and Libre Open Source Software ::: Smart Home Software ::: Digital Innovations in East Africa https://mastodon.social/@jzik | https://github.com/zikusooka

Tools

How to monitor the presence of nearby WiFi devices using Icinga2

Introduction

I recently published a Python based plugin for Icinga and Nagios monitoring platforms that monitors the presence of wireless devices in the vicinity.

I really like the stability and reliability Icinga provides when it comes to monitoring the state of hosts or services. There are so many software applications that let you do this, including one I talked about a while back called trackerjacker: https://github.com/calebmadrigal/trackerjacker

Why this way?

At first trackerjacker seemed like what I needed to do this sort of thing, but after several months of testing one issue persisted. The performance hit whenever I started the process was huge. The server, would frequently slow down, as packet capturing and monitoring of WiFi devices took place. So I decided to ditch this tool, and write my own plugin.

I am already using icinga on the server, so I figured, rather than write another app for polling, why not use the existing and well performing icinga2 monitoring software. After all, I had done this with bluetooth devices earlier and presence detection was working so well.

Pre-requisites

You are running a Linux based server with Icinga2 monitoring software installed, configured and working properly. There are several articles about how to install and configure icinga2 including the official documentation at:
https://icinga.com/docs/icinga-2/latest/doc/01-about/

The heavy lifting i.e. scanning is done by the Wireshark based CLI tool ‘tshark’. Therefore, ensure that Wireshark is installed on your system. Also, a separate wireless interface that supports monitor mode is required

To capture packets as a non-root user, run the following command in your terminal:
sudo setcap cap_net_raw,cap_net_admin+eip $(which dumpcap)

If you’re still having trouble capturing packets as a non-root user, check out the following Wireshark wiki page:
https://wiki.wireshark.org/CaptureSetup/CapturePrivileges#Most_UNIXes

You will need to identify the MAC address of each wireless device you plan on monitoring. For phones for example, this information is in the Settings >> General >> About >> WiFi Address for iOS. For Android, go to Settings >> About >> Status >> Wi-Fi MAC address

NOTE: Some phones like the iPhone may have MAC randomization enabled, which makes it difficult to reliably monitor their presence status

Setup Icinga2 plugin

Download icinga2 monitoring plugin named ‘check_tshark’ from my Github page at:
https://github.com/zikusooka/icinga-nagios-plugins

Alternatively, you can clone the entire repository and check out my other plugins too:

git clone https://github.com/zikusooka/icinga-nagios-plugins

Copy the icinga2 plugin i.e. check_tshark to your icinga2 monitoring plugins directory e.g. /usr/lib64/nagios/plugins/

cp -v check_tshark /usr/lib64/nagios/plugins/

Configure Icinga2

Add new check and event command objects to icinga2 i.e. Add and save the following snippets to the file:
/etc/icinga2/conf.d/commands.conf

object CheckCommand "tshark" {
        import "plugin-check-command",

        command = [ PluginDir + "/check_tshark" ]

        arguments = {
                "-i"="$tshark_interface$"
                "-t"="$tshark_timeout$"
                "-a"="$tshark_address$"
        }
}
object EventCommand "wifi-tshark-status-event" {
  import "plugin-event-command"

  command = [ SysconfDir + "/icinga2/scripts/wifi-tshark-status-event.sh" ]

  env = {
    "HOSTALIAS" = "$host.display_name$",
    "HOSTADDRESS" = "$address$",
    "HOSTSTATE" = "$host.state$",
    "HOSTSTATEID" = "$host.state_id$",
    "HOSTSTATETYPE" = "$host.state_type$",
    "HOSTOUTPUT" = "$host.output$",
    "HOSTDISPLAYNAME" = "$host.display_name$",
    "LASTHOSTSTATE" = "$host.last_state$",
    "LASTEHOSTSTATEID" = "$host.last_state_id$",
    "LASTHOSTSTATETYPE" = "$host.last_state_type$",
    "LASTHOSTSTATECHANGE" = "$host.last_state_change$",
    "LASTHOSTCHECK" = "$host.last_check$",
    "LONGDATETIME" = "$icinga.long_date_time$",
  }

}

Add new host templates to icinga2 i.e. Add and save the following snippets to the file:
/etc/icinga2/conf.d/templates.conf

template Host "event-tshark-status" {
  max_check_attempts = 6
  check_interval = 30s
  retry_interval = 5s

  check_command = "tshark"

  enable_event_handler = 1
  event_command = "wifi-tshark-status-event"

  enable_flapping = 1
  flapping_ignore_states = ["Critical"]
}

Finally add the wireless devices you want to monitor to the hosts in icinga2 i.e. Add and save the following snippets to the file:
/etc/icinga2/conf.d/hosts.conf

NOTE: In addition to the MAC address, make sure you specify the WiFi interface used for monitoring

object Host "Phone_Zik" {
  import "event-tshark-status"
  vars.tshark_interface = "wlan1"
  vars.tshark_timeout = 10
  vars.tshark_address = "xx:xx:xx:xx:xx:xx"
}

object Host "Phone_Shushu" {
  import "event-tshark-status"
  vars.tshark_interface = "wlan1"
  vars.tshark_timeout = 10
  vars.tshark_address = "xx:xx:xx:xx:xx:xx"
}

Optional: Add Alert notification using MQTT

In order to send alerts whenever a WiFi device appears or disappears, you will need to set up a MQTT broker server. I personally use mosquitto on Fedora Linux. For detailed instructions on how to setup mosquitto on Fedora Linux, check out this how to: https://nullr0ute.com/2016/05/getting-started-with-mqtt-using-the-mosquitto-broker-on-fedora/

Since, we have already enabled event handling for our monitored devices in icinga2, all that is left is to add an event script that will be triggered by the HOST state of either UP or DOWN. Here’s an example:

Create the following script and make it executable:

cat > /etc/icinga2/scripts/wifi-tshark-status-event.sh <<ET
#!/bin/sh
# Variables
TSHARK_MAC_ADDRESS=$(echo "$HOSTOUTPUT" | grep -oP "(?<=\[).+?(?=\])")
MQTT_TOPIC_PRESENCE_TSHARK=Home/presence/$TSHARK_MAC_ADDRESS
MQTT_PUBLISH_CMD=/usr/bin/mosquitto_pub
MQTT_PUBLISH_OPTS="--quiet -h 127.0.0.1 -p 8883"
# Quit if type of state alert is 'SOFT'
[[ "$HOSTSTATETYPE" = "SOFT" ]] && exit 0

# Publish status via MQTT
if [[ "$HOSTSTATE" = "UP" ]];
then
$MQTT_PUBLISH_CMD $MQTT_PUBLISH_OPTS -t "$MQTT_TOPIC_PRESENCE_TSHARK" -m "Home"

else
$MQTT_PUBLISH_CMD $MQTT_PUBLISH_OPTS -t "$MQTT_TOPIC_PRESENCE_TSHARK" -m "Away"
fi
ET
 
chmod 755 /etc/icinga2/scripts/wifi-tshark-status-event.sh

To check your configuration and that all syntax is correct; run the following command:

icinga2 daemon -C

If all’s OK, restart icinga2 as follows:

systemctl restart icinga2

Conclusion

Next, log into your icinga2 web interface (if you have this setup) and ensure your devices are reporting correctly.

In order to monitor alerting via MQTT run the following command in a terminal:

mosquitto_sub -v -h JambulaTV -p 8883 -t "JambulaTV/#" --insecure  | grep presence

That’s all for now. Until next time!

Connect to 3G networks in Uganda using the Linux command line

If you are a Linux user living in Uganda and use 3G internet, you may want to try out my tools to connect to the Internet. These are a couple of scripts I created a while back, however, I’ve now updated them to allow for the following:

  • You can now connect to Airtel, Orange/Africell, MTN, UTL, and Smart telecom.
  • I have added the capability to use your PC (or device such as a raspberry Pi) as a router, this way several devices can access the Internet using one 3g dongle. You can create a MiFI of sorts if you’re inclined to.
  • Query your modems for: EMEI, Serial, IMSI numbers, Lock status, Model/firmware version, etc.
  • A few BUG fixes and script clean ups.

Want to try it out? Visit my Github repository

Getting started with Docker on Linux

Docker containers are all the rage these days. However, if you’ve used Linux for a while you’ve come across LXC. For FreeBSDĀ users, docker containers will remind you of jails. Docker is essentially the same, but with a better tool chain that makes it easy to build system images and move them around different environments. Docker is also lightweight and very fast when compared to LXC for example.

With traditional office servers increasingly being moved to the cloud, it is easy to see why docker is popular. The ability to deploy and scale easily, makes docker a must-learn tool for IT administrators.

Here are a few notes to get you started with docker. For a detailed instructions, see the official docker user guide.

Getting started with docker

Install docker
yum install docker-io
(On Red Hat based systems)

Start the docker service
systemctl start docker

Pull docker image from the repository
docker pull fedora
(Ensure your Internet speed can handle the size of this image)

List all images available
docker images

Run docker image (interactive mode)
docker run -i -t fedora /bin/bash
(Type exit, to get out and leave container running)

Show containers current running
docker ps

To reconnect to the docker instance after exiting:
docker attach [CONTAINER ID]

To start an existing docker container:
docker start [CONTAINER ID]

To stop a docker container
docker stop

How to ship your first container
Reconnect to the container as shown above.

Show all the changes that were made since initial creation
docker diff [CONTAINER ID]

Commit your changes
docker commit [CONTAINER ID] [TAG]

Then to see the newly created image, run
docker images

You can now share your image. Please note that for the public docker repository, you need to follow the proper naming conventions when picking a tag for your image. Then push the image as follows:
docker push [USERNAME]/[TAG]

As you begin to create images using docker, you may want to read documentation on dockerfiles and how to use them to quickly deploy your containers.

How to setup a 3G Wireless Hotspot using Linux

The prevalent and most used type of Internet in Uganda currently is 3G via a USB modem or dongle. Have you found yourself somewhere; may be on travel, or at home, and you need to share your Internet connection with a friend or family members via WiFi? Do you wish you could just plug in your laptop, and just use your WiFi-enabled phone or tablet to surf? Are you a Linux user? Well its very easy to setup a WiFi hotspot for yourself using free and open source software.

hotspot_via_3g

There are several ways to do this, however, if you use Linux say on your laptop (or server), what you need is an application called hostapd. It is already installed in most Linux distributions like Redhat/Fedora, CentOS, Ubuntu, Debian, etc. If not simply install it as follows:

yum install hostapd (or use apt get for Debian based systems like Ubuntu)

Of course, you will need to have a Wireless device enabled on your laptop (or server box), and the chipset should support AP (Access Point) mode. To test this:

iw list (Look for modes section to see if AP mode is supported on your Wireless device

Also, you need to setup the Wireless interface device. In this post I am using an IP address of 172.16.0.1 for my Hotspot and ‘wlan0’ as the device name e.g.

ifconfig wlan0 172.16.0.1 Please remember that the above will not survive a reboot, so you need to permanently add it to your network configuration. On Redhat based systems:

vim /etc/sysconfig/network-scripts/ifcfg-wlan0Add these parameters:
TYPE=Wireless
BOOTPROTO=static
IPADDR0=172.16.0.1
NAME=”wlan0″
ONBOOT=yes

Now edit the configuration file for hostapd to suit your needs.

vim /etc/hostapd/hostapd.conf A typical hostapd.conf file looks like this:
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
wpa_passphrase=AVERYSECRETPASSPHRASE
interface=wlan1
ssid=MY-HOTSPOT
hw_mode=g
channel=6
driver=nl80211

The most important changes to make in the above file are:
ssid: The name you want your hotspot to be called
wpa: The encryption type. Use WPA2 and above always
wpa_passphrase: the password users will need to access your hotspot

After you have modified and saved the above file, enable hostapd services, so they also start during boot time.

systemctl enable hostapd.service or chkconfig hostapd on (old way)
systemctl start hostapd.service or service hostapd start (old way)

You will need some facility to dynamically offer IP addresses to clients of your hotspot. One very useful tool is called dnsmasq. Dnsmasq is a lighweight DHCP and DNS server. You can install it using your package manager e.g.

yum install dnsmasq Once installed, edit the configuration file for dnsmasq to suit your environment:

vim /etc/dnsmasq.confThe most important changes to make in the above file are:
interface=wlan0
domain=example.com
dhcp-range=172.16.0.10,172.16.0.199,12h
dhcp-option=3,172.16.0.1

Enable dnsmasq to start now and at boot time:

systemctl enable dnsmasq.service or chkconfig dnsmasq on (old way)
systemctl restart dnsmasq.service or service dnsmasq restart (old way)

The next step is to dial your ISP using either the GUI (NetworkManager) or the CLI tools like the ones I wrote about earlier. If you use the GUI tools, you will need to allow the laptop (server) to act as a gateway. This can be achieved simply:

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE (NOTE: This assumes you are connected using a 3G modem with an assigned interface node of ppp0)

Once you are connected, and gateway has been setup, your clients should be able to connect to your Hotspot using the SSID and passphrase you setup above.

That’s it. Happy New year!

Scroll to top