msgbartop
Blog di Bernardino (Dino) Ciuffetti
msgbarbottom

19 Mar 14 TSL2561 light sensor on Raspberry pi in C

After I bought a new TSL2561 digital light sensor from Adafruit, I found that the very cool and small device cannot be accessed directly from linux (rasbian doesn’t have it’s kernel module compiled). Since I didn’t want to cross recompile my whole raspberry pi kernel just to have the tsl2563.ko driver enabled, and since it seems that raspbian does not relase genuine kernel headers to just compile custom kernel modules, I decided to write a user space simple library driver in C.

I found out that Adafruit relases proof of concept libraries written in C++ and python to access its hardware devices, the problem is that the c++ version is ready for arduino but it was not so directly usable for my raspberry pi. It also makes use of an adafruit unified sensor library and other external stuff. Since I am too lazy I decided yesterday to write a new simple library in plain C without external dependencies, just ready for my raspberry pi.

This is the arduino version that inspired me: https://github.com/adafruit/TSL2561-Arduino-Library
This is another cool blog post that inspired me (it now seems dead!!): http://russelldavis.org/2013/03/23/raspberryhunt-part-2/

This is an example:

/* prepare the sensor
(the first parameter is the raspberry pi i2c master controller attached to the TSL2561, the second is the i2c selection jumper)
The i2c selection address can be one of: TSL2561_ADDR_LOW, TSL2561_ADDR_FLOAT or TSL2561_ADDR_HIGH
*/
TSL2561 light1 = TSL2561_INIT(1, TSL2561_ADDR_FLOAT);

/* initialize the sensor */
rc = TSL2561_OPEN(&light1);

/* sense the luminosity from the sensor (lux is the luminosity taken in "lux" measure units)
the last parameter can be 1 to enable library auto gain, or 0 to disable it */
rc = TSL2561_SENSELIGHT(&light1, &broadband, &ir, &lux, 1);

TSL2561_CLOSE(&light1);

Compile:

gcc -Wall -O2 -o TSL2561.o -c TSL2561.c
gcc -Wall -O2 -o TSL2561_test.o -c TSL2561_test.c
gcc -Wall -O2 -o TSL2561_test TSL2561.o TSL2561_test.o

The output is like this:

root@rasponi:~/test/gpio# ./TSL2561_test
Test. RC: 0(Success), broadband: 141, ir: 34, lux: 12

As you can see it’s very easy at this point to get the light measures in C. Just include TSL2561.c and TSL2561.h inside your project and use the public APIs to setup and sense the IC.

I decided to release the code with the liberal apache v2 license, so feel free to include it into your commercial projects if you like.

It’s useful for me, and I hope that it can be useful to you too. Obviously it comes with absolutely no warranty.

p.s.1: I left the hardware stuff out of this article (just attach +vcc, gnd and i2c bus to the sensor
p.s.2: you have to load two kernel modules to get i2c bus working on you Raspberry pi:

modprobe i2c_bcm2708
modprobe i2c_dev

Ciao, Dino.

TSL2561.c
TSL2561.h
TSL2561_test.c

This is an example on how to use all 3 sensors on the same i2c bus:

#include <stdio.h>
#include <string.h>
#include "TSL2561.h"

int main() {
	int i;
	int rc;
	uint16_t broadband, ir;
	uint32_t lux=0;
	TSL2561 lights[3]; // we can handle 3 sensors
	
	// prepare the sensors
	// (the first parameter is the raspberry pi i2c master controller attached to the TSL2561, the second is the i2c selection jumper)
	// The i2c selection address can be one of: TSL2561_ADDR_LOW, TSL2561_ADDR_FLOAT or TSL2561_ADDR_HIGH
	
	// prepare all sensors
	/* cannot assign that way
	lights[0] = TSL2561_INIT(1, TSL2561_ADDR_LOW);
	lights[1] = TSL2561_INIT(1, TSL2561_ADDR_FLOAT);
	lights[2] = TSL2561_INIT(1, TSL2561_ADDR_HIGH);
	*/
	
	// initialize at runtime instead
	// FIRST SENSOR --> TSL2561_ADDR_LOW
	lights[0].adapter_nr=1;						// change this according to your i2c bus
	lights[0].sensor_addr=TSL2561_ADDR_LOW;				// don't change this
	lights[0].integration_time=TSL2561_INTEGRATIONTIME_402MS;	// don't change this
	lights[0].gain=TSL2561_GAIN_16X;				// don't change this
	lights[0].adapter_fd=-1;					// don't change this
	lights[0].lasterr=0;						// don't change this
	bzero(&lights[0].buf, sizeof(lights[0].buf));			// don't change this
	
	// SECOND SENSOR --> TSL2561_ADDR_FLOAT
	lights[1].adapter_nr=1;						// change this according to your i2c bus
	lights[1].sensor_addr=TSL2561_ADDR_FLOAT;			// don't change this
	lights[1].integration_time=TSL2561_INTEGRATIONTIME_402MS;	// don't change this
	lights[1].gain=TSL2561_GAIN_16X;				// don't change this
	lights[1].adapter_fd=-1;					// don't change this
	lights[1].lasterr=0;						// don't change this
	bzero(&lights[1].buf, sizeof(lights[1].buf));			// don't change this
	
	// THIRD SENSOR --> TSL2561_ADDR_HIGH
	lights[2].adapter_nr=1;						// change this according to your i2c bus
	lights[2].sensor_addr=TSL2561_ADDR_HIGH;			// don't change this
	lights[2].integration_time=TSL2561_INTEGRATIONTIME_402MS;	// don't change this
	lights[2].gain=TSL2561_GAIN_16X;				// don't change this
	lights[2].adapter_fd=-1;					// don't change this
	lights[2].lasterr=0;						// don't change this
	bzero(&lights[2].buf, sizeof(lights[2].buf));			// don't change this
	
	// initialize the sensors
	for(i=0; i<3; i++) {
		rc = TSL2561_OPEN(&lights[i]);
		if(rc != 0) {
			fprintf(stderr, "Error initializing TSL2561 sensor %i (%s). Check your i2c bus (es. i2cdetect)\n", i+1, strerror(lights[i].lasterr));
			return 1;
		}
		// set the gain to 1X (it can be TSL2561_GAIN_1X or TSL2561_GAIN_16X)
		// use 16X gain to get more precision in dark ambients, or enable auto gain below
		rc = TSL2561_SETGAIN(&lights[i], TSL2561_GAIN_1X);
		
		// set the integration time 
		// (TSL2561_INTEGRATIONTIME_402MS or TSL2561_INTEGRATIONTIME_101MS or TSL2561_INTEGRATIONTIME_13MS)
		// TSL2561_INTEGRATIONTIME_402MS is slower but more precise, TSL2561_INTEGRATIONTIME_13MS is very fast but not so precise
		rc = TSL2561_SETINTEGRATIONTIME(&lights[i], TSL2561_INTEGRATIONTIME_101MS);
	}
	
	// you can now sense each sensor when you like
	for(i=0; i<3; i++) {
		// sense the luminosity from the sensors (lux is the luminosity taken in "lux" measure units)
		// the last parameter can be 1 to enable library auto gain, or 0 to disable it
		rc = TSL2561_SENSELIGHT(&lights[i], &broadband, &ir, &lux, 1);
		printf("Test sensor %i. RC: %i(%s), broadband: %i, ir: %i, lux: %i\n", i+1, rc, strerror(lights[i].lasterr), broadband, ir, lux);
	}
	
	// when you have finisched, you can close things
	for(i=0; i<3; i++) {
		TSL2561_CLOSE(&lights[i]);
	}
	
	return 0;
}

21 Feb 14 HOWTO generate a SAN (Subject Alternative Names) SSL CSR with OpenSSL

There is a cool SSLv3 protocol extension that’s called SAN (Subject Alternative Names). With this extension you can create a single SSL X509 certificate that is valid for several domain names, instead of a classic certificate that’s valid for one domain name only.

You can ofcourse create this kind of certificate with OpenSSL. We are now going to see how to do that.
Fist you have to create a file called openssl.cnf and put it for example into a temporary dir. The file should begin with:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

This is to enable SSLv3 req extensions.
Now, you have to add your custom informations to the openssl.cnf file: those informations will be reflected on the next steps.
Add something like this to openssl.cnf:

[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = IT
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Italy
localityName = Locality Name (eg, city)
localityName_default = Rome
organizationName = Organization name
organizationName_default = My company name Srl
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = System Techies
commonName = Common Name (eg, YOUR name)
commonName_max = 64
#commonName_default = www.myfirstdomain.it
emailAddress = Email Address
emailAddress_max = 40

The informations above are used by the “openssl req” command to ask you data to generate your certificate request.
Then, add this block of informations into the openssl.cnf file:

[v3_req]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names

Those informations will enable some extra useful things on your certificate request that will hopefully became valid on your brand new SSLv3 certificate. For example you are requesting your Certification Authority to release a X509 SSLv3 certificate with server and client authentication purposes, plus other certificate goodies.

Now the cool part: this is where you are asking your CA to release a certificate with Alternative Names (certificate valid for several domains). Append this stuff in openssl.cnf:

[alt_names]
DNS.1   = www.myfirstdomain.it
DNS.2   = myfirstdomain.it
DNS.3   = www.myalternativedomain.it
# you could also specify IP addresses like this:
# IP.1 = 1.2.3.4

OK. You are almost ready to create your CSR, but first you have to generate your private key.
NOTE that many CA are now requesting a private key of 2048 bits or more. Warned: a key of 1024 bits is not recommended!
To generate a 2048 bits private key, as usual, execute this command:

openssl genrsa -out server.key 2048

Perfect. It’s time to create the Certificate Request (PKCS#10) with SSLv3 extensions:

openssl req -new -out server.csr -key server.key -config openssl.cnf

Now, send your new server.csr file to your Certification Authority that will hopefully accept the request and relase a valid X509 SSLv3 certificate with SAN.

Good luck and enjoy.

05 Dic 13 As you can see, this site is reachable via IPv6!

If you are using IPv6 (like me) you can see that this blog is reachable via IPv6. Pretty cool!

ipv6 ready

14 Nov 13 LVM Hot backups with snapshot

As you may know, LVM make it possible to create live snapshots of running logical volumes.
Imagine a guest virtual machine that has its virtual disk backed on a LVM logical volume on the host system.
You may create a live hot backup of your virtual machine on the fly, while it is working.

To do this, I created a small script that makes a compressed backup of all the logical volumes on the /dev/vg0 volume group.
The script make use of the standard LVM utilities to have the snapshot, the pv utility to get a cool progress bar and pigz utility to compress (gzip) using all of your processors.
If everything went ok, when the script finishes you’ll find your LVM hot backups on the /backups directory, and the temporary lvm snapshots removed.

This is how I make hot backups of some of my virtual machines (lvm_hot_backup.sh):

#!/bin/bash

for lv in `lvdisplay /dev/vg0 | grep ‘LV Name’ | awk ‘{print $3}’`
do
LV_SIZE=”`lvs –units m –noheadings –nosuffix $lv | cut -d’ ‘ -f7 | cut -d. -f 1`” # LV size in MB
LV_UUID=”`lvdisplay $lv | grep ‘LV UUID’ | awk -F’LV UUID’ ‘{print $2}’ | sed ‘s/^ *//g’`”
LV_SNAPNAME=”SNAP_`basename $lv`”

echo “LVM Logical Volume: $lv”
echo “Size: $LV_SIZE MB”
echo “UUID: $LV_UUID”
echo “Snapshot name: $LV_SNAPNAME”
echo “Removing old snapshot (if any)…”
lvremove -f “/dev/vg0/$LV_SNAPNAME”
echo “Creating snapshot…”
lvcreate -L+2G –snapshot -n”$LV_SNAPNAME” “$lv”
sleep 4
echo “Backing up snapshot…”
dd if=”/dev/vg0/$LV_SNAPNAME” bs=512k of=/dev/stdout | pv -pterbW -i 2 –buffer-size 512k –size “$LV_SIZE”m | /usr/bin/pigz -9 -b 256 > “/backups/$LV_SNAPNAME.lv.gz”
echo “Removing snapshot…”
lvremove -f “/dev/vg0/$LV_SNAPNAME”
echo “–”
done

 

13 Nov 13 Apache HTTPD as 2WAY (mutual) authentication SSL reverse proxy balancer

In this small article I’ll instruct myself (and you too?) how to create a 2 way authentication (mutual authentication) SSL reverse proxy balancer gateway. This configuration is useful in any enterprise environment where it’s requested to separate clients, the frontend and the backend, and when the traffic between clients and the gateway, and between the gateway and the backends must be encrypted.
This also ensure the clients and the backends to be authentic, and avoids Man In The Middle attacks.

Since the reverse proxy is in the middle between the clients and the backends, it’s requested for the clients to send a known client certificate to the gateway (apache), so that the gateway can recognize them. This is done with X509 certificates.
For the same reason, each backend contacted by the gateway is requested to respond with a valid and known server certificate. This is also done with X509 certificates.
Generally, the clients and the backends will also check their peer’s (apache) certificate to be known and valid, so that if someone is going to impersonate the gateway, it will be found and will not be considered authentic.

To do so, we’ll use:

  • apache httpd
  • mod_ssl
  • mod_proxy_balancer + mod_proxy + mod_proxy_http

Everything is done with a simple and single virtualhost in apache to be included in httpd.conf.
A working example is given below (assumes apache to be installed in /opt/apache, working with IP 11.22.33.44 on port 443):

<VirtualHost 11.22.33.44:443>
# General setup for the virtual host
DocumentRoot “/opt/apache/htdocs”
ServerName 11.22.33.44:443
ServerAdmin hostmaster@yoursite.com
CustomLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/ssl_request_%Y%m%d.log 43200” “%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \”%r\” %b”
ErrorLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/error_%Y%m%d.log 43200”
CustomLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/access_%Y%m%d.log 43200” combined

# SSL CONFIGURATION – SERVER SIDE
# Enable SSL Server on this virtualhost
SSLEngine on
# Disable SSLv2 in favor of the more robust and secure SSLv3
SSLProtocol all -SSLv2
# List of supported cryptografic server cipher suites
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

# Apache server certificate
SSLCertificateFile “/opt/apache/conf/ssl/server.pem”
# Apache server private key
SSLCertificateKeyFile “/opt/apache/conf/ssl/key.pem”
# Apache server CA certificate (certificate of who released your server certificate)
SSLCertificateChainFile “/opt/apache/conf/ssl/ca.pem”
# Client’s CA certificates (list of certificates of who released your client’s certificates)
SSLCACertificateFile “/opt/apache/conf/ssl/ca.pem”
# It’s mandatory for apache to authenticate the client’s certificate
SSLVerifyClient require
# END OF SSL CONFIGURATION – SERVER SIDE

# SSL CONFIGURATION – CLIENT SIDE
# Enable SSL Client on this virtualhost (the traffic to the backends can be encrypted)
SSLProxyEngine on
# Apache client CA certificate (certificate of who released your client certificate)
SSLProxyMachineCertificateChainFile “/opt/apache/conf/ssl/ca.pem”
# Apache client private key + client certificate (concatenated in a single file)
SSLProxyMachineCertificateFile “/opt/apache/conf/ssl/client.pem”
# Backends’ CA certificates (list of certificates of who released your backends’ certificates)
SSLProxyCACertificateFile “/opt/apache/conf/ssl/ca.pem”
# It’s mandatory for apache to authenticate the backends’ certificate
SSLProxyVerify require
# END OF SSL CONFIGURATION – CLIENT SIDE

<FilesMatch “\.(cgi|shtml|phtml|php)$”>
SSLOptions +StdEnvVars
</FilesMatch>
<Directory “/opt/apache/cgi-bin”>
SSLOptions +StdEnvVars
</Directory>

BrowserMatch “MSIE [2-5]” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

# Define a load balancer worker to be used to balance the HTTPS traffic to three backends.
# The traffic between apache and the backends is encrypted
<Proxy balancer://httpslb>
# Define the first backend (https) with 2 way auth
BalancerMember https://192.168.1.11:443/ route=worker1 retry=10
# Define the second backend (https) with 2 way auth
BalancerMember https://192.168.1.12:443/ route=worker2 retry=10
# Define the third backend (https) with 2 way auth
BalancerMember https://192.168.1.13:443/ route=worker3 retry=10
</Proxy>

# Don’t send the “/balancer-manager” uri to the backends
ProxyPass /balancer-manager !
# Distribute the traffic (any url, since it is “/”) to the backends with round robin + cookie based session persistence
ProxyPass / balancer://httpslb/ lbmethod=byrequests stickysession=JSESSIONID

</VirtualHost>

If the clients and the backends are configured to check the gateway (apache) certificates, this is considered to be a very secure configuration.

Enjoy!

03 Nov 13 SSH connection is slow? Did you try to disable DNS lookups?

If your SSH connection is slow, it may depends on your SSH server that is executing reverse DNS lookups to try to identify your details.

Try setting the parameter below to your /etc/ssh/sshd_config and restart your ssh server daemon:

UseDNS no

It worked perfectly for me, it may work perfectly with you too.

10 Ott 13 How to fix svn error: OPTIONS ‘https://1.2.3.4/svn/prj’: SSL handshake failed: SSL error: Key usage violation in certificate has been detected

If you encounter an error like this one on your SVN client:

svn: OPTIONS di ‘https://192.168.1.36/svn/myprj‘: SSL handshake failed: SSL error: Key usage violation in certificate has been detected. (https://192.168.1.36)

you can try to fix your problem linking your libneon-gnutls.so.27 library used by your svn client to /usr/lib/libneon.so.27.

Try with this one:

mv /usr/lib/libneon-gnutls.so.27 /usr/lib/libneon-gnutls.so.27.old
ln -s /usr/lib/libneon.so.27 /usr/lib/libneon-gnutls.so.27

Tested on Debian 6.0 and Ubuntu 11.10

03 Mar 13 How to install php 5.2 on debian squeeze (6.0.x), the debian way

You may know that the PHP version coming with debian squeeze is 5.3. Since the 5.3 version of PHP breaks some compatibility with 5.2 you may find that an old PHP application is no longer working with the new version of PHP on squeeze.
The steps required to install PHP 5.2 on debian squeeze are very simple, you just need to setup APT to install the PHP packages coming with debian lenny.

The first thing to do is to add the lenny repository to the end of /etc/apt/sources.list:

deb http://archive.debian.org/debian lenny main contrib non-free

Then you need to make sure that your favourite PHP packages will be downloaded from lenny instead of squeeze. You can do this creating the file /etc/apt/preferences.d/lenny, with this stuff inside:

Explanation: choose Lenny as installation source if the package is not already installed and not available from Squeeze
Package: *
Pin: release n=lenny*
Pin-Priority: 100

Explanation: choose Lenny as installation source for those packages
Package: libapache2-mod-php5 php5-common php5-curl php5-gd php5-mcrypt php5-mysql php5-cli php5-mhash php5-xsl php5-imap php5-xmlrpc php5-sqlite
Pin: release n=lenny*
Pin-Priority: 999

After that, remove any previously installed PHP 5.3 package, for example with the command

apt-get remove –purge php5\*

and then install the PHP 5.2 packages from lenny:

apt-get update
apt-get clean
apt-get install libapache2-mod-php5 php5-common php5-curl php5-gd php5-mcrypt php5-mysql php5-cli php5-mhash php5-xsl php5-imap php5-xmlrpc php5-sqlite

That procedure saved my life twice, I hope it will save yours too!

02 Dic 12 New NuvolaBase Dashboard

Tonight at 03.00 GTM the NuvolaBase team publicly released the new NuvolaBase Dashboard.
As you may know, with NuvolaBase you can handle your private database on the cloud.

The new dashboard aims to be simple, stable and powerful. You can login using your google, twitter, facebook, linkedin account.
In the next days the NuvolaBase guys will release many new cool features like a powerful REST API to handle your databases in the cloud from your application.

This is the official article on the NuvolaBase blog: http://nuvolabase.blogspot.it/2012/12/nuvolabase-dashboard-upgrade.html

17 Set 12 SSH local and remote tunnels

Sometimes you may need to forward remote traffic to a local host through a SSH connection. In other words you can bind a given TCP port to a server running SSH and make remote clients connecting to it, letting the traffic to be redirected to a local server.

    You may need to add the parameter GatewayPorts clientspecified to /etc/ssh/sshd_config on the SSH server and restart sshd. This is to enable ssh clients to bind remote connections on a given ip, otherwise you can only connect to the remote port just from 127.0.0.1.

    At this point, let me do an example:

    • A TCP client wants to connect to 192.168.1.2 on TCP port 18443
    • You want to forward TCP traffic from 192.168.1.2:18443 to 11.22.33.44:18443
    • You have a client host with IP address 11.22.33.41 that can reach 11.22.33.44
    • You can establish a SSH connection from your client (11.22.33.41) to the remote server (192.168.1.2)

    If you have the given situation, you can execute the following command to bind the TCP port 18443 on the remote server:

    ssh -l root 192.168.1.2 -R:18443:11.22.33.44:18443

    Now, you can apply your changes:

    • Substitute “root” with your SSH user on the remote SSH server
    • Substitute “192.168.1.2” with your remote SSH server IP/host
    • Substitute the first “18443” with the port your remote TCP clients need to connect
    • Substitute “11.22.33.44” with your internal TCP server to forward traffic coming from the outside
    • Substitute the second “18443” with the TCP port listening on the internal host

    You can even do the reverse, letting local traffic flowing to an external host, passing through a SSH connection.

    Let me do another example:

    • You have a client host with IP address 11.22.33.41
    • A TCP client wants to connect to 11.22.33.41 (your IP) on TCP port 18443
    • You want to forward local TCP traffic from 11.22.33.41:18443 to 192.168.1.3:18443
    • You can establish a SSH connection from your client (11.22.33.41) to a remote server (192.168.1.2) that can reach 192.168.1.3

    If you have the given situation, you can execute the following command to bind the TCP port 18443 of your computer to the remote server:

    ssh -g -l root 192.168.1.2 -L18443:192.168.1.3:18443

    Now, apply your changes:

    • Substitute “root” with your SSH user on the remote SSH server
    • Substitute “192.168.1.2 with your remote SSH server IP/host
    • Substitute the first “18443” with the port your local TCP clients need to connect
    • Substitute “192.168.1.3” with the remote TCP server you want to reach from your local TCP clients
    • Substitute the second “18443” with the TCP port of the remote server