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:

1pip install telepot

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

1apt 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:

1auth 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):

1auth [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):

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

the script itself

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

 1#!/usr/bin/python
 2
 3import telepot
 4import subprocess
 5import os
 6
 7bottoken = 'XXXXXXXXXXXXXXX'
 8
 9chat = 1111111111
10
11temp = subprocess.check_output(["mktemp", "tmp.XXX.jpg"]).rstrip()
12
13subprocess.call(["ffmpeg","-f", "video4linux2", "-s", "vga", "-i", "/dev/video0", "-vframes", "1", "-y", temp])
14
15# initialize telegram bot connection
16bot = telepot.Bot(bottoken);
17bot.sendMessage(chat, 'Failed login!!!')
18bot.sendPhoto(chat, open(temp, 'rb'))
19
20os.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:

1/newbot

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

1@my_new_auth_bot

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

1/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:

 1#!/usr/bin/python
 2import time
 3import telepot
 4
 5bottoken = 'XXXXXXXXXXXXXXX'
 6
 7def handle(msg):
 8    content_type, chat_type, chat_id = telepot.glance(msg)
 9    print (chat_id)
10
11bot = telepot.Bot(bottoken);
12bot.message_loop(handle)
13# Keep the program running. CTRL+C to stop
14while 1:
15    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:

1/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