Lead Image © Bruce Rolff, 123RF.com

Lead Image © Bruce Rolff, 123RF.com

Build a honeypot with real-world alerts

Seeing Is Believing

Article from ADMIN 52/2019
The honeyBot tools create a honeypot that activates an alert in the real world.

If you manage systems or get excited about security, like I do, you probably have an Intrusion Detection System (IDS), an ELK (Elasticsearch, Logstash, and Kibana) syslog server front end, performance monitoring, and a plethora of other dashboards. The first week your IDS or SIM is running, everyone watches it, trying to catch an invader in their enterprise. Then, when the sheer amount of data coming in overwhelms you, the systems are left to run in the dark recesses of your data center. During the 2013 hack of Target, numerous warnings from the IDS were ignored, which lead to a judge ruling in 2014 that banks could sue Target for losses [1].

In the medical field, this is called alert fatigue and is blamed for ignoring dangerous drug incompatibilities or even ignoring real health monitoring emergencies. You can help fight this by taking the alert off of the screen and into the real world with the following items:

  • Raspberry Pi with SD card
  • Rasp Pi Relay HAT [2] (Figure 1)
  • Alarm: Anything with lights! I even used a light-up tin robot toy for a while
Figure 1: The Relay HAT for the Raspberry Pi lets you control high voltage, high current devices and lends normal appliances some intelligence.

To be honest, it is also a fun way to show people outside of the security group that hacks are happening.

In this article, I build a standalone system (Figure 2) with some tools I collectively call honeyBot; however, it could certainly be deployed on multiple systems, because it is designed to be modular. Files are monitored by one process, and alerts are then sent by MQTT and stored in a SQLite database. The front end is a lightweight Flask app [3].

Figure 2: The honeyBot project flowchart.

Setting up the honeypot comprises two main steps: system configuration and software deployment. To begin the system configuration, secure the Pi and set it up to log failed logins and Nmap scans by first creating an SSH key with the ssh-keygen command (Figure 3); you will copy the public key and enforce key-based logins.

Figure 3: Creating an SSH key.

On the client, copy your public key file and test your login:

ssh-copy-id -i ~/.ssh/id_rsa_honeybot.pub pi@raspberrypi.local
ssh pi@raspberrypi.local -i ~/.ssh/id_rsa_honeybot

This box is on the public Internet, so you will need keys to log in via SSH. To do so, edit sshd_config, uncomment the line PasswordAuthentication, and set its value to no. After you have made the changes, restart the SSH daemon:

sudo service ssh restart

At this point, if you have any issues logging in, take a look at the documentation from the Raspberry Pi organization [4].

The next step in securing the Raspberry Pi and collecting data is to set up iptables by installing iptables-persistent

apt-get install iptables-persistent

and creating some rules. Although you can manually enter the rules, an online sample file [5] (Listing 1) makes it easy. Be sure to change the subnet mask on line 11 to your address space, so web console access is only allowed from your trusted space. It is a honeypot after all, so nothing is really trusted. The takeaway is the -j LOG option (line 12), which logs port scanning behavior to a logfile with the iptables: prefix.

Listing 1

iptable Rules

01 *filter
02 *filter
03 :INPUT ACCEPT [0:0]
05 :OUTPUT ACCEPT [125:13440]
07 -A INPUT -p icmp -j ACCEPT
08 -A INPUT -i lo -j ACCEPT
09 -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
10 -A INPUT -p udp --dport 5353 -j DROP
11 -A INPUT -s <add your subnet> -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
12 -A INPUT -m limit --limit 30/min -j LOG --log-prefix "iptables: "
13 -A INPUT -j REJECT --reject-with icmp-host-prohibited
14 -A FORWARD -j REJECT --reject-with icmp-host-prohibited

In the /etc/rsyslog.d/10-iptables.conf file, modify rsyslog to log messages to its own file,

:msg,contains,"iptables: " /var/log/iptables.log

and then restart rsyslog:

service rsyslog restart

The :msg,contains,"iptables: " option tells rsyslog to store alerts in iptables.log. You can test this new setting by running Nmap from your remote machine and tailing the /var/log/iptables file (Figure 4) with:

tail -f /var/log/iptables.log
Figure 4: The tail end of the iptables logfile.

For my environment, I wanted to disable IPv6 in /etc/sysctl.conf, because my ISP was IPv4 only:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

At this point, the Raspberry Pi is set up, so it is time to install the honeyBot prerequisites and then configure the software. The honeyBot software comprises three processes: honeyBotMon.py, honeyMqtt.py, and honeyWeb.py. All of these and the startup scripts are available in the GitHub repo [6].

The Python tools require a few packages:

apt-get install python3-rpi.gpio daemonize mosquitto mosquitto-clients
pip3 paho-mqtt flask maxminddb-geolite2geopandas pyshp shapely plotly psutil

Before installing the software, I'll review the function of each part of the system, so you can expand on it and make your install even better. The honeyBot tools are released under the GNU GPLv3, and code contributions are always welcome.

The Python program honeyBotMon.py looks at two files: iptables.log and auth.log. The auth.log file logs failed SSH logins. The iptables.log file has information about port scans. Five scanned ports from a single host or one failed login calls the functions raiseAlert and sendAlert (Listing 2).

Listing 2

honeyBotMon.py Snippet

01 while(1):
02   time.sleep(args.delay)
03   line=sshFile.readline()
04   if line:
05     if "sshd" in line and "closed" in line and "preauth" in line:
06       srcIP=line.split()[8]
07       print(srcIP)
08       raiseAlert(relay)
09       sendAlert(args.server, srcIP)
11   line=iptablesFile.readline()
12   if line:
13     if "UDP" in line or "TCP" in line:
14       for words in line.split():
15         if "SRC" in words:
16           srcIP=words.split('=')[1]
17         if "DPT" in words:
18           dPort=words.split('=')[1]
20       #count the number of ports keyed by src IP
21       if srcIP:
22         print("srcIP: {} dPort {}".format(srcIP, dPort))
23         if srcIP not in srcIPs:
24           srcIPs[srcIP] = 1
25         else:
26           srcIPs[srcIP] += 1
28         if srcIPs[srcIP] == 4:
29           print("alert")
30           raiseAlert(relay)
31           sendAlert(args.server, srcIP)
32           srcIPs[srcIP] = 0
33           srcIP = None

The function raiseAlert tells the relay to go high and low, making the emergency light flash:

def raiseAlert(relay):

The function sendAlert uses MQTT to send a message with the topic honeyBot/IP to the MQTT listener locally or on another host:

def sendAlert(server, message):
  pub.single('honeyBot/IP', message, hostname=server)

The next piece, honeyMqtt.py, listens for connections and writes them to an SQLite database (Listing 3), and the last piece is the web front end, honeyWeb.py, which uses the flask module for the alert display and uses GeoIP to geolocate the attackers. When the index page is hit, it will query the SQLite database and look up the location (Listing 4).

Listing 3

honeyMqtt.py Snippet

01 def on_message(mosq, userdata, msg):
02   print(msg.payload.decode("utf-8"))
03   now=datetime.datetime.now()
04   t=(msg.payload.decode("utf-8"),now,)
05   query='insert into honeyLog(ip, dateStamp) values(?,?)'
06   cursor=db.cursor()
07   cursor.execute(query, t)
08   db.commit()

Listing 4

Geolocating Attackers

01 for row in rows:
02     ip=row[1]
03     count=str(row[0])
04     match = reader.get(ip)
05     if match:
06       try:
07         country=match['country']['names']['en']
08       except:
09         country="unknown"
10     else:
11       country="unknown"

Now you need to set up your honeypot to run on boot. Copy the *.service files to /lib/systemd/system, and then enable them (Listing 5). You can now browse to the Rasp Pi IP address to view the alerts (Figure 5). Be warned, it is a self-signed key, so you will get a security warning.

Listing 5

Run honeyBot on Boot

wget https://github.com/joemcmanus/honeyBot/archive/master.zip
unzip master.zip
mkdir /var/honeyBot
cp -r master/* /var/honeyBot
cp startupScripts/*.service /lib/systemd/system
systemctl enable honeyBotMon.service
systemctl enable honeyMqtt.service
systemctl enable honeyWeb.service
Figure 5: Geographic and list views of attacks.


To wire the Relay Hat you will need to pick a spot somewhere in the middle of the cord, cut one of the wires, and strip each end. Insert one end of each wire into the screw terminals of the relay labeled "Relay Ch1." One end of the wire should be in the outside terminal (rightmost if the screw terminals are facing you) and the other in the center terminal of the terminal (Figure 6). Keep in mind that you are using household current, so be careful! Be sure you have the alarm unplugged. I tinned the stranded copper wire so it did not fray when inserted into the relay.

Figure 6: The Relay HAT wired.

After building this honeypot, set it up in a conspicuous location to highlight the threats a public-facing machine encounters – and provide a bit of fun. You can also see it in action on YouTube [7].

The Author

Joe McManus runs the security group at Canonical. You can listen to Joe talk about all things Linux security in the weekly Ubuntu Security Podcast (https://ubuntusecuritypodcast.org). When not tinkering with electronics or code, Joe can be found somewhere outside on a trail with his wife and their dogs. For questions, contact Joe at mailto:josephmc@alumni.cmu.edu.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus