Enviar correos con la Raspberry Pi desde la línea de comandos

Para un proyecto que tengo entre manos necesito poder enviar automáticamente un fichero con un log por correo electrónico desde una Raspberry Pi. Esto se hace con los programas ssmtp y mpack. En esta página se explican muy bien los pasos, que seguí más o menos al pie de la letra.

Primero instalo el programa ssmtp:

sudo apt-get update
sudo apt-get install ssmtp

Ahora edito el fichero de configuración:

sudo nano /etc/ssmtp/ssmtp.conf

Comento los parámetros que vienen por defecto y pego lo siguiente (tuve que darle varias vueltas hasta hacerlo funcionar):

root=midireccion@miservidor.com
mailhub=smtp.miservidor.com:465
rewriteDomain=miservidor.com
AuthUser=midireccion@miservidor.com
AuthPass=micontraseña
FromLineOverride=YES
UseTLS=YES

También tengo que editar el siguiente fichero:

sudo nano /etc/ssmtp/revaliases

Y pego al final del todo:

pi:midireccion@miservidor.com:smtp.miservidor.com:465

Y ahora pruebo a enviar un correo:

ssmtp direccionDeCorreo@dominio.com
subject: prueba
funciona?

Y envío el correo pulsando Ctrl+D.

¡Funciona!

Ahora quiero poder enviar un fichero adjunto. Para ello tengo que instalar el programa mpack:

sudo apt-get install mpack

Y para enviar un fichero por correo es tan sencillo como ejecutar:

mpack -s "Este es el asunto" fichero.txt direccion@correo.com

Túnel reverso SSH

Voy a contar un método muy útil para poder acceder a un servidor remoto al que por diversos motivos en principio no tenemos acceso directo por SSH, creando un túnel reverso tenebroso por SSH.

Una aplicación podría ser para poder acceder a una Raspberry Pi que tiene conexión a internet por medio de un modem 3G de la que desconocemos la IP (y que probablemente aún conociéndola, el ISP no nos dejaría acceder a la misma por SSH). Es el caso que tengo entre manos para una Raspberry Pi que quiero dejar monitorizando unas temperaturas de fraguado del hormigón en una obra, que cuento en esta entrada.

Necesitamos en primer lugar un Servidor A al que tenemos acceso por SSH. Podría ser una Raspberry Pi ubicada dentro de una red, y a la que podemos acceder desde fuera de la red. Para ello es muy posible que hayamos tenido que redirigir puertos del Router de la red a la misma, como es mi caso. Tengo el router configurado para que cualquier petición de conexión a un puerto concreto, digamos el 22122, se redirija al puerto 22 de la Raspberry Pi, que está escuchando y esperando conexiones SSH por ese puerto.

Tengo además instalado un servicio externo de DNS (en mi caso el gratuito No-IP) en ese Servidor A de forma que se le asigne un determinado nombre al host a la IP dinámica que mi ISP me ofrece. Digamos que ese nombre es miServidor.com

Desde el Servidor B (la Raspberry Pi con conexión 3G a internet, a la que voy a querer poder acceder en el futuro) pruebo a conectarme al Servidor A:

ssh usuarioMiServidorA@miServidor.com

Introduzco la contraseña del usuario usuarioMiServidor, y listo, ya esto conectado desde el Servidor B al Servidor A por SSH.

Habiendo comprobado que tengo acceso, salgo:

exit

Y ahora vuelvo a entrar, pero con el siguiente comando:

ssh -N -R 2222:localhost:22 usuarioMiServidorA@miServidor.com -p 22122

Y vuelvo a introducir la contraseña para conectarme (más abajo veremos cómo evitar tener que introducir la contraseña). Con esto lo que le estoy diciendo al Servidor A es que que toda conexión que le llegue al puerto 2222 (por ejemplo) lo redirija por el túnel al puerto 22. La opción -N es específica para redireccionamiento de puertos, e indica que no viene un comando después.

Y ahora, desde el Servidor A, abro el túnel para conectarme con el Servidor B, que básicamente consiste en redirigir todo el tráfico SSH a un determinado puerto:

ssh -l usuarioServidorB -p 2222 localhost

Introduzco la contraseña del usuarioServidor B y ¡ya estoy en el Servidor B!

Hasta aquí todo bien, pero nos quedan cosas por hacer. Por un lado, como en teoría no voy a tener acceso al Servidor B al iniciar la conexión, es necesario que se conecte por SSH sin necesitar introducir la contraseña. Y por otro, tendremos que tener algún tipo de servicio que se encargue de vigilar que el túnel está funcionando, y volver a abrirlo en el caso de que se haya caído.

Acceso SSH por medio de certificado

En el Servidor B (desde el que quiero acceder al Servidor B sin que me pida la contraseña), tengo que generar el par de claves público-privada. :

cd ~/.ssh

ssh-keygen -t rsa

Doy al enter varias veces aceptando las opciones por defecto, sin passphrase. Con esto se generan dos ficheros: id_rsa y id_rsa.pub.

Ahora copiamos la clave pública al Servidor A:

scp -P 22122 id_rsa.pub usuarioServidorB@servidorB:.ssh/authorized_keys

(O lo copiamos con un pincho USB o como se quiera.)

Ahora pruebo a conectarme desde el Servidor B al Servidor A, y a ver si no me pide la clave:

ssh usuarioMiServidorA@miServidor.com -p 22122

Si a la hora de hacer la conexión tenemos algún problema, puede interesar empelar el comando con la opción -v, y ver lo que pasa:

ssh -v usuarioMiServidorA@miServidor.com -p 22122

¡Funciona!

Control de la conexión

Ahora tenemos que comprobar que el túnel permanece abierto a lo lagro del tiempo, y garantizar que se reconecta en caso de pérdida de que lo haya perdido.

Creo un fichero ~/create_ssh_tunnel.sh, con el siguiente contenido (sacado y adaptado de aquí):

#!/bin/bash
createTunnel() {
/usr/bin/ssh -N -R 2222:localhost:22 pi@miServidor.com -p 22122
if [[ $? -eq 0 ]]; then
echo Tunnel to jumpbox created successfully
else
echo An error occurred creating a tunnel to jumpbox. RC was $?
fi
}
/bin/pidof ssh
if [[ $? -ne 0 ]]; then
echo Creating new tunnel connection
createTunnel
fi

Este script comprueba que haya un proceso ssh ejecutándose, y si no, abre el túnel.

Hacemos ejecutable el script:

chmod 700 ~/create_ssh_tunnel.sh

Modifico crontab para que se ejecute cada minuto:

crontab -e

Y añado al final del fichero:

*/1 * * * * ~/create_ssh_tunnel.sh > tunnel.log 2>&1
Con esto decimos que se ejecute el script cada minuto.

Y listo, ya está funcionando.

Referencias

https://blog.devolutions.net/2017/3/what-is-reverse-ssh-port-forwarding

https://www.tunnelsup.com/raspberry-pi-phoning-home-using-a-reverse-remote-ssh-tunnel/

 

 

Manejar un motor stepper con un driver DRV8825 y una Raspberry Pi

Para un proyecto que tengo entre manos (un scanner 3D por fotogrametría, ver esta entrada), quiero controlar un motor a pasos (stepper) con una Raspberry Pi. En esta entrada ya expliqué cómo hacerlo con Arduino, pero ahora lo voy a hacer con la Rapsberry Pi, y voy a emplear un driver DRV8825.

En teoría, al no ser linux un sistema de «tiempo real», no es muy indicado para manejar directamente elementos que requieren un control preciso del tiempo. Para mis propósitos, como no necesito controlar de forma muy precisa la velocidad, sino la posición, me sirve sin problemas.

0j42241200

Características principales del driver DRV8825:

  • Para motores bipolares
  • Permite microstepping de hasta 1/32
  • 1.5  por fase o 2.2A si se dispone de ventilación forzada de aire o disipadores
  • Interfaz casi idéntica al A4988
  • 45 V máximo
  • Control de corriente máxima con un potenciómetro

El motor que tengo es un motor NEMA 17 JK42HS40-1704 13A, comprado aquí por 12.50 €.

Características:

  • Número de parte: JK42HS40-1704 13A
  • Tamaño de marco: NEMA17
  • Ángulo del paso: 1,8 grados
  • Voltaje: 3.4V
  • Corriente: 1,7 A/phase
  • Resistencia: 2,0 ohmios/fase
  • Inductancia: 3,0 mH/phase
  • Llevar a cabo el esfuerzo de torsión: 4000g-cm 58.30 OZ-IN
  • Inercia del rotor: 54 g-cm2
  • Esfuerzo de torsión de la muesca: 0,22 kilogramo-cm
  • Número de ventajas de alambre: 4
  • Peso: 0,24 kilogramos
  • Longitud: 40m m
  • Eje del motor: 5mm
  • Longitud del árbol delantero: 20 mm
  • Certificación: CE, ROHS, ISO9001

 

Para alimentar el motor empleo una fuente de alimentación de un ordenador (ver esta entrada).

Siguiendo las instrucciones de la página de Pololu, voy a emplear el siguiente modo de conexión, con paso completo (sin microstepping):

El esquema Fritzing sería así:

Manejar un motor paso a paso con DRV8825 y Raspberry Pi

La conexión de los cables del motor al DRV8825 la hago así:

  • B2: azul
  • B1: rojo
  • A1: negro
  • A2: verde

Para no dañar el motor tenemos que regular inicialmente el potenciómetro a la mínima potencia, girando el potenciómetro en sentido antihorario hasta el final, y más adelante ajustarlo hasta la capacidad del motor. En este vídeo se explica cómo regular adecuadamente la intensidad.

Empiezo con el motor desconectado. Lo primero, calculo el voltaje por cada fase. Para eso me fijo en las características de mi motor. Ahí me dicen que el motor es de 1.7 A / fase. Tendré que limitar el DRV8825 a este valor. Por encima de 1.5 A (y hasta 2.2A) el controlador DRV8825 debe tener ventilación forzada de aire o un disipador, así que le pego un disipador (me venía al comprarlo con el DRV8825), pues pretendo fijarlo en la capacidad máxima del motor.

Ahora tengo que ajustar la corriente del DRV8825 con el potenciómetro. Primero tengo que averiguar a cuánto he de limitar esa corriente. Para ello empleo la fórmula que viene en la hoja de especificaciones del driver:

Current Limit = VREF × 2

(Ojo, que por muchas páginas se ven otras fórmulas; hay que emplear la fórmula específica de nuestro driver).

Entonces:

1.7 = VREF x 2

VREF = 0.85 V

Pero ojo, este voltaje va asociado a la corriente máxima que recibirá el motor, y depende de la configuración de micropasos. Hay que consultar en la Tabla 2 de la hoja de especificaciones del DRV8825. En mi caso, con paso completo (full step), la corriente es un 71%, así que deberé multiplicar por este factor el resultado anterior:

VREF = 0.71 · 0.85 = 0.60 V

Así que el voltaje límite que debo ajustar es 0.60 V por fase.

Ahora tengo que ver dónde medir con el multímetro en el DRV8825:

Aunque es más fácil medir directamente desde el potenciómetro:

Desconecto el motor, pero alimento con 12V el DRV8825 y alimento también el Arduino a través del puerto USB. Con todo así, mido el voltaje y ajusto el potenciómetro hasta alcanzar mis VREF calculado antes (0.60 V).

Ya tengo el driver ajustado a mi motor, así que ya puedo conectarlo y empezar a utilizarlo.

 

En la Raspberry Pi voy a emplear código en Python. He conectado el pin de STEP del DRV8825 en el pin GPIO7 de la Raspberry Pi (pin 26), y el de DIR en el pin GPIO8 (pin 26). Mandando señales a estos pines podré indicar que se avance un paso (pin STEP), y cambio de dirección en en pin DIR. Por como tengo conectado todo, son pasos completos, nada de micropasos, que no me hacen falta por el momento.

Con el código siguiente en Python el motor da una vuelta completa en una dirección, y luego cambia de dirección y da otra vuelta:

# -*- coding: utf-8 -*-

import time                     #Para las pausas
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)        #Usar la numeración de pines de la placa

pinDir = 24                     #Pin DIR
pinStep = 26                    #Pin Step
numSteps = 200                  #Número de pasos del motor
microPausa = 0.005              #Número de segundos de pausa


GPIO.setup(pinDir,GPIO.OUT)
GPIO.setup(pinStep,GPIO.OUT)

while True:

        GPIO.output(pinDir,0)           #Establezco una dirección (0 o 1)

        for x in range(0,numSteps):
                GPIO.output(pinStep, True)
                time.sleep(microPausa)
                GPIO.output(pinStep, False)
                time.sleep(microPausa)

        time.sleep(microPausa)

        GPIO.output(pinDir, 1)          #Cambio de dirección

        for x in range(0,numSteps):
                GPIO.output(pinStep, True)
                time.sleep(microPausa)
                GPIO.output(pinStep, False)
                time.sleep(microPausa)

GPIO.cleanup()          #Para acabar correctamente

Y aquí un vídeo mostrando el motor en funcionamiento:

 

Referencias

https://www.pololu.com/product/2133

 

https://forum.pololu.com/t/drv-8825-stepper-motor-steps-and-delay-between-pulses/7530

Raspberry Pi Stepper Motor Tutorial

Power supply de una fuente de alimentación ATX de PC

Para trabajar con todo tipo de «inventos» es muy útil tener una fuente de alimentación. Las fuentes de ordenador de sobremesa se pueden adaptar de forma muy fácil para esto, y suministran (sin necesidad de hacer nada) diferentes voltajes:

  • +3.3 V
  • +5 V
  • +12 V
  • -12 V

(Combinando los anteriores podemos obtener otros voltajes, naturalmente).

Hay inifinidad de tutoriales por internet en el que explican cómo hacer esto, aunque relamente no hace falta un tutorial porque es cortar cables y listo.

Como puntos a destacar, para que arranque la fuente es necesario puentear el cable verde a cualquier cable tierra (negro). Y en función de lo antigua que sea la fuente será necesario añadir una resistencia o no; en mi caso no fue necesario.

Para hacer los agujeros en la cargasa recomiendo empezar con pequeños taladros y luego hacerlos más grandes.

Compré unos conectores como estos y estos los que realmente compré ya no los veo, pero hay miles)

Y para la próxima que me haga, las conexiones las voy a hacer con estas horquillas, que facilitará mucho la vida.

No hice muchas fotos durante el montaje, pero es que es muy básico todo…

 

Referencias

http://www.instructables.com/id/Computer-Power-Supply-to-Bench-Power-Supply-Adapte/?ALLSTEPS

http://www.wikihow.com/Convert-a-Computer-ATX-Power-Supply-to-a-Lab-Power-Supply

 

Acceder a la consola de una Raspberry Pi (Zero) por UART con un adaptador USB PL2303

La Pi Zero es una maravilla, si no fuera por lo complicado que es acceder a su consola, al tener un único puerto USB y no tener ni WiFi integrado ni una conexión de red: hace falta conectarse con un teclado y a una pantalla a través de HDMI, o a través de un hub USB, más una tarjeta WiFi USB, etc.

Una forma más sencilla de poder acceder a la consola de la Raspberry Pi es a través de UART, con un cable específico USB, o con un adaptador USB PL2303. Esto es válido no solo para la Raspberry Pi Zero, sino para todas las Raspberrys.

Adaptador USB – TTL PL2303 (vista delantera)

Adaptador USB – TTL PL2303 (vista trasera)

Lo primero es activar la comunicación en serie en la Raspberry Pi. Esto lo podemos hacer con sudo raspi-config
y después en Advanced Options – Serial decimos sí a permitir hacer login por serie. Otra alternativa es editar el ficher /boot/config.txt y añadir al final enable_uart=1. En cualquier caso, es necesario reiniciar tras hacer el cambio.

Ahora es necesario instalar los drivers en nuestro ordenador para que reconozca el PL2303. Para ello nos descargamos de la página oficial el driver correspondiente a nuestro sistema operativo (para Mac, para Windows, para Linux no hace falta, viene por defecto). Tras instalarlo tenemos que reiniciar el ordenador.

Como en Windows me ha dado problemas (no reconoce el módulo), al final lo he probado desde mi Mac y ha funcionado. He hecho lo siguiente.

 

Tras instalar el driver del enlace anterior y reiniciar, he conectado el adaptador (a su vez conectado a la Raspberry Pi) de la siguiente forma:

Ojo, que el TXD de la Raspberry Pi se conecta al RXD del PL2303 y viceversa.

Esquema conexión PL2303 a Raspberry Pi Zero

Tras comprobar que todo estaba bien conectado, he abierto una consola en mi Mac y he escrito el siguiente comando: screen /dev/cu.usbserial 115200. ¡Y ya está! Tras hacer eso y dar al enter, ya nos pide el usuario y contraseña y ya estamos conectados a la Raspberry Pi.

(Ojo, que a lo mejor en otros casos el dispositivo podrá tener otro nombre; entonces bastará con teclear screen /dev/cu. y darle al TAB para ver los que hay, y escogemos.)

Instalar No-IP en la Raspberry Pi

Voy a explicar a continuación cómo instalar y configurar una cuenta de No-IP para tener una dns dinámica que sea capaz de actualizarse periódicamente para poder solventar el problema que supone la IP dinámica que seguramente nos provee nuestro ISP.

Lo primero, hay que registrarse en no-ip y obtener un nombre de dominio.

A continuación

mkdir noiptemp
cd noiptemp
wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
tar -zxvf noip-duc-linux.tar.gz
cd noip-2.1.9-1/
make
sudo make install

 

Al compilarlo a mí me dio un par de errores:

gcc -Wall -g -Dlinux -DPREFIX="/usr/local" noip2.c -o noip2
noip2.c: In function ‘dynamic_update’:
noip2.c:1595:6: warning: variable ‘i’ set but not used [-Wunused-but-set-variable]
  int i, x, is_group, retval, response;
      ^
noip2.c: In function ‘domains’:
noip2.c:1826:13: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
         int x;
             ^
noip2.c: In function ‘hosts’:
noip2.c:1838:20: warning: variable ‘y’ set but not used [-Wunused-but-set-variable]
         int     x, y, z;
                    ^

 

Pero son de variables definidas que no se usan, así que no pasa nada.

Ojo, que es posible que haya que cambiar el nombre de la carpeta, si la versión que descarguéis es posterior.

El instalador nos pregunta nuestro correo o nombre de usuario de no-ip, lo introducimos. También el nombre del host, y el intervalo de refresco. Por defecto viene 30 minutos; yo lo cambio a 5 minutos. También pregunta si queremos ejectuar algo tras actualizar la IP; en mi caso digo que no.

El instalador guarda el archivo de configuración en /usr/local/etc/no-ip2.conf

Y ya podemos borrar la carpeta temporal donde descargamos y descomprimimos el instalador.

Ahora que está instalado y configurado, tenemos que hacer que se inicie el proceso cada vez que reiniciemos. Para ello creamos un rc script:

sudo nano /etc/init.d/noip2

 

Y copiamos el siguiente contenido:

### BEGIN INIT INFO
# Provides:          noip2
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

 #! /bin/sh
# /etc/init.d/noip


# If you want a command to always run, put it here


# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting noip"
    # run application you want to start
    /usr/local/bin/noip2
    ;;
  stop)
    echo "Stopping noip"
    # kill application you want to stop
    killall noip2
    ;;
  *)
    echo "Usage: /etc/init.d/noip {start|stop}"
    exit 1
    ;;
esac

exit 0

Y por último:

sudo chmod +x /etc/init.d/noip2
sudo update-rc.d noip2 defaults

Ahora debemos hacer que se arranque tras cada reinicio. Para ello agregamos /usr/local/bin/noip2 al fichero /etc/rc.local, antes de la última línea, donde pone exit 0.

Ya está. Reiniciamos y debería funcionar.

Crear un servidor VPN en una Raspberry Pi

Uno de los primeros proyectos que hice con una Raspberry Pi fue crear un servidor VPN para poder acceder a mi red doméstica y navegar tranquilamente desde conexiones públicas. O, para cuando viajo a países como China, en los que el acceso a ciertas páginas está bloqueado, poder navegar tranquilamente.

Tengo una Raspberry Pi 2 permanentemente encendida, con una distribución OpenElec para usar Kodi al ver la televisión. Quería utilizar esta máquina como servidor VPN, pero tras investigar mucho he decidido desistir por los muchos problemas que tiene el emplear una distribución no completa como es OpenElec. Así que mejor lo hago en otra Raspberry exclusiva (una B), con una distribución decente, como es Raspbian.

Hay miles de tutoriales por internet sobre cómo hacer esto. Yo voy a seguir fundamentalmente este en dos partes, que me parece maravilloso (aunque hay varias cosas que han cambiado con las nuevas versiones de OpenVPN y no se puede seguir tal cual):

Building A Raspberry Pi VPN Part One: How And Why To Build A Server
Building A Raspberry Pi VPN Part Two: Creating An Encrypted Client Side

Configuraré mi portátil del trabajo (Windows), mi portátil personal (Mac) y mi iPhone para poder acceder a la VPN.

Pasos previos

Instalo Raspbian, cambio la contraseña, compruebo que puedo acceder a la Raspberry Pi por SSH, desde otro ordenador conectado a la misma red local. Y actualizo todo con sudo apt-get update y sudo apt-get upgrade.

También tengo que asegurarme de que la Raspberry Pi tiene asignada una IP estática dentro de la red local, o bien a mano (ver esta entrada) o en mi router. Hecho (no explico cómo hacerlo por el router porque en cada router se hace de una forma, aunque todos son similares). Supongamos que es la 192.168.1.45.

También seguramente necesite un servidor dns dinámico como no-ip.com, para poder acceder desde cualquier sitio al servidor, que seguramente tenga una IP dinámica. Puedo hacerlo siguiendo las instrucción ques expliqué en esta entrada.

Una cosa más en el router: debo hacer que todo paquete que llegue al puerto 1194 UDP sea dirigido a mi Raspberry Pi. Hecho (tampoco lo explico, si tienes dudas, googlea tu modelo de router).

Instalando OpenVPN

Instalo OpenVPN:

sudo apt-get install openvpn easy-rsa

 

Se me instala la versión 2.3.4.

Voy a generar las claves RSA. Empiezo por darme permiso de supersusuario, para no tener que andar haciendo sudo todo el rato:

sudo -s

 

Vamos a emplear easy-rsa.

Y ahora:

mkdir /etc/openvpn/easy-rsa
cp /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
nano /etc/openvpn/easy-rsa/vars

 

Busco dentro del fichero /etc/openvpn/easy-rsa/vars la línea que dice export EASY_RSA="`pwd`" y lo cambio por:

export EASY_RSA=”/etc/openvpn/easy-rsa” 

 

Y ahora genero los certificados, ejecutando los siguientes comandos:

source ./vars
./clean-all
./build-ca

 

¡Ojo! Si no es la primera vez que seguimos estos pasos es posible que ya tengamos algunos certificados generados en el directorio /etc/openvpn/easy-rsa. En este caso, NO debemos ejecutar el comando ./clean-all

Al ejecutar ./build-ca saltarán una serie de preguntas (Country name, State or Province Name, Locality Name, Organization Name, Organizational Unit Name, Common Name, Name), que yo prefiero no rellenar y dejo los valores por defecto, pulsando Enter.

Ahora definimos el nombre del servidor, en mi caso raspivpn:

./build-key-server raspivpn

 

Nuevamente, nos pedirá rellenar una serie de nombres, que dejo en sus valores por defecto, fijándome que el Common Name que me ofrece por defecto y apruebo es el que di al servidor, raspivpn. El Challenge Pasword lo dejo en blanco, y cuando me pregunte «Sign the certificate? [y/n]», pues diré que sí (y), naturalmente.

Con esto ya tenemos configurado el servidor. Ahora nos queda generar las claves de los clientes y configurarlos.

Creo un certificado para cada usuario:

./build-key-pass usuario1
./build-key-pass usuario2
./build-key-pass usuario3
./build-key-pass usuario4
./build-key-pass usuario5
...

 

Introduzco la contraseña que quiero tenga cuando dice «Enter PEM pass phrase», y el resto de opciones por defecto.

Y ahora encriptamos las llaves con des3:

openssl rsa -in usuario1.key -des3 -out usuario1.3des.key
openssl rsa -in usuario2.key -des3 -out usuario2.3des.key
openssl rsa -in usuario3.key -des3 -out usuario3.3des.key
openssl rsa -in usuario4.key -des3 -out usuario4.3des.key
openssl rsa -in usuario5.key -des3 -out usuario5.3des.key

 

E introducimos una nueva contraseña (o la misma).

Volvemos al directorio de easy-rsa:

cd /etc/openvpn/easy-rsa/ 

 

Ahora generamos el intercambio de llaves Diffie-Hellman. Esto puede tardar (en mi caso, una hora y cuarto, porque dejé la opción por defecto de encriptación 2048 bit):

./build-dh

 

Y la protección contra un ataque de DoS, generando una llave HMAC estática:

openvpn --genkey --secret keys/ta.key

 

Ya está todo instalado y creado. Falta configurar OpenVPN. Para ello vamos a crear un fichero /etc/openvpn/server.conf con el contenido de este archivo.

nano /etc/openvpn/server.conf

 

Más adelante he descubierto que OpenVPN no arranca tras reiniciar el servidor. Investigando, he llegado a que hay que comentar la primera línea de este fichero: # local 192.168.1.45. Entonces, en mi caso, lo dejo así:

#local 192.168.1.45 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
dev tun
proto udp #Some people prefer to use tcp. Don't change it if you don't know.
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/raspivpn.crt # SWAP WITH YOUR CRT NAME
key /etc/openvpn/easy-rsa/keys/raspivpn.key # SWAP WITH YOUR KEY NAME
dh /etc/openvpn/easy-rsa/keys/dh2048.pem # If you changed to 2048, change that here!
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OpenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.1.45 255.255.255.0" # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
# Set primary domain name server address to the SOHO Router
# If your router does not do DNS, you can use Google DNS 8.8.8.8
push "dhcp-option DNS 192.168.1.1" # This should already match your router address and not need to be changed.
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1

 

Otra cosa, tenemos que redirigir el tráfico de internet, ya que Raspbian por defecto no lo hace. Para ello editamos el siguiente fichero:

nano /etc/sysctl.conf

 

Buscamos la línea donde dice:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

 

Y lo descomentamos:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

 

Aplicamos los cambios con el siguiente comando:

sysctl -p

 

Ahora queda desbloquear OpenVPN en el firewall, y además hacer que se haga en cada reinicio, ya que las excepciones del cortafuegos no se quedan grabadas. Para ello creamos este pequeño script:

nano /etc/firewall-openvpn-rules.sh

 

Y dentro del fichero escribimos lo siguiente:

#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.1.45

 

Grabamos y salimos. Ahora toca darle permisos de ejecución a este fichero, y cambiarle el usuario a root:

chmod 700 /etc/firewall-openvpn-rules.sh 
chown root /etc/firewall-openvpn-rules.sh

 

En las versiones anteriores de Raspbian, bastaba con editar el fichero /etc/network/interfaces:

nano /etc/network/interfaces

 

buscar la línea:

iface eth0 inet manual

 

y debajo de ella, con un sangrado, añadir:

    pre-up /etc/firewall-openvpn-rules.sh

 

Pero si se tiene Raspbian Jessie o superior, hay que añadir además «auto eth0» en la línea anterior, de forma que finalmente debe quedar así:

auto eth0
iface eth0 inet manual
   pre-up /etc/firewall-openvpn-rules.sh

 

Con esto ya garantizamos que tras cada reinicio se abre el Firewall para OpenVPN. Así que reiniciamos la Raspberry Pi:

reboot

 

Configurando el cliente

Ya tenemos el servidor VPN en marcha. Ahora vamos a configurar los clientes.

Pero seguimos todavía en el servidor. Vamos a crear los ficheros de configuración que instalaremos en los clientes.

Creamos un fichero:

nano /etc/openvpn/easy-rsa/keys/Default.txt

Y copiamos lo siguiente:

client
dev tun
proto udp
remote TU-SERVIDOR-AQUI 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20 

Donde dice TU-SERVIDOR-AQUI pondremos la dirección pública de nuestro servidor. Puede ser una IP, o un nombre como mi.servidorVPN.com. Lo más probable es que aquí pongas una dirección de dominio dinámico gratuita como las que ofrece no-ip.com, que expliqué cómo se hace en otro post.

Ahora para generar los ficheros de configuración de cada cliente descargamos este pequeño script maravilloso aquí, y copiamos su contenido en un fichero en /etc/openvpn/easy-rsa/keys/MakeOVPN.sh (he corregido dos cosas menores):

#!/bin/bash 
 
# Default Variable Declarations 
DEFAULT="Default.txt" 
FILEEXT=".ovpn" 
CRT=".crt" 
KEY=".3des.key" 
CA="ca.crt" 
TA="ta.key" 
 
#Ask for a Client name 
echo "Please enter an existing Client Name:"
read NAME 
 
 
#1st Verify that client’s Public Key Exists 
if [ ! -f $NAME$CRT ]; then 
 echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT" 
 exit 
fi 
echo "Client’s cert found: $NAME$CR" 
 
 
#Then, verify that there is a private key for that client 
if [ ! -f $NAME$KEY ]; then 
 echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY" 
 exit 
fi 
echo "Client’s Private Key found: $NAME$KEY"

#Confirm the CA public key exists 
if [ ! -f $CA ]; then 
 echo "[ERROR]: CA Public Key not found: $CA" 
 exit 
fi 
echo "CA public Key found: $CA" 

#Confirm the tls-auth ta key file exists 
if [ ! -f $TA ]; then 
 echo "[ERROR]: tls-auth Key not found: $TA" 
 exit 
fi 
echo "tls-auth Private Key found: $TA" 
 
#Ready to make a new .opvn file - Start by populating with the default file 
cat $DEFAULT > $NAME$FILEEXT 
 
#Now, append the CA Public Cert 
echo "" >> $NAME$FILEEXT 
cat $CA >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT

#Next append the client Public Cert 
echo "" >> $NAME$FILEEXT 
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
#Then, append the client Private Key 
echo "" >> $NAME$FILEEXT 
cat $NAME$KEY >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
#Finally, append the TA Private Key 
echo "" >> $NAME$FILEEXT 
cat $TA >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
echo "Done! $NAME$FILEEXT Successfully Created."

#Script written by Eric Jodoin
#No newline at end of file

 

Damos permiso de ejecución al script:

cd /etc/openvpn/easy-rsa/keys/
chmod 700 MakeOVPN.sh

 

Y ejecutamos el script:

./MakeOVPN.sh

 

Nos pide el nombre del cliente. Introduzco usuario1, trabaja un poco y crea el fichero usuario1.ovpn. Repito con el resto de usuarios.

De esta forma se me generan unos ficheros usuario1.ovpn, usuario2.ovpn, etc. que son los que cargaré a continuación en los clientes.

Basta con cargar el fichero .ovpn, introducir la contraseña, y listo.

Lo he probado de forma exitosa en:

iPhone, con OpenVPN.
Mac, con TunnelBlick
Windows, con OpenVPN Connect

Me consta que OpenVPN Connect también funciona en Android, pero no lo he probado.

Referencias

https://nxfifteen.me.uk/2015/02/07/raspberry-pi-powered-openvpn-server/

IP estática en la Raspberry Pi

Hay varias formas de asignar una IP estática a nuestra Raspberry Pi. Una de ellas es entrar en la configuración del router, averiguar la dirección MAC de la tarjeta de red o wifi de la Raspberry Pi, y asignarle desde ahí una IP estática. Otra forma es configurando la propia Raspberry para que tenga la IP estática, que es como voy a explicar aquí.

Lo primero que tenemos que hacer es conectar nuestra Raspberry Pi por cable a la red. Si el router o servidor tiene un servicio DHCP, habrá asignado automáticamente una dirección IP a nuestra máquina. A continuación, ejecutamos el comando ifconfig y obtenemos información de la red, que vamos a necesitar para configurar adecuadamente la IP estática:

ifconfig

Obtenemos la siguiente pantalla:
Captura

Me fijo en inet addr:192.168.1.45, Bcast:192.168.1.255 y Mask:255.255.255.0

Ejecuto ahora el comando netstat -nr:

netstat -nr

Y obtengo:
Captura

Me fijo en: Gateway 192.168.1.1 y Destination 192.168.1.0

Con estos datos ya podría editar el fichero /etc/network/interfaces e introducir ahí la configuración de la IP estática. ¡Pero desde la versión 20150505 de Raspbian (Jessie) ya no se hace así! Ahora hay un demonio llamado dhcpcd, que cambia un poco cómo sea hace.

Lo más fácil es editar el fichero /etc/dhcpcd.conf y añadir al final:

# IP estática en eth0:
interface eth0
static ip_address=192.168.1.45/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

El /24 tras la dirección IP indica que la netmask es 255.255.255.0, como obtuvimos arriba.

sudo nano /etc/network/interfaces

Ya está. Reiniciamos y listo.

Referencias
ModMyPi
Sizious.com

Display Adafruit 0.56» de 4 dígitos de 7 segmentos I2C en la Raspberry Pi

En este post expliqué cómo hacer funcionar un display de 4 dígitos de 7 segmentos con la Raspberry Pi. Ahora voy a explicar como hacerlo de forma más sencilla, empleando el display de Adafruit, que lleva un controlador incorporado y podemos controlarlo por medio de I2C empleando sólo cuatro cables. Está todo muy bien explicado en la página de Adafruit, así que sigo tal cual los pasos allí indicados.

Lo primero que tenemos que hacer es configurar la Raspberry Pi para I2C.
Luego ejecuto sudo raspi-config y activo I2C, indicando que se cargue en el arranque:
8- Advanced Options
A7 I2C Enable/Disable automatic loading of I2C Kernel module
Would you like the ARM I2C interface to be enabled?
Would you like the I2C kernel module to be loaded by default?

Edito el fichero sudo nano /etc/modules y añado estas dos líneas al final:

i2c-bcm2708 
i2c-dev

Edito el fichero sudo nano /boot/config.txt y añado al final:

dtparam=i2c1=on
dtparam=i2c_arm=on

Reinicio.

Ahora instalo lo siguiente:

sudo apt-get install python-smbus i2c-tools

Ahora conecto el display, de la siguiente forma:

Display VCC —-> RPi 5V (por ejemplo, pin 5)
Display GND —-> RPi GND (por ejemplo, pin6)
Display SDA —-> RPi SDA (pin 3)
Display SCL —-> RPi SCL (pin 5)

Compruebo a ver si funciona, ejecutando:

sudo i2cdetect -y 1

Me sale:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --   

El 70 está indicando que tengo algo conectado ahí, así que por el momento, todo bien.

Ahora me voy a instalar las librerías de Adafruit:

sudo apt-get install git
git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
cd Adafruit-Raspberry-Pi-Python-Code
cd Adafruit_LEDBackpack 

Y pruebo el ejemplo del reloj:

sudo python ex_7segment_clock.py

¡Funciona!

Referencias

Sensores de humedad y temperatura DHT11 y DTH22 en la Raspberry Pi

Existen varios sensores de humedad relativa, entre los cuales el DHT11 y el DHT22 son de los más comunes. El DHT11 es muy barato (alrededor de 2-3€ si lo compras desde China, 8-10€ en España), pero con algo menos de precisión tanto en la humedad como en la temperatura que la que da su hermano mayor, el DHT22, que es algo más caro. Puede verse una tabla comparativa de ambos modelos aquí.

Vamos a empezar conectando el sensor de humedad y temperatura DHT11 a la Raspberry Pi y tomar lecturas. Y después haremos lo mismo con el DHT22.

Sensor de humedad DTH11

Sensor de humedad DHT11

Sensor de humedad DTH22

Sensor de humedad DHT22

Sensores de humedad y temperatura DTH11 y DTH22

Sensores de humedad y temperatura DHT11 y DHT22

Hace falta además una resistencia entre el pin de alimentación y el de datos, aunque se puede comprar el sensor en una mini placa con la resistencia incorporada, como el caso del sensor que tengo yo y que se ve en la imagen de arriba.

En muchas páginas se explica cómo conectar el sensor a la Raspberry Pi (ver más abajo), y todas lo hacen al pin GPIO4 (pin 7). Como en el proyecto que estoy haciendo ahora mismo ya tengo conectado ahí un termómetro DS18B20 (ver este post), voy a conectarlo el GPIO5 (pin 29). Bastará con cambiar el código según a dónde lo conectemos.

Entonces lo conecto así:

  • GND del sensor a un pin GND de la RPi, en mi caso al 20
  • S (datos) al GPIO 5 (pin 29 de la Raspberry Pi)
  • 3V3 a uno de los 3V3 de la Raspberry Pi, en mi caso al 17.

Y ahora, el código para tomar las lecturas. Googleando se pueden encontrar varias formas de hacerlo. El problema en todas ellas es que linux no es un sistema operativo de tiempo real, y como el sensor requiere medidas muy rápidas consecutivas, esto puede suponer un problema. He visto varios ejemplos en Python y en C; en C funciona mejor porque es de más bajo nivel. De todas maneras, en todos los casos advierten de que en ocasiones da error en la lectura y hay que intentarlo varias veces.

Vamos a emplear el código de Adafruit. Es necesario hacer lo siguiente:

git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT

Hay que tener instaladas las siguientes librerías (que tal vez ya tengas instaladas):

sudo apt-get update
sudo apt-get install build-essential python-dev python-openssl

Y ahora compilamos la librería de Adafruit:

sudo python setup.py install

Tras instalarse, probamos a ver si funciona:

cd examples
sudo ./AdafruitDHT.py 11 5

Con esto estoy diciendo que lea los datos del sensor DHT11 (podría ser el DHT22 o el AM2302), conectado al pin GPIO 5.

Y con esto obtenemos la lectura de temperatura y humedad:

Temp=28.0*C  Humidity=29.0%

¡Funciona!

Vamos a probar ahora el sensor DHT22. Lo primero que tengo que hacer es soldarle la resistencia. En algunos sitios he visto que la resistencia debe ser de 4.7KΩ, y en otros, que debe ser de 10KΩ.

thumb_IMG_7031_1024

Soldando la resistencia al sensor DHT22

thumb_IMG_7032_1024

Y lo conecto a la Raspberry Pi de la siguiente forma:

dht22 temperature and humidty sensor circuitry wiring

thumb_IMG_7033_1024

Sensor DHT22 conectado a la Raspberry Pi

Sigo los pasos de instalación de más arriba, y cuando ejecuto:

sudo ./AdafruitDHT.py 22 4

Tras un par de segundos obtengo:

Temp=29.0*C  Humidity=26.4%

¡Funciona!

Los dos sensores funcionando al mismo tiempo, el DHT22 conectado al GPIO4, y el DHT11 al GPIO5:

Sensores DHT11 y DHT22 conectados a la Raspberry Pi

Sensores DHT11 y DHT22 conectados a la Raspberry Pi

 

Referencias

  • http://fpaez.com/sensor-dht11-de-temperatura-y-humedad/
  • http://www.uugear.com/portfolio/dht11-humidity-temperature-sensor-module/
  • https://learn.adafruit.com/dht-humidity-sensing-on-raspberry-pi-with-gdocs-logging/wiring