jueves, enero 17, 2013

Instalar gphoto2 2.5 en raspberry pi

EDITO:
Como esto es bastante más largo de lo que pensaba antes de empezar la entrada he creado un pequeño script que realiza todos los pasos automáticamente. Está disponible en https://github.com/gonzalo/gphoto2-updater 

Una de mis proyectos con RPI tiene que ver con la cámara DSLR Olympus E-520 que tengo. Para poder controlarla desde el ordenador podemos usar el software gphoto2. Lamentablemente la versión disponible en debian y, por extensión, en Raspbian es algo antigua la 2.4.14. Así que para poder ponerme al día he tenido que compilar e instalar la nueva versión.

Te recomiendo desinstalar gphoto2 si lo has hecho para evitar confusiones.

sudo apt-get remove gphoto2

Para empezar he bajado el código fuente desde la página del proyecto y descomprimido.

wget http://downloads.sourceforge.net/project/gphoto/libgphoto/2.5.0/libgphoto2-2.5.0.tar.bz2?r=&ts=1358269367&use_mirror=freefr

(tendras que renombrar el archivo porque wget le pondrá un nombre muy largo)

tar xjf libgphoto2-2.5.0.tar.bz2
cd libgphoto2-2.5.0

A partir de ahí los clásicos comandos para configurar y compilar el proyecto

./configure

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for POSIX sh $() command substitution... yes
checking for gcc... gcc

(...y mucho código más...)

Ojo a la salida de este comando que nos avisa de qué nos falta. A mi me dio un aviso de falta de las librerías libltdl y libusb. Nada que no se pueda arreglar con apt-get

$ sudo apt-get install libltdl-dev
$ sudo apt-get install libusb-dev

Lanzo de nuevo configure y compruebo los resultados...y sigue sin poder compilar. Resulta que la versión de libusb no es lo bastante reciente para él. Toca bajar del código fuente de libusb1.0, compilarlo e instalarlo (esto se empieza a parecer a las cosas que no me gustan de linux :-D)

wget http://ftp.de.debian.org/debian/pool/main/libu/libusbx/libusbx_1.0.11.orig.tar.bz2
tar xjvf libusbx_1.0.11.orig.tar.bz2
cd libusbx-1.0.11/
./configure
make
sudo make install

Ya tengo instalada la nueva libusb. Lanzo de nuevo configure y parece que todo es correcto.

./configure
make 
(zzz...zzzz....zzzz....zzzz...zzzz...zzzz....)
sudo make install

...y después de un buen rato ¡por fin! Por fin tienes instaladas las librerías, ahora toca compilar e instalar gphoto2. Antes instalamos las dependencias exigidas.

sudo apt-get install libexif-dev
sudo apt-get install libpopt-dev

Descargamos, compilamos e instalamos gphot2

wget http://downloads.sourceforge.net/project/gphoto/gphoto/2.5.0/gphoto2-2.5.0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fgphoto%2Ffiles%2Fgphoto%2F2.5.0%2F&ts=1358271589&use_mirror=freefr

(tendras que renombrar el archivo porque wget le pondrá un nombre muy largo)

tarx zvf gphoto2-2.5.0.tar.gz
cd gphoto2-2.5.0
./configure
make
sudo make install

Y ya tengo instalado por fin gphoto2 versión 2.5. Queda un detallito tienes que ejecutar el siguiente comando para que enlace correctamente las librerías:

sudo ldconfig

Y ahora sí que sí. Gphoto2 y librerías correspondientes correctamente instaladas

$ gphoto2 --version
gphoto2 2.5.0

Copyright (c) 2000-2012 Lutz Mueller and others

gphoto2 comes with NO WARRANTY, to the extent permitted by law. You may
redistribute copies of gphoto2 under the terms of the GNU General Public
License. For more information about these matters, see the files named COPYING.

This version of gphoto2 is using the following software versions and options:
gphoto2         2.5.0          gcc, popt(m), exif, no cdk, no aa, no jpeg, no readline
libgphoto2      2.5.0          all camlibs, gcc, ltdl, no EXIF
libgphoto2_port 0.10.0         gcc, ltdl, USB, serial without locking




Protegiendo un poco nuestra Raspberry Pi de ataques externos (ssh)

La historia de siempre, basta con conectar un aparato a internet para que un montón de bots empiecen a atacarlo a ver si consiguen acceder. A raíz de este post se me ocurrió investigar el fichero de log del sshd a ver si tenía algún intento de acceso ilegal. Pues en menos de 12 horas tenía ¡1728 intentos de acceso! La mayoría a la cuenta root.

Este es el comando que muestra por pantalla:
cat /var/log/auth.log | grep 'invalid user\|Failed'

...y este el que cuenta cuántos líneas aparecen:
cat /var/log/auth.log | grep 'invalid user\|Failed' | wc -l

Hay varias cosas que podemos hacer para evitar cualquier problema.

Contraseña
Es obvio pero la primera es asegurarnos de que cambiamos la contraseña por defecto y que no lo hacemos por otra que sea obvia como "12345", "password" y cosas así. Lo puedes hacer directamente desde el menú de raspi-config (sudo raspi-config) o con el comando passwd

Desactivar el login con root desde ssh
Edita el fichero de configuración de ssh

sudo nano /etc/ssh/sshd_config

Cambia "PermitRootLogin yes" por

PermitRootLogin no

Bloqueos ataques fuerza bruta
Añade estas línea al final del sshd_config para bloquear el número máximo de accesos fallidos desde una IP y el número máximo de sesiones simultáneas que se pueden abrir.


# Custom settings
MaxAuthTries 3
MaxStartups 5

Frikonsejo: Puedes comprobar que tu configuración del sshd es correcta mediante el comando

$ sudo sshd -t

Si no ves ningún mensaje de error es que la configuración es correcta. Es muy importante que compruebes que el archivo de configuración es correcto porque si no cuando reinicies el servicio (o la máquina) el servicio ssh no arrancará y no podrás conectarte

Cambio de puerto estándar
No es una medida definitiva pero te evitará muchos ataques automáticos de los bots que circulan por Internet. Basta con que cambies el puerto que has abierto en el router a cualquier otro no estándar. En la redirección indicas que sigues queriendo enviarlo al 22 de tu IP en la red interna. Pero ten cuidado porque muchos proveedores de internet no permiten conectarse al rango completo de puertos de tu router. Comprueba con una herramienta como http://www.yougetsignal.com/tools/open-ports/ si el puerto realmente está abierto y accesible.

Bloqueo de IP, límites de anchos de banda...
Hay muchas más estrategias que puedes aplicar para proteger tus puertos pero en ocasiones son algo rígidas y más orientadas a sistemas multiusuario.

Aquí tienes una buena colección de estrategias para proteger tu servidor ssh

ACTUALIZACIÓN: en vista de la cantidad de ataques por fuerza bruta que sufro en mi puerto 22 he instalado un servicio de baneo de IPs. Aquí lo explico con más detalle.

miércoles, enero 16, 2013

Configurar wifi usb en Raspberry Pi

Es muy fácil y económico añadir conectividad wifi a tu RPI. Hace poco pedí a Dealextreme este dispositivo wifi por USB pequeño y muy barato (por poco más de 6€ en casa).
Hace un rato me ha llegado y en un momento ya lo tengo funcionando. Bastaba con conectarlo para que lo reconociera así que sólo hace falta configurar los datos de nuestra wifi para tenerlo en marcha. Primero comprobamos que el sistema ha reconocido el dispositivo correctamente.


 $ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:40:af:2c  
          inet addr:192.168.0.254  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:121 errors:0 dropped:1 overruns:0 frame:0
          TX packets:105 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:15687 (15.3 KiB)  TX bytes:13555 (13.2 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:55 errors:0 dropped:0 overruns:0 frame:0
          TX packets:55 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:9890 (9.6 KiB)  TX bytes:9890 (9.6 KiB)

wlan0     Link encap:Ethernet  HWaddr e8:4e:06:0c:d4:27  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Sabiendo que el sistema ha reconocido correctamente el dongle vamos a configurar la wifi. Primero generamos la passphrase de nuestra wifi. Se hace con un simple comando:

$ wpa_passphrase SSID_DE_TU_RED PASSWORD
network={
ssid="SSID_DE_TU_RED"
#psk="PASSWORD"
psk=64958acd6XXXXXXXXXX9eecbac86243a19960224ace0d8e148c329ec
}

Copiamos en el portapapeles el valor del psk y lo guardamos para usarlo más adelante. A continuación editamos el archivo de configuración de los interfaces de red.

$ sudo joe /etc/network/interfaces

...y lo editamos de la siguiente forma:

allow-hotplug wlan0
#iface wlan0 inet manual
#wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface wlan0 inet dhcp
wpa-ssid "SSID_DE_TU_RED"
wpa-psk 64958acd6XXXXXXXXXX9eecbac86243a19960224ace0d8e148c329ec

iface default inet dhcp

(Deja las líneas del eth0 tal y como están)

...y ya está sólo hace falta reiniciar la RPI para que tengamos la wlan activa.

$ sudo reboot

Al reiniciar ya podemos ver activo nuestro dispositivo con su flamante IP

$ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:40:af:2c  
          inet addr:192.168.0.254  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:120 errors:0 dropped:2 overruns:0 frame:0
          TX packets:102 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:14730 (14.3 KiB)  TX bytes:13592 (13.2 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:55 errors:0 dropped:0 overruns:0 frame:0
          TX packets:55 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:9876 (9.6 KiB)  TX bytes:9876 (9.6 KiB)

wlan0     Link encap:Ethernet  HWaddr e8:4e:06:0c:d4:27  
          inet addr:192.168.0.9  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:26 errors:0 dropped:37 overruns:0 frame:0
          TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5608 (5.4 KiB)  TX bytes:4573 (4.4 KiB)

Fijar la IP
Es posible que quieras que la IP asignada sea fija para poder acceder a ella sin problemas. Edita de nuevo el fichero /etc/network/interfaces y sustituye los contenidos por los siguientes


auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
#iface wlan0 inet dhcp
#wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface wlan0 inet static
        address 192.168.0.254
        netmask 255.255.255.0
        network 192.168.0.0
        gateway 192.168.0.1
        wpa-ssid "SSID_DE_TU_RED"
        wpa-psk 64958acd6XXXXeecbac86243a19960224ace0d8e148c329ec
iface default inet dhcp

No olvides ajustar los detalles de IP, SSID y PSK a los de tu red.

martes, enero 15, 2013

Acceder desde Internet a tu Raspberry Pi. IPs dinámicas, puertos, DNS y túneles SSH

Una de las ventajas de la RPI es precisamente que su bajo consumo hace que no sea un crimen dejarla encendida todo el día. Eso sí, para que sea realmente útil debes tener la posibilidad de acceder a ella desde cualquier ordenador, no solo desde tu LAN. En esto no se diferencia de cualquier otro ordenador pero demos un repaso a lo que necesitamos.

  • La RPI configurada  y conectada a tu red local
  • Acceso a nuestro router para redireccionar puertos
  • Un ordenador con un cliente SSH: en linux/unix/mac directamente la línea de comandos, desde windows puedes usar Putty.
  • Opcionalmente un servicio de DNS dinámico (en nuestro caso www.dnsexit.com) y una cuenta shell para probar el servicio ssh desde el exterior de nuestra red.

Configurar IP local fija
Comenzamos por fijar la IP de nuestra RPI. Esto es imprescindible para que la cuando habramos el puerto en el router siempre la encuentre en la misma dirección. Para ello editamos el fichero /etc/network/interfaces

pi@raspberrypi ~ $ sudo nano /etc/network/interfaces

...y comentamos la línea del DHCP y/o la sustituimos directamente por este código: 

#iface eth0 inet dhcp
iface eth0 inet static
address   192.168.0.254
netmask   255.255.255.0
network   192.168.0.0
gateway   192.168.0.1
broadcast 192.168.0.255

Podéis ver que he escogido la dirección 192.168.0.254 para mi RPI y que mi red está en el rango 192.168.0.0. Debes adaptar esta configuración a tu red, puede que en tu caso sea la 192.168.1.0 o cualquier otra. Para que los cambios sean efectivos debes reiniciar los dispositivos de red con ifdown y ifup, pero si estás accediendo por red ¡perderás la conectividad! Casi que lo más fácil es que reinicies directamente la RPI.

pi@raspberrypi ~ $ sudo reboot

Aseguramos que podemos acceder por ssh a nuestra RPI. A estas alturas ya debes tener claro como se hace.

Desde otra máquina linux/mac:

ssh pi@192.168.0.254

Por cierto, si no has cambiado la contraseña de tu RPI sería buen momento para hacerlo antes de ponerla a disposición de todo el mundo en Internet.

Accediendo desde internet. Redirección de puertos
Para poder acceder a una máquina de una red local desde internet debes abrir un puerto en tu router y redireccionarlo a la máquina y puerto correspondiente. En nuestro caso debes acceder a tu router y redireccionar el puerto 22 externo de tu router al mismo puerto 22 y a la IP que has escogido para tu RPI. Esta configuración es similar en todos los routers pero a la vez casi siempre el menú es diferente. Busca información al respecto en internet si tienes dudas.

Puede que más adelante quieras que externamente el puerto no sea el 22 o abrir sólo el puerto de web (80) pero como algunos ISP no permiten acceder a todos los puertos lo mejor es que de momento lo pruebes así.

Si has redireccionado correctamente los puertos y configurada correctamente la IP fija ya deberías poder acceder por SSH a tu RPI desde internet. Comienza comprobando que el puerto está correctamente abierto con http://www.yougetsignal.com/tools/open-ports/. La misma página te dice cuál es la dirección ip externa de tu router, selecciona el puerto 22 y comprueba que te indica que el puerto está abierto.


Bien, si todo ha ido bien ya podrías conectar por ssh desde cualquier máquina de internet. Si tienes acceso a una cuenta shell gratuita de las que hay por internet podrías conectarte (usando la cadena pi@ip_externa) para comprobarlo. Yo tengo una cuenta que uso con frecuencia en http://www.cjb.net/shell.html por si te sirve de algo.

Configurando DNS para una IP dinámica
Ya podemos acceder a nuestra RPI desde internet, el problema es que la dirección IP que le asigna nuestro ISP al router suele cambiar cada vez que lo reiniciamos, además no suelen ser precisamente fácil de recordar. Para solventarlo lo mejor es usar un servicio de DNS dinámica gratuito.

Yo he utilizado por recomendación del foro de RPI  el servicio http://www.dnsexit.com/ que te "regala" un dominio del tipo loquesea.com. Una recomendación, si tienes intención de colgar una web no uses un dominio "regalado", como empieces a ser popular rápidamente se apropiarán de él, pero para un servicio personal es ideal.

El caso es que una vez registrados obtendrás un dominio gratuito. Lo que haremos ahora es instalar un servicio en la RPI que periodicamente comprobará nuestra IP externa y la actualizará siempre que sea preciso. ¿Cómo lo hacemos? Pues así de fácil:

wget http://downloads.dnsexit.com/ipUpdate-1.6-2.tar.gz
tar xzvf ipUpdate-1.6-2.tar.gz 
sudo ./setup.pl

Cuando nos pregunte si queremos instalarlo como un daemon responderemos que sí para que se inicie con la RPI. Si te dice algo de que el fichero no existe vete a http://downloads.dnsexit.com/ y comprueba que versión es la que está activa.

Si todo ha ido bien podrás usar usar la dirección cadena pi@tudominio.com para conectarte a tu RPI. Muy cómodo ¿verdad?

Accediendo a otros puertos en la RPI
Tal vez quieras a acceder a otros puertos de tu RPI, típicamente al puerto 80 del servidor web, pues tienes dos opciones.
  1. Abrir otro puerto en tu router. Es la opción si quieres que esté accesible para cualquiera siempre que tu RPI esté encendida. Basta con hacerlo igual que antes con el 22.
  2. Crear un tunel SSH. Así sólo tú podrás acceder en el momento que quieras al puerto que desees. Un túnel ssh tiene la ventaja adicional de que va encriptado y es tremendamente seguro. Crea una conexión transparente entre un puerto de nuestra máquina y otro puerto de una máquina de la red destino, en nuestro caso será la propia RPI. ¿Cómo se configura? Muy sencillo:
Supongamos que tienes el servidor web activo en tu RPI. Desde una máquina externa hacemos la siguiente conexión:

gonzalo@matilda:~$ ssh -L 81:localhost:80 pi@tudominio.com

Así creamos un tunel  entre puerto 81 de la máquina que estamos usando y el puerto 80 de la RPI (localhost).

Ahora desde el ordenador desde el que hemos iniciado la conexión abrimos una ventana del navegador y  visitamos la dirección http://localhost:81. Si todo ha ido bien debería responder el servidor web de tu RPI.

Podrías también abrir otros puertos como el del VNC en el caso de que tuvieras instalado el servicio y quisieras acceder remotamente al escritorio, o al MySQL o a cualquier servicio en general que se cuelgue de un puerto local. Puedes abrir multiples puertos al mismo tiempo con una única cadena de conexión. Como puedes imaginar, este método es muy útil porque permite acceder a tantos puertos como necesites de tu RPI abriendo un único puerto en  tu router.

Accesos ilegales
Haberlos haylos... hay bots que recorren internet buscando puertos ssh abiertos (de ahí la importancia de no usar la contraseña por defecto). Podrías cambiar el puerto abierto en tu router del 22 a cualquier otro para luego indicar que se redirija al puerto 22 en la red interna. Pero si tienes curiosidad y no te preocupa demasiado déjalo un par de días abierto a ver quien intenta acceder ilegalmente. Puedes comprobarlo con el comando:

pi@raspberrypi ~ $ cat /var/log/auth.log* | grep "Invalid user" 
Jan 15 09:04:00 raspberrypi sshd[23921]: Invalid user ____ from 202.77.107.203

En mi caso, en menos de 12h ya tenías varios intentos de acceso :-D. En este post se habla un poco más del tema.

viernes, enero 11, 2013

Añadiendo un botón de reset a Raspberry Pi

Aprovechando que tenía un botón de pulsación para circuitos por casa me he animado a añadir a la Raspberry Pi para usarlo como reset. No me hace mucha gracia tener que desenchufarla para reiniciarla, porque con el tiempo me temo que acabaría cascando el conector, así que este método es perfecto.

La última revisión de la RPI incluyó incluyó un par de pines que al cerrarlos resetean la máquina. En la foto los tienes localizados.
Usé un sencillo pulsador para circuitos que adapté con unos pequeños alicantes para que encajara en el hueco y quedarán cogidos como un clip (el de la derecha).


Quedando de la siguiente forma


Una prueba de sencilla demostró que funcionaba perfectamente. No lo he fijado definitivamente con soldadura por dos razones: se agarra con suficiente fuerza por el momento y con el tiempo es posible que quiera montar la RPI en algún proyecto y si tiene caja propia entonces soldaré un par de pines y añadiré un botón de reset cableado que saqué de un ordenador.


Actualización: Se me olvidó mencionar que la información sobre el botón de reset la encontré gracias a los estupendos apuntes sobre RPI de @ulysess10

jueves, enero 10, 2013

Capturando imágenes de la webcam con Raspberry PI

Tras conectar la webcam y comprobar con lusb y dmesg que está correctamente cargada, instalamos el software necesario. Entre los múltiples paquetes disponibles escogí

sudo apt-get install uvccapture

Ya debería funcionar con:

uvccapture -v -m

Y se puede parametrizar un poco para brillo, contraste, saturación...:


pi@raspberrypi ~ $ uvccapture -v -B30 -C100 -S150 -G1 -q100 
Using videodevice: /dev/video0
Saving images to: snap.jpg
Image size: 320x240
Taking snapshot every 0 seconds
Taking images using mmap
Resetting camera settings
ioctl querycontrol error 22 
Setting camera brightness to 30
Setting camera contrast to 100
Setting camera saturation to 150
Setting camera gain to 1
ioctl querycontrol error 22 
Saving image to: snap.jpg




Parece que no consigo configurar la captura a 640x480 que es una resolución admitida por la cámara pero que el programa de captura no llega a leer correctamente  :-P


Probaré con otra cámara...