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 https://github.com/thinkst/opencanary cd opencanary
python setup.py 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
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/app.py", line 642, in run runApp(config) File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/scripts/twistd.py", line 23, in runApp _SomeApplicationRunner(config).run() File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-armv7l.egg/twisted/application/app.py", 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/app.py", 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/app.py", 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/service.py", 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/sob.py", 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/pkg_resources.py", 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
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
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
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 canary_log_forwarder.py
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 FROM_ADDRESS = 'firstname.lastname@example.org' TO_ADDRESS = 'email@example.com' SMTP_SERVER = 'mail.example.com' # 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 canary_log_forwarder.py` SMTP_USERNAME = None SMTP_PASSWORD = None 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 message.attach(message_body) server = smtplib.SMTP(SMTP_SERVER) server.ehlo() server.starttls() server.ehlo() # Login if applicable if SMTP_PASSWORD and SMTP_PASSWORD: server.login(SMTP_USERNAME, SMTP_PASSWORD) server.sendmail(FROM_ADDRESS, [TO_ADDRESS], message.as_string()) server.quit() class EmailFactory(protocol.Factory): def buildProtocol(self, addr): return SendEmail() reactor.listenTCP(1514, EmailFactory(), interface='localhost') reactor.run()
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
sudo nano /etc/systemd/system/opencanary.service
[Unit] Description=OpenCanary honeypot After=syslog.target After=network.target [Service] User=pi Restart=always Environment=VIRTUAL_ENV=/home/pi/canary-env/ Environment=PATH=$VIRTUAL_ENV/bin:/usr/bin:$PATH WorkingDirectory=/home/pi/canary-env/bin ExecStart=/home/pi/canary-env/bin/opencanaryd --dev [Install] WantedBy=multi-user.target
sudo nano /etc/systemd/system/canary-log-forwarder.service
[Unit] Description=Canary log forwarder After=syslog.target After=network.target [Service] User=pi Restart=always Environment=VIRTUAL_ENV=/home/pi/canary-env/ Environment=PATH=$VIRTUAL_ENV/bin:$PATH WorkingDirectory=/home/pi/canary-env/ ExecStart=/home/pi/canary-env/bin/python /home/pi/opencanary/canary_log_forwarder.py [Install] WantedBy=multi-user.target
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.
You should get emailed when it boots up letting you know that all the services have started.
I know the website said "Under $10k" but they wouldn't phrase it like that if the price was $300. ↩