Index ¦ Archives ¦ Atom

Installing OpenCanary on a Raspberry Pi

A few recent Risky Business podcasts have been sponsored by Thinkst and they have been plugging their Canary tools. Basically, little honeypots that sit on your network and sends an alert when something tries to access them. To me, the idea sounded pretty cool but when I looked at their pricing it said

For under $10k, you get 5 Canaries, a dedicated console, and 5 licences for alerts, support and maintenance.

While for some organisations $10,0001 might be chicken feed for me that's prohibitively expensive. So I looked around for open source alternatives and was surprised to find that Thinkst have released OpenCanary. It doesn't seem to be getting a whole lot of love with only a few commits in over a year at the time of this writing but I did have a spare Raspberry Pi and it's open source so if something is missing I can make a pull request.

Grab a Raspberry Pi and Install Raspbian

Download the Raspbian Jessie Lite image and SSH in. There are already hundreds of tutorials so I'm going to skip this step and just assume you have a fresh Raspbian install that you can SSH into.

If you haven't already, update all your packages.

sudo apt-get update && sudo apt-get dist-upgrade

Install the prerequisites

Install the packages needed to build OpenCanary.

sudo apt-get install git python-virtualenv python-pip python-dev libssl-dev libffi-dev

Install a virtual environment

It's recommended that you run OpenCanary in a virtual environment. It makes managing libraries easier but if the only thing your going to run on the Raspberry Pi is OpenCanary it's not strictly necessary.

virtualenv -p python2 canary-env
source ./canary-env/bin/activate

The versions of pip and setuptools that come with Debian's virtualenv are a little out dated and need to be upgraded for OpenCanary

pip install --upgrade pip setuptools

Clone the git repository

git clone
cd opencanary

Install OpenCanary

python install

I got some build errors with Jinja2 but it's a known issue and does not impact OpenCanary.

Also building cryptography and the other dependencies took about 10 minutes on my Raspberry Pi so now is an absolutely smashing time to go and have a cup of tea.

Setup config and start OpenCanary

OpenCanary does have a --copyconfig option which creates a config file in your home directory, however, I found that sometimes OpenCanary misses the config file in the home directory. I tried debugging it but in the end found it more reliable (and logical) to save the config to /etc/opencanaryd/opencanary.conf

sudo mkdir /etc/opencanaryd
sudo cp opencanary/data/settings.json /etc/opencanaryd/opencanary.conf

For some reason when I installed OpenCanary the opencanary.tac file did not copy across correctly and I kept getting an error

Unhandled Error
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/", line 642, in run
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/scripts/", line 23, in runApp
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/", line 376, in run
    self.application = self.createOrGetApplication()
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/", line 441, in createOrGetApplication
    application = getApplication(self.config, passphrase)
--- <exception caught here> ---
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/", line 452, in getApplication
    application = service.loadApplication(filename, style, passphrase)
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/", line 405, in loadApplication
    application = sob.loadValueFromFile(filename, 'application', passphrase)
  File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/persisted/", line 210, in loadValueFromFile
    exec fileObj in d, d
  File "/usr/local/bin/opencanary.tac", line 4, in <module>
    __import__('pkg_resources').run_script('opencanary==0.3.2', 'opencanary.tac')
  File "/usr/lib/python2.7/dist-packages/", line 531, in run_script
    name = ns['__name__']
exceptions.KeyError: '__name__'

Failed to load application: '__name__'

I needed to copy the tac file manually.

cp bin/opencanary.tac /home/pi/canary-env/bin/opencanary.tac

I also found the default Raspbian image has the NTP service running and so port 123 was already in use. I chose to disable the NTP module in OpenCanary

sudo nano /etc/opencanaryd/opencanary.conf

"ntp.enabled": false,

Alternatively, you could leave the NTP module enabled and disable the service on the Raspberry Pi

sudo systemctl stop ntp.service
sudo systemctl disable ntp.service

Start OpenCanaryd

As a bit of a "Hello World!" start opencanaryd in developer mode so it runs process in the foreground to check it's all working

opencanaryd --dev

Hopefully, you will see a message that contains Canary running!!! although you will probably also see a number of Dropping log message due to too many failed sends messages as well. This is because opencanaryd trying to send messages to opencanary-correlator but we don't have that setup yet.

At this point you can have a play with your canary, try to nmap it or telet to it and see the output.

Once you have had some fun Ctrl + C out to close opencanaryd

Setup Email Alerts

Apparently, it's possible to have your canary log directly to email but when I tried I couldn't get it to work.

I looked at opencanary-correlator, but it uses mandrill for mail and that's now a paid MailChimp add-on which I didn't want to use.

In the end, I found it quicker and easier to write a simple python script to work like correlator and forward all alerts to an email address.

sudo nano

Add your email addresses and SMTP server into the script and save it.

Forwards logs from OpenCanary that come in on port 1514 to an email address.

This is a very simple script, it does no validation on the logs, it just
forwards everything that comes in.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

from twisted.internet import protocol, reactor

# Settings
# Saving passwords in a file is not a great idea. If you do need to log in to
# your SMTP server, at the very least make sure this file is not world readable
# e.g. `chmod 700`

class SendEmail(protocol.Protocol):
    def dataReceived(self, data):
        message = MIMEMultipart('alternative')
        message_body = MIMEText(data, "plain", "utf-8")
        message['Subject'] = 'Alert from OpenCanary'
        message['From'] = FROM_ADDRESS
        message['To'] = TO_ADDRESS

        server = smtplib.SMTP(SMTP_SERVER)
        # Login if applicable
            server.login(SMTP_USERNAME, SMTP_PASSWORD)
        server.sendmail(FROM_ADDRESS, [TO_ADDRESS], message.as_string())

class EmailFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return SendEmail()

reactor.listenTCP(1514, EmailFactory(), interface='localhost')

Make it a service

Now we have everything setup we want to make it run as a service and start automatically when we boot up the Raspberry Pi. So we will create two systemd .service files.

sudo nano /etc/systemd/system/opencanary.service
Description=OpenCanary honeypot

ExecStart=/home/pi/canary-env/bin/opencanaryd --dev

sudo nano /etc/systemd/system/canary-log-forwarder.service
Description=Canary log forwarder

ExecStart=/home/pi/canary-env/bin/python /home/pi/opencanary/

sudo systemctl enable canary-log-forwarder.service opencanary.service
sudo systemctl start canary-log-forwarder.service opencanary.service


Your canary should now be all set up and ready to run.

It's a good idea to reboot it just to make sure all the services start correctly.

sudo reboot

You should get emailed when it boots up letting you know that all the services have started.

  1. I know the website said "Under $10k" but they wouldn't phrase it like that if the price was $300. 

Creative Commons License
Content on this site is licensed under a Creative Commons Attribution 4.0 International License.
Built using Pelican. Based on a theme by Giulio Fidente on github.