Contents

Intruder alert

Essentially you receive a telegram message for each failed login to your system. This works with any type of login, even SSH. And you also get a picture of the intruder (taken with the webcam).

how it works

Thanks to PAM’s modularity, it’s easy to integrate your own script. This script will acquire a picture from the webcam and send a message using telegram alongside the picture previously taken.

The script is made in python and thanks to some imported libraries is indeed very simple.

If you have a webcam LED, it will blink for a fraction of a second, it’s very unlikely that the intruder will notice it.

requirements

As I mentioned, we need some python libraries, most of which are included in default python install. With one exception:

pip install telepot

We also need two external binaries and most likely they’re already installed in your system:

apt install coreutils ffmpeg

As usual, this was easy.

PAM configuration

At the moment, this is the only “dirty” part of the whole thing: I still have to check if there’s a better way to do the pam integration. For now, this “just works”.

Edit /etc/pam.d/common-auth, search for the line containing this text:

auth	requisite		pam_deny.so

and edit the line above, by changing “success=1” to “success=2”; then insert this new line (also before the “pam_deny” line):

auth    [default=ignore]		pam_exec.so seteuid /usr/local/bin/badlogin.py

We assume that our script will be placed in /usr/local/bin/badlogin.py. No need to reload any service or restart the computer.

For your reference, the resulting file should look something like this (comments stripped out):

auth	[success=2 default=ignore]	pam_unix.so nullok_secure
auth    [default=ignore]                pam_exec.so seteuid /usr/local/bin/badlogin.py
auth	requisite			pam_deny.so
auth	required			pam_permit.so
auth	optional	pam_ecryptfs.so unwrap
auth	optional			pam_cap.so

the script itself

Let’s put this in /usr/local/bin/badlogin.py:

#!/usr/bin/python

import telepot
import subprocess
import os

bottoken = 'XXXXXXXXXXXXXXX'

chat = 1111111111

temp = subprocess.check_output(["mktemp", "tmp.XXX.jpg"]).rstrip()

subprocess.call(["ffmpeg","-f", "video4linux2", "-s", "vga", "-i", "/dev/video0", "-vframes", "1", "-y", temp])

# initialize telegram bot connection
bot = telepot.Bot(bottoken);
bot.sendMessage(chat, 'Failed login!!!')
bot.sendPhoto(chat, open(temp, 'rb'))

os.remove(temp)

Don’t forget to chmod 755 /usr/local/bin/badlogin.py.

Two things are missing now: the bot token and the chat id. More on this later. Let’s take a look at the code itself:

  • First of all, we import some libraries, then we add the two aforementioned variables
  • Then we call the “mktemp” binary, which is creating a temporary file (ending in .jpg, this is important)
  • After that, we call another external binary: ffmpeg. This is responsible of taking the snapshot and saving it to our temporary file (rewriting it)
  • Then comes the telegram stuff: bot initialization, send a text message and our picture
  • Temporary file cleanup

telegram bot setup

Start Telegram on your PC or phone and open a chat with @botfather:

/newbot

He’ll ask for a name. Name it whatever you want (but it must end in ‘bot’)

@my_new_auth_bot

Botfather will now give you the bot’s token. Place this in the script, in place of ‘XXXXXXXXXXXXXXX’.

/setprivacy

Enable the privacy for this bot, just to be sure.

Obtaining the chat id is a bit tricky: the bot has to be running and answering to chats for that. So I wrote a small script:

#!/usr/bin/python
import time
import telepot

bottoken = 'XXXXXXXXXXXXXXX'

def handle(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)
    print (chat_id)

bot = telepot.Bot(bottoken);
bot.message_loop(handle)
# Keep the program running. CTRL+C to stop
while 1:
    time.sleep(10)

Just put the token at the right place, then start the script: the bot will start to listen, you can then send him a message (with your telegram client) like this:

/start

and it’ll print to console the chat id. Once you have that, type CTRL+C to stop the program and throw it away. Put the chat id at the correct place in the final script and you’re done.

Enjoy!

future improvements

  • better pam integration (we don’t like to mess with system pam configuration, it’s better to add our own in a separate file)
  • telegram bot setup
  • check if webcam is available before taking the shot
  • display snapshot
  • configuration file
  • .deb package
  • get rid of mktemp in favor of python internals
  • get rid of ffmpeg in favor of python’s ffmpeg bindings