Archivo de la etiqueta: linux

Reempaquetar el rpm de Portsentry para que loguee en su propio archivo

Desde hace mucho tiempo utilizo como media preventiva de seguridad el paquete Portsentry en los servidores para detectar potenciales accesos maliciosos y bloquearlos directamente en el firewall. El problema es que por defecto Portsentry deja sus logs en el archivo principal del sistema, /var/log/messages, lo que genera tal cantidad de ruido que es imposible encontrar algo útil en el log. El archivo donde loguea Portsentry no es configurable sino que viene predefinido en tiempo de compilación, con lo que deberemos recompilarlo si queremos que sea otro. Podríamos compilar e instalar el fuente directamente, pero no quiero perder las ventajas que ofrece rpm, veamos como hacerlo para Centos5.5 (o RHEL5.5).

Lo primero que debemos hacer es descargar e instalar el rpm con los fuentes desde aquí.

#rpm -ivh portsentry-1.2-1.te.src.rpm

Ahora debemos modificar el archivo donde se configura dónde logueará:

#cd /usr/src/redhat/SOURCES
#tar xvfz portsentry-1.2.tar.gz
#cd portsentry_beta

Editamos el archivo portsentry_config.h cambiando la línea 32 para que quede así:

#define SYSLOG_FACILITY LOG_LOCAL6

Con esto simplemente le decimos que loguee al “facility” local6 en vez de al “daemon” por defecto.

Se guarda el archivo y se empaqueta de nuevo:

#tar cvfz portsentry-1.2.tar.gz portsentry_beta

Ya podemos reconstruir el rpm:

#cd /usr/src/redhat/SPECS
#rpmbuild -ba portsentry.spec

Si todo va bien tendremos el paquete generado:

#cd /usr/src/redhat/RPMS/x86_64

Y ahí estará nuestro portsentry-1.2-1.te.x86_64.rpm preparado para loguear donde queremos que lo haga. Sólo queda instalarlo. Si tu arquitectura es de 32bits lo encontrarás en /usr/src/redhat/RPMS/i386.

Nos queda un detalle, configurar syslog para que guarde donde nos interesa la facility local6. Para eso editamos /etc/syslog.conf. Añadimos al final de todo la línea:

local6.*   /var/log/portsentry.log

y al principio de todo veremos algo parecido a:

*.info;mail.none;authpriv.none;cron.none /var/log/messages

La cambiaremos por:

*.info;mail.none;authpriv.none;cron.none;local6.none    /var/log/messages

Es decir, le decimos que de local6 no loguee nada en /var/log/messages. Solo nos queda reiniciar los demonios:

#/sbin/service syslog restart
#/sbin/service portsentry start

A partir de ahora tendremos nuestro log general bien limpio y la información de se seguridad separada.

SAI Salicru bajo Linux con nut y monitorización en Cacti

Recientemente he tenido que cambiar el SAI que tenía en casa desde hace unos años, un Powermust 1000 que me había dado muy buen resultado, sin embargo las baterías habían llegado a su fin. En App encontré uno con muy buena pinta, con puerto USB para monitorización, indicaban que soportaba Linux y, además, fabricado en España :|, el Salicru SPS 900 One, a un precio insuperable. Me lo llevo :P.

La decepción llegó al instalarlo. La monitorización se hace a través de una aplicación propia, algo que no me convencía ya que estaba acostumbrado a utilizar nut y a tenerlo integrado en Cacti.

Leyendo y probando algunos drivers encontré cómo hacerlo funcionar :). Muy sencillo.

./configure --with-usb --with-snmp --with-cgi --prefix=/usr --with-cgipath=/path/to/cgi-bin/nut/
make
make install

Esto instalará todo lo necesario y dejará los scripts para acceder vía web al estado del SAI en la ruta indicada.

No voy a entrar en detalles de la configuración, sólo indicar que el driver a utilizar es blazer_usb:

cat /etc/ups/ups.conf
[salicru]
driver = blazer_usb
port    = auto
desc    = "Sai Salicru 900"

Con eso iniciamos los demonios upsd y si todo va bien  lo tendremos funcionando. Si vamos a la ruta donde dejamos los scripts web veremos:

Primer paso preparado. Vamos ahora a configurar el monitor de avisos para que sepamos cuando el SAI cambia de estado (se va la luz en casa, vuelve, se queda sin batería, etc.). Esto lo controla el demonio upsmon. Como veis se monitoriza todo bien excepto el nivel de batería, este SAI no informa de ese dato, pero tampoco es algo crítico, los cambios de estado sí que funcionan correctamente, con eso es suficiente para nuestro propósito.

Primero preparamos la configuración.

# cat upsmon.conf
MONITOR salicru@localhost 1 monmaster momi master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"

NOTIFYCMD /bin/avisoups

POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower

NOTIFYMSG ONBATT "El SAI esta funcionando con bateria."
NOTIFYMSG LOWBATT "La bateria del SAI esta muy baja"
NOTIFYMSG SHUTDOWN "El servidor sera apagado inmediatamente"
NOTIFYMSG ONLINE "EL SAI esta funcionando con alimentacion externa"

NOTIFYFLAG ONBATT WALL+EXEC
NOTIFYFLAG LOWBATT WALL+EXEC
NOTIFYFLAG SHUTDOWN WALL+EXEC
NOTIFYFLAG ONLINE WALL+EXEC

RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

Además de definir los mensajes que queremos recibir, le indicamos también que en los cambios de estado llame al script /bin/avisoups.

# cat /bin/avisoups
#!/bin/bash
/bin/echo "$*" | /usr/local/bin/gammu --sendsms TEXT 666666666
echo "$*" | mail -s "Aviso del SAI" [email protected]

Este script se ejecutará en cada cambio de estado que se produzca en el SAI y recibirá como parámetro el texto correspondiente al nuevo estado. En mi caso me envío un email y un SMS a través de Gammu.

Levantamos el demonio upsmon y probamos a enchufar y desenchufar la alimentación externa del SAI. Si todo va bien recibirás un email y/o un sms con el aviso :).

Cuando al SAI se le termine la batería apagará el servidor para evitar que se corte la alimentación de golpe. Si configuras la Bios para que arranque automáticamente cuando reciba alimentación, se reiniciará él solito en cuanto vuelva la luz :).

Integración con Cacti

Para integrar la monitorización en Cacti podemos utilizar estas plantillas ya creadas.

Una vez instalada y creada en el host que hace de monitor debemos configurar el “Data source” correspondiente indicando el SAI que debe monitorizar, en mi caso salicru@localhost.

Si todo ha ido bien, comenzaremos a ver la gráfica de nuestro SAI. Tendremos sólo las líneas Input, Output y Load, la de Batteries, como he indicado, no se recibe en este SAI.

Ya tenemos nuestro SAI baratito bien instalado y configurado. A partir de ahora nos avisará cuando haya cortes de luz, apagará el equipo, se encenderá de nuevo automáticamente y, si lo configuramos todo bien, tendremos hasta un SMS en nuestro móvil. Y todo ello monitorizado a través de Cacti :).

Vsftpd con autentificación a través de servidor Radius y MySQL

Le he cogido gusto a lo del Radius y centralizar todos los temas de autentificación bajo su paraguas 😛 .

Por un lado hemos visto como crear vpn’s y puntos de acceso wireless con Radius y por otro cómo integrar vsftpd con MySQL utilizando usuarios de ftp virtuales. ¿Por qué no combinarlos? ¿Para qué vamos a querer mantener una nueva base de datos para ftp si ya tenemos nuestro Radius preparado para realizar autentificaciones? Está casi todo hecho, sólo nos falta tocar las teclas adecuadas.

Vamos a suponer que tu servidor Radius ya está funcionando y que ya has montado tu sistema vsftpd con usuarios virtuales, en los links anteriores se explica todo. Configuraremos ahora nuestro servidor ftp para que se autentique contra Radius en vez de contra MySQL directamente.

Como vsftpd utiliza PAM para autenticarse, deberemos solamente cambiar el módulo MySQL por el correspondiente a Radius. En aquél momento utilizábamos pam_mysql. ahora haremos lo mismo con pam_radius, así de sencillo.

En mi caso, como sabéis, utilizo CentOS5, y curiosamente no está disponible un rpm con este módulo, así que toca prepararlo a mano, la suerte es que en los fuentes viene el archivo .spec adecuado para crearlo directamente. Si para vuestro sistema tenéis el instalable adecuado podéis saltaros este paso.

Podríamos compilar e instalar directamente el tar, pero prefiero crear un rpm que permita actualizarlo y desinstalarlo a posteriori. Descargamos el código fuente desde aquí, lo desempaquetamos en una ruta temporal y copiamos el propio tar a la ruta adecuada para compilar el rpm:

#cp pam_radius-1.3.17.tar.gz /usr/src/redhat/SOURCES/pam_radius_auth-1.3.17.tar.gz
#tar xvfz pam_radius-1.3.17.tar.gz
#cp pam_radius-1.3.17/pam_radius_auth.spec /usr/src/redhat/SPECS

Ahora debemos hacer un pequeño cambio en este archivo spec. Deberemos editarlo y modificar la línea 2

%define version 1.3.15

actualizando el número de versión correspondiente:

%define version 1.3.17

Y añadimos la línea

BuildRequires: pam pam-devel

Después de la línea 15, de manera que queda

%define name pam_radius_auth
%define version 1.3.17
%define release 0

Name: %{name}
Summary: PAM Module for RADIUS Authentication
Version: %{version}
Release: %{release}
Source: ftp://ftp.freeradius.org/pub/radius/pam_radius_auth-%{version}.tar
URL: http://www.freeradius.org/pam_radius_auth/
Group: System Environment/Libraries
BuildRoot: %{_tmppath}/%{name}-buildroot
License: BSD-like or GNU GPL
Requires: pam
BuildRequires: pam pam-devel

Ya tenemos todo preparado para compilar el módulo

#rpmbuild -ba /usr/src/redhat/SPECS/pam_radius_auth.spec

Si todo va bien tendremos en /usr/src/redhat/RPMS/x86_64 el rpm del paquete preparado para instalar. En mi caso, como es un sistema de 64bits está en la carpeta x86_64, en tu caso puede estar en i386. Sólo nos queda instalarlo.

rpm -ivh /usr/src/redhat/RPMS/pam_radius_auth-1.3.17-0.x86_64.rpm

Vamos ahora a configurar lo poco que hay que configurar 😛 . Indicamos la dirección del servidor Radius y la clave de acceso al mismo:

/etc/raddb/server

127.0.0.1       claveSecretaRadius             1

Cambiamos la configuración PAM de vsftpd para que en vez autenticarse con MySQL utilice Radius:

/etc/pam.d/vsftpd

auth required /lib/security/pam_radius_auth.so debug
account required /lib/security/pam_radius_auth.so debug

Eso es todo. Nuestro servidor FTP se autenticará contra el servidor Radius. Hemos añadido la opción de depuración (debug) para comprobar el funcionamiento, cuando estemos seguros de que todo funciona bien podemos eliminarla.

Si tienes algún problema, para verificar qué hace el módulo pam_radius debemos comprobar el log estándar de debug. Por defecto no viene activado en el demonio syslog, así que lo añadimos:

/etc/syslog.conf

*.debug       /var/log/debug.log

Intentamos acceder al servidor FTP y comprobamos qué está haciendo el módulo de autentificación en este log:

cat /var/log/debug.log

Sep 28 17:11:09 osiris vsftpd: pam_radius_auth: Got user name XXX
Sep 28 17:11:09 osiris vsftpd: pam_radius_auth: Sending RADIUS request code 1
Sep 28 17:11:09 osiris vsftpd: pam_radius_auth: DEBUG: getservbyname(radius, udp) returned 1214042784.
Sep 28 17:11:09 osiris vsftpd: pam_radius_auth: Got RADIUS response code 2
Sep 28 17:11:09 osiris vsftpd: pam_radius_auth: authentication succeeded

Si hubiese algún problema deberíamos verlo ahí, pero si ya tenías Radius y vsftpd funcionando, todo debería ir bien.

Hasta aquí hemos llegado, hemos integrado un nuevo servicio de nuestra red en el mismo sistema de autentificación. Cualquier demonio que utilice PAM para autenticarse se debería configurar del mismo modo. Ssh es el ejemplo más claro, se haría prácticamente igual.

Punto de acceso inalámbrico con autentificación a través de servidor Radius y MySQL

Si hace unos meses os mostraba cómo crear conexiones VPN entre máquinas Linux y Windows con autentificación a través de servidor Radius y MySQL hoy veremos cómo aprovechar la misma estructura para autentificar usuarios que se conecten a nuestra red wifi de manera que tengamos todo el entorno de acceso a nuestra red integrado. En capítulos posteriores puede que veamos cómo añadir más servicios.

Ante todo aviso que no soy ningún experto en la materia y puede que diga cosas que no son correctas 😛 , por favor, no dudéis en corregirme.

La parte más importante del sistema la tenemos ya preparada, si necesitas montar todo el servidor Radius puedes leer el artículo anterior donde se explica bien el procedimiento. En esta ocasión nos centraremos en hacer que el servidor Radius que ya teníamos autentifique a los usuarios que se conecten a nuestro punto de acceso inalámbrico.

En un escenario normal es el punto de acceso el que se encarga de autentificar al cliente que intenta conectarse a través de las conocidas contraseñas (técnicamente shared-keys) con el inconveniente de que todos los usuarios deben utilizar la misma y si hay que cambiarla hay que comunicar a todos ellos cual es la nueva.

Hay dos conceptos dentro de todo este sistema que van siempre juntos pero son distintos:

  1. La encriptación de la comunicación entre el cliente y el punto de acceso, las conocidas WEP, WAP y WAP2.
  2. La shared-key de acceso al router.

Estos dos elementos son completamente independientes. No me voy a meter técnicamente en los distintos tipos de encriptación ya que no son el objetivo del artículo y hay toda la documentación que quieras al respecto. Para nuestro ejemplo vamos utilizar WPA2 con cifrado AES. Recuerda que estos parámetros sólo importan al punto de acceso y al cliente que se conecta, se utiliza para asegurar el canal inalámbrico, el servidor Radius es completamente ajeno a estos mecanismos.

En nuestro escenario el procedimiento descrito anteriormente quedaría como muestra este gráfico.

Dibujo1

Es decir, para que un cliente se conecte a nuestro punto de acceso necesitará las credenciales adecuadas. Una vez el AP las recibe, consulta al servidor Radius si son correctas y debe dejarle pasar, en cuyo caso el cliente ya puede acceder a nuestra red. Cómo os habréis dado cuenta, entre el AP y Radius no he nombrado en ningún momento WAP2 o AES, éstos se utilizan sólamente en lo que en el gráfico superior es el rayo amarillo, el medio inalámbrico. En resumen, la diferencia entre la configuración habitual con shared-key estática y ésta es que permitimos que cada usuario tenga su login independiente, pudiendo cancelar su acceso en cualquier momento, algo que puede ser muy útil en ciertos ambientes, sobre todo corporativos.

Configurando el servidor Radius

Nuestro servidor Radius ya estaba configurado, sólo deberemos hacer un par de modificaciones. Primero añadimos permiso para que se conecte el punto de acceso y pueda autentificar a los clientes, para ello agregamos lo siguiente al archivo /etc/raddb/clients.conf:

client 192.168.100.100 {
	secret = clavesecreta
	shortname = osusnet
}

Donde la ip es la del APsecret es la contraseña que utilizará el AP para conectarse a Radius y shortname un identificador interno. A continuación editamos el archivo /etc/raddb/eap.conf dejando las siguientes secciones de este modo:

default_eap_type = peap

tls {
        private_key_password = whatever
        private_key_file = ${raddbdir}/certs/cert-srv.pem
        certificate_file = ${raddbdir}/certs/cert-srv.pem
        CA_file = ${raddbdir}/certs/demoCA/cacert.pem
        dh_file = ${raddbdir}/certs/dh
        random_file = ${raddbdir}/certs/random
}

peap {
        default_eap_type = mschapv2
}

Eap es el método de autenticación que se utilizará, en el caso que tratamos será PEAP (conocido también como EAP-MSCHAPv2) y necesita además TLS, por eso debemos añadir los dos en la configuración de Radius. En mi caso, la instalación de FreeRadius crea los certificados necesarios así que no entraré más en detalle sobre este tema, supondremos que existen y funcionan bien. Ya solo queda reiniciar el demonio Radius para que los cambios comiencen a estar visibles.

Configurando el punto de acceso

En este punto hemos terminado la configuración en nuestro servidor Linux. Configuraremos ahora el router, en mi caso un SMC. Tendremos que utilizar un cable ethernet para acceder al router ya que no podremos entrar por wifi hasta que lo tengamos bien configurado. La configuración en tu router será muy parecida a ésta. En las opciones “Wireless” le indicamos que la seguridad será WPA:

router4

En la configuración WPA especificamos los parámetros que hemos acordado, WPA2 y AES. Además le indicamos que no utilizaremos pre-shared key para autenticación sino que se hará a través del protocolo 802.1x. Los demás parámetros no nos importan.

router1Finalmente configuramos las opciones de autenticación 802.1x habilitándola e indicando la dirección IP de nuestro servidor Linux con Radius.

router2Ya está el router configurado. Sólo nos queda hacer lo propio con nuestro cliente inalámbrico. Como hemos escogido WAP2 supondremos que la tarjeta wireless del portátil la soporta, si no ¿por qué la has escogido? 😛 .

Configurando los clientes inalámbricos

Al buscar las redes inalámbricas disponibles en el portátil veremos la del router que hemos configurado. Por defecto no podremos acceder a ella, debemos indicarle cómo debe autenticarse, para ello vamos a “Configuración avanzada” y en la lista de redes seleccionamos la que nos ocupa y vamos a propiedades.

En la venta que se abre seleccionamos, en la pestaña “Asociación“,  los métodos de autenticación y cifrado que hemos definido:

wifi3En la pestaña “Autenticación” seleccionamos “PEAP” como tipo de EAP y vamos a “Propiedades“:

wifi1En la ventana que se abre eliminamos la selección de “Utilizar certificado cliente” y en el método de autenticación “EAP-MSCHATP v2” vamos a “Configurar”, eliminando en la ventana que se abre la opción que viene señalada por defecto.

wifi0Aceptamos todos los cambios hacia atrás y guardamos la configuración. A los pocos segundos veremos este aviso:

wifi4Parece que funciona 😛 . Pinchamos en el aviso y nos salta la venta que buscamos:

wifi5Introducimos nuestro usuario y clave de Radius y padentro!

Eso es todo, hemos conseguido el objetivo del artículo, utilizar la misma infraestructura de autentificación para el entorno inalámbrico que la que teníamos para el acceso remoto por VPN.

Cómo realizar backups centralizados de sistemas Windows desde Linux

Hoy voy a contar cómo tengo montado en mi casa el sistema de copias de seguridad para los equipos de escritorio basados en Windows, concretamente para mi portátil.

Lo primero, obviamente, es compartir las carpetas o unidades de las que vas a querer hacer copia, en mi caso la unidad d: completa y mi escritorio, tengo todos los documentos y archivos centralizados en esas dos rutas. Lógicamente no debes hacerlas públicas, sino cualquiera que tenga acceso por red a tu equipo podrá entrar a todo, hay que compartirlas y punto, el que quiera entrar que se autentifique como hará nuestro sistema.

Las copias están centralizadas desde el servidor Linux del que ya os he hablado otras veces, basado en CentOS5. En este equipo tengo un disco duro USB con dos particiones, una ext3 para copias del propio servidor y otra NTFS para las de los equipos Windows. Para evitar pérdidas por cortes, el disco se monta y desmonta automáticamente cuando se necesita a través del sistema autofs, de este modo cada vez que se acceda a la ruta predefinida se montará el disco y pasado un tiempo de inactividad se desmonta. Veamos primero cómo preparar este sistema.

Lo primero que necesitaremos son los drivers para acceder a partificiones NTFS desde Linux, yo utilizo ntfs-3g. En mi caso es tan sencillo como hacer:

yum instal ntfs-3g

Mi equipo tiene varias rutas de automontaje, vamos a ver las que nos interesa que son las del disco usb. Primero configuramos los dos archivos necesarios:

/etc/auto.master

/mnt/backup /etc/auto.backup

/etc/auto.backup

backupusb       -fstype=auto    :/dev/sdb1
backupntfs      -fstype=ntfs-3g,rw,fmask=666,dmask=777,gid=users,nls=iso8859-1,locale=es_ES     :/dev/sdb2

En el primero indicamos que nuestras unidades se van a montar en /mnt/backup y que lea la configuración del segundo archivo mientras que en éste especificamos qué montar y cómo hacerlo.

Como veis he definido dos puntos de montaje correspondientes a las dos particiones. El primer parámetro indica la “carpeta” dónde los montará dentro de la definida en master, en este caso /mnt/backup/backupusb y /mnt/backup/backupntfs. La importante en nuestro caso es la segunda donde indicamos el tipo de archivos y el lenguaje en el que están los nombres, imprescindible para que se lean bien los acentos y eñes del castellano.

Ya sólo debemos iniciar el demonio autofs y probar las rutas.

service autofs status

Si ahora intentamos acceder a /mnt/backup/backupntfs deberíamos poder entrar a la unidad del disco correspondiente y ver su contenido. Ya tenemos la mitad del trabajo resuelto.

Vayamos ahora con el backup propiamente dicho. Creamos el punto de montaje de la unidad que vamos a copiar, en este caso /mnt/portatil. Ahí montaremos temporalmente la unidad remota para hacer las copias. Creamos además en la partición del disco USB el directorio donde meteremos el backup, en mi caso /portatil. Ya estamos preparados para copiar. Ah no, falta un detalle. ¿Cómo lo hacemos si no queremos copiar los tropecientos Gb cada vez que se haga la copia?. El socorrido rsync viene en nuestra ayuda. Rsync permite sincronizar datos entre dos rutas sin copiarlo todo, simplemente elimina lo que ya no existe  y copia lo nuevo y lo que ha cambiado sin tocar lo que no ha variado, con lo que en un ambiente normal será poco lo que hay que copiar.

Este sería mi script.

#!/bin/sh
PORTATIL=192.168.0.79
fecha=`date +%Y-%m-%d`

#MONTAMOS EL USB
if test -d "/mnt/backup/backupntfs"
	then
		echo "Dispositivo USB correcto"
	else
		echo "Error en dispositivo de backups NTFS $fecha" | mail -s "Error montando dispositivo USB backup NTFS" [email protected]
		exit;
	fi
echo "MONTAMOS EL PORTATIL"
mount -t cifs -o iocharset=utf8,username=usuario,password=clave  //$PORTATIL/D /mnt/portatil
if [ $? -ne 0 ]
	then
		echo "ERROR MONTANDO EL PORTATIL/D"
	else
		#copiamos
		echo "COPIAMOS"
		/usr/bin/rsync ----alv ----modify-window=1 ----delete ----recursive ----exclude "RECYCLER" ----exclude="$RECYCLE.BIN" ----exclude "System Volume Information"  /mnt/portatil/ /mnt/backup/backupntfs/portatil/
fi
echo "DESMONTAMOS"
umount //$PORTATIL/D

Lo primero que hago es comprobar que el disco USB está disponible, básico para poder hacer el backup :P. A continuación montamos la unidad remota en el directorio que creamos antes, /mnt/portatil. Esto lo hacemos con:

mount -t cifs -o iocharset=utf8,username=usuario,password=clave  //$PORTATIL/D /mnt/portatil

Los parámetros importantes son los del medio, le indicamos que el juego de caracteres sea UTF-8 y los datos con los que autentificarse en el portátil.  En este punto podríamos hacer un ls -l /mnt/portatil y deberíamos ver los archivos de la unidad D: del portátil.

A continuación ejecutamos la sincronización. La primera vez que se lance tardará bastante ya que ahí sí que debe copiar todos los archivos de la unidad origen en el portátil a la del backup. Cuando termine de sincronizar el script desmontará la unidad del portátil y el autofs hará lo propio automáticamente con la del USB. En el rsync añadimos los parámetros adecuados para que excluya algunas carpetas predefinidas de Windows, como la papelera, y muy importante, el parámetro –modify-window=1 para salvar la diferencia que tiene Windows con la fecha de modificación de los archivos, Windows utiliza sólo valores pares, lo que generaría la copia de muchos más archivos de los que realmente han sido modificados.

Vayamos un poco más lejos. Quiero poder recuperar algún archivo borrado, no sea que me equivoque y me cargue algo. Con rsync todo es muy sencillo, le indicamos que los archivos que vaya a eliminar los mueva a otra ruta. Para ello añadimos los parámetros :

----backup ----backup-dir=/mnt/backup/backupntfs/incremental/portatil/$fecha

Con esto conseguimos que en la carpeta /incremental/portatil de la partición NTFS del disco USB se mantenga un histórico por fecha de los archivos eliminados. El comando entero quedaría del siguiente modo:

/usr/bin/rsync ----alv ----modify-window=1 ----delete ----recursive ----backup ----backup-dir=/mnt/backup/backupntfs/incremental/portatil/$fecha ----exclude "RECYCLER" ----exclude="$RECYCLE.BIN" ----exclude "System Volume Information"  /mnt/portatil/ /mnt/backup/backupntfs/portatil/

De este modo tenemos en el disco todo, por un lado la instantánea de la unidad al momento de hacerla y en otro un histórico diario por día, pudiendo recuperar todo lo que queramos.

Sólo nos queda añadir el script al crontab para que se ejecute cuando creamos oportuna, una vez por semana por ejemplo. Yo crearía también un script que limpie las copias de los archivos eliminados cada cierto tiempo, cada mes o cada dos meses, para que no crezca en exceso el espacio ocupada por la “basura“.

Siguiendo este mismo ejemplo podemos ahora hacer copias de las copias para tener varias copias distribuidas no sea que se nos incendie el piso y lo perdamos absolutamente todo 😛 .

Cómo desmontar una unidad ocupada bajo Linux

Esto es algo que siempre me pasa y nunca me acuerdo de cómo solucionarlo. Hoy he recibido una alerta de uno de mis servidores, MySQL se había parado y no podía reiniciarse. Al entrar a la máquina para hacerlo manualmente, en efecto, me decía que no podía, que los archivos eran de sólo lectura 😐 . Después de hacer alguna comprobación más me doy cuenta de que la unidad entera se había quedado en algún estado extraño de sólo lectura a pesar de que el mount indicaba lo contrario.

[osus@servidor ~]# mount
/dev/hdb1 on /mnt/unidad type ext3 (rw)

Decido entonces desmontar la unidad y volver a montarla, pero…

[osus@servidor ~]# umount /mnt/unidad
umount: /mnt/unidad: device is busy

Y aquí viene el problema. Había parado, en teoría, todos los servicios que utilizaban esa unidad, pero aún así me daba este error. Podría haber forzado el umount con:

umount -l /dev/hdX

Pero prefiero saber qué es lo que está ocupando la unidad antes de forzarlo, cuestión de precaución sólo. Necesitamos saber, entonces, qué procesos están haciendo uso de la unidad que queremos desmontar, y esto es lo importante de este artículo.

[osus@servidor ~]# fuser -vm /dev/hdb1

                     USER        PID ACCESS COMMAND
/dev/hdb1:           named       456 ..c.. named
                     mysql       587 F.c.. mysqld
                     apache     1113 F.... httpd
                     root       1925 ..c.. screen
                     root       1926 ..c.. bash
                     apache     8009 F.... httpd
                     apache     9267 F.... httpd

Con este sencillo comando de fuser ya sabemos quién accede a la unidad en cuestión. En mi caso era un proceso bash de un screen que estaba abierto y un rsync. Los paré y ya pude desmontar la unidad correctamente. Al volver a montarla todo comenzó a funcionar correctamente.

¿La causa? Ni idea, no había nada raro en los logs, pero me da que el rsync había hecho algo extraño…

Televigilancia con Motion y un servidor Linux

Hoy vamos con algo curioso 😛 . A veces pienso que su utilidad no está muy clara, me refiero a utilidad real 😉 , no sólo como juguete, pero seguro que cuando lo leáis se la encontráis.

Hoy veremos cómo montar un sistema de televigilancia con un servidor Linux y una webcam USB normal y corriente, de las baratitas.

Asumiré que ya tienes tu webcam funcionando bajo Linux, no entraré en detalles puesto que no es el objeto de este artículo y cada webcam tendrá una configuración distinta. Por suerte, hoy en día la mayoría de webcams USB funcionan perfectamente bajo Linux.

La base de este artículo cae sobre el software encargado de monitorizar la webcam en busca de actividad: motion. Lo utilicé por primera vez allá por 2001, hace ya tiempo, y desde luego puedo confirmar es una solución completa y robusta.

Motion funciona como la mayoría de programas de detección de movimiento basados en cámaras, no hay mucho misterio, simplemente comprueba la diferencia de píxeles entre fotogramas consecutivos capturados y si esta diferencia es superior a un umbral predefinido asume que hay movimiento. Este umbral debe ser bien estudiado para que un simple movimiento de cortina o el reflejo del sol que entra por la ventana no salten como un falso positivo. Una de las características que lo diferencian de otros programas similares es que permite monitorizar tantas cámaras como el ancho de banda de tus puertos USB pueda asumir, aunque no tienen porqué ser USB, recuerda que Linux trata igual cualquier flujo de vídeo, venga de donde venga, /dev/videoX. Veremos todo esto más adelante.

Instalación

En mi caso, como ya sabéis los que me seguís, utilizo un servidor con Centos5. No hay un rpm para esta distribución (o al menos yo no lo encontré en su día) y me gusta normalmente instalar las cosas con rpm por sencillez, así que vamos a construirlo desde el fuente, así que, descárgalo y descomprímelo.

Dentro de esta carpeta que has obtenido encontrarás un archivo motion.spec.in, edítalo y cambia las primeras líneas:

Name:           @PACKAGE_NAME@
Version:        @PACKAGE_VERSION@

por

Name:           motion
Version:        3.2.11

Guárdalo. Ahora copia el archivo original que descargaste antes, motion-3.2.11.tar.gz a /usr/src/redhat/SOURCES/. Ya está todo, ahora construímos el RPM.

[osus@servidor motion-3.2.11]# rpmbuild -bb motion.spec.in

Si todo va bien, cuando termine tendremos el RPM en /usr/src/redhat/RPMS/x86_64/motion-3.2.11-1.x86_64.rpm. Si usas una arquitectura de 32bits lo tendrás en una carpeta distinta a x86_64, mira en /usr/src/redhat/RPMS. Instala el rpm generado, rpm -ivh motion-3.2.11-1.x86_64.rpm. Primer paso completado.

Configuración

Motion no tiene interfaz gráfica propiamente dicha aunque sí una sencilla aplicación web para modificar los parámetros. Todas sus opciones se gestionan a través del archivo de configuración /etc/motion/motion.conf. Por defecto, viene bastante bien configurado. El parámetro más importante es:

videodevice=/dev/video1

Ahí debes indicar cuál es el dispositivo de tu cámara.

Con el resto de configuraciones puedes jugar desde la interfaz web, aquí dejo algunas importantes.

Primera opción chula. Activar una interfaz web para ver las capturas directamente desde la cámara, así tienes un sitio desde donde espiar. Obviamente debes tener acceso al puerto desde donde lo quieras ver, es decir, abrirlo en el router.

webcam_port 8001

Conéctate a http://ipdelservidor:8001/. Sorpresa!. Con firefox lo verás como si fuese un vídeo, aunque en realidad es un flujo de imágenes JPG. A Explorer no le gusta mucho ese formato y se suele utilizar un applet para convertirlo.

La siguiente es interesante ya que en vez de mostrar las imágenes muestra los píxeles distintos entre ellas, útil para preparar el sistema y comprobar cómo funciona motion.

setup_mode off

Ahora activamos la gestión web para configurar el sistema y hacer más “cositas“.

control_port 8000
control_localhost off
control_authentication tuusuario:tucontraseña

Pasa lo mismo con el puerto, no olvides abrirlo.

Conéctate a http://ipdelservidor:8001/ y juega con las opciones. Todo lo que toques desde ahí se aplicará en tiempo real sin necesidad de reiniciar motion. Muy útil para la puesta a punto. Recuerda sin embargo que debes guardar los cambios para que se mantengan la próxima vez que reinicies el servidor.

motion

La siguiente nos permite decidir cuántos fotogramas deben cambiar para disparar la alerta. Por defecto viene a 1 y esto nos provocará bastantes avisos falsos, si entra alguien en casa se cambiarán muchos fotogramas 😛 .

minimum_motion_frames 1

Con ésta otra podemos generar automáticamente un frame cada X segundos. Por defecto está desactivado (0), si le das un valor se creará la imagen por cada intervalo, podremos utilizarla para poner una webcam en web “semi-real” 😛 . Cuando estaba en la universidad teníamos una cámara enfocando al comedor que actualizaba una imagen periódicamente y nos servía para controlar la cola del comedor y bajar cuando había poca 😛 .

snapshot_interval X

Motion tiene muchísimas opciones más como para comentarlas todas, en la documentación de la web oficial puedes enterarte de para qué sirven y qué hacen todas ellas.

Comprobando el funcionamiento

Ya tenemos todo listo, hemos configurado todo bien, ¿funcionará?.

Veamos qué ocurre cuando lanzamos el servicio (service motion start). Me muevo un rato delante de la cámara y ocurre esto:

snaps

Sí, motion comienza a grabar imágenes de lo que está ocurriendo. Pero eso no es todo. Cada vez que se detecta movimiento motion graba un vídeo del momento, sonríe ladrón, te están grabando 🙂 :

Enviando alertas

Hay una serie de eventos que puedes utilizar para hacer otras acciones no definidas, como enviarte alertas por email, SMS, etc…

on_event_start value
on_event_end value
on_picture_save value
on_motion_detected value
on_movie_start value
on_movie_end value

Simplemente debes añadir el comando completo que quieres utilizar. Con %f accedes al nombre del fichero generado en los eventos de imagen y vídeo. Por ejemplo, voy a utilizarla para convertir el vídeo generado a 3gp y enviarlo por email para verlo en el móvil.

on_movie_end ffmpeg -i %f -s qcif /ruta/publica/web/video.3gp && echo "puedes verlo aqui http://tuservidor.com/video.3gp" | mail -s "Alertas de movimiento" [email protected]

Incríble pero cierto 😛 . Ahora tendría una tarea que recoge los emails de ese buzón y me los envía por SMS. También podríamos haber enviado el SMS directamente como vimos aquí.

¿Puedo usar más cámaras?

Para lanzar una segunda cámara (o más) añadiríamos al final del archivo de configuración tantas líneas como cámaras quieres poner:

thread /etc/motion/cam2.conf

Donde cam2.conf es un archivo de configuracion como motion.conf donde cambias, además de todos los parámetros que necesites, el videodevice. Recuerda que los puertos de gestión y visualización deben ser diferentes en cada cámara.

Quiero ver mi cámara desde fuera sin abrir ningún puerto más

¡Qué complicado me lo estás poniendo!

Apache viene al rescate. Configuramos los puertos del streaming jpeg y/o la interfaz de administración para que se vean a través de Apache:

ProxyPass /camara.cgi http://127.0.0.1:8001
ProxyPassReverse /camara.cgi http://127.0.0.1:8001
ProxyPass /admincamara.cgi http://127.0.0.1:8000
ProxyPassReverse /admincamara.cgi http://127.0.0.1:8000

Ahora sí, todo perfecto. Aunque pensándolo bien, como comience a recibir alertas me voy a cagar de miedo :S , me estrán robando 😛 .

Usuarios de ftp virtuales con vsftpd y MySQL

Un problema que se me ha presentado más de una vez es dar acceso FTP a determinadas carpetas a usuarios que necesitan actualizar archivos en ellas. Por regla general habría que crear un usuario del sistema que tuviese su “home” en esa carpeta o un enlace simbólico desde otra, pero nunca me ha gustado la idea de crear usuarios a diestro y siniestro, aunque sean sin privilegios. Buscando un día, empecé a encontrar información sobre cómo crear usuarios “virtuales” en vsftpd y me gustó mucho la idea, combinando esto con la gestión de usuarios en MySQL podría tener un sistema bastante sencillo de dar acceso FTP a unos cuantos usuarios sin incrementar los del sistema y, por tanto, sin abrir agujeros de seguridad.

Lo primero será instalar los módulos necesarios, asumiendo que ya tienes el servidor MySQL funcionando. Nos hará falta el paquete vsftpd y el pam_mysql que permitirá hacer autentificaciones contra una base de datos de este tipo.

yum install pam_mysql vsftpd

Ahora configuramos el archivo /etc/pam.d/vsftpd para que quede así;

[osus@servidor vsftpd]# cat /etc/pam.d/vsftpd
auth required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0
account required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0
session required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0

Esto indica a vsftpd que debe autenticarse contra “basedatos” en “localhost” con el usuario “vsftpd” y la clave “clave” y que debe buscar en la tabla “usuarios” con las columnas  “usuario” y “pass“. Qué evidente es todo 😛 .

El último parámetro, “crypt“, indica el modo en que se guardarán las claves:

  • 0 para claves en texto plano sin encriptar
  • 1 para claves encriptadas con la función crypt()
  • 2 para claves generadas con la función PASSWORD() de MySQL
  • 3 para claves en md5

Escoge el sistema que prefieras. Dejaremos ahora el archivo de configuración principal de este modo:

[osus@servidor vsftpd]# cat /etc/vsftpd/vsftpd.conf
ftpd_banner= "Servidor FTP"
anonymous_enable=NO
chroot_local_user=YES
guest_enable=YES
guest_username=ftpoculto
hide_ids=YES
listen=yes
listen_address=192.168.3.254
listen_port=21
local_enable=YES
max_clients=100
max_per_ip=5
pam_service_name=vsftpd
use_localtime=YES
user_config_dir=/etc/vsftpd/usuarios
userlist_enable=YES
userlist_file=/etc/vsftpd/denied_users
virtual_use_local_privs=YES
xferlog_enable=YES
async_abor_enable=YES
connect_from_port_20=YES
dirlist_enable=NO
download_enable=NO
local_umask=000

Con esto le estamos diciendo que no permitiremos el acceso anónimo y que el usuario real que se utilizará será “ftpoculto“, los usuarios virtuales se comportarán como este usuario. Le indicamos, además, que busque los usuarios virtuales en /etc/vsftpd/usuarios y que no deje entrar a ningún usuario real, sólo a los virtuales. Para esto último haremos lo siguiente:

cat /etc/passwd | cut -d ":" -f 1 | sort > /etc/vsftpd/denied_users

Así añadimos a la lista de usuarios denegados a todos los usuarios del sistema, no hay que ponerlos a mano uno a uno 🙂 .

Ahora debemos configurar el acceso para cada usuario dentro de la carpeta “usuarios“. El nombre del archivo debe ser el mismo que el del usuario que se ha añadido a la base de datos, el que utilizará el cliente para conectarse. Yo, por ejemplo, suelo utilizar como nombres el dominio del cliente, así se quién es quién.

[osus@servidor usuarios]# cat tudominio.com
dirlist_enable=YES
download_enable=YES
local_root=/var/www/tudominio.com/
write_enable=YES
anon_world_readable_only=NO

Tendremos que configurar el directorio de este usuario para que pueda escribir en él. Para conseguirlo recordamos que vsftpd utilizaría el usuario real “ftpoculto“. Debemos, por tanto, dar permisos sobre los directorios de los usuarios virtuales a ese usuario:

chown -R ftpoculto.users /var/www/tudominio.com

Con esto, el usuario “tudominio.com” podrá moverse en /var/www/tudominio.com a sus anchas 🙂 .

La verdad es que me ha funcionado muy bien siempre. Si se combina con un sistema de acceso VPN sencillo, de manera que el puerto FTP no tenga que estar abierto púclibamente, queda todo muy robusto y seguro además de que es muy sencillo añadir nuevos usuarios, incluso lo puedes automatizar con un script ya que solamente hay que añadir un registro en la base de datos y crear el archivo de configuración en /etc/vsftpd/usuarios.

Es una buena idea en pequeños entornos ISP no dedicados o especializados, entornos donde los usuarios no van a necesitar habitualmente acceso FTP (cms, blogs, webs corporativas…).

Hay muchos más parámetros en vsftpd, desde limitar el ancho de banda por usuario hasta utilizar SSL en las conexiones, sólo hay que leer un poco la documentación 🙂 .

Reiniciar el router automáticamente

Tengo un problema con mi router ADSL de casa. Cada 3 o 4 días se cuelga por alguna extraña razón (¿será saturación? 😛 ) y hay que resetearlo para que vuelva a funcionar. Cansado de estos cuelgues decidí solucionarlo con un pequeño script que mi máquina Linux ejecuta cada dos días de madrugada, así no me entero. Ya no me he vuelto a dar cuenta de los cuelges.
Lo primero que hay que hacer es habilitar el acceso telnet al router desde dentro de la red local, nunca desde el exterior 😛 .

expect es una herramienta que permite automatizar aplicaciones interactivas tipo telnet o ftp, donde tienes que introducir tu usuario y tu clave y alguien tiene que estar ahí para teclearlas. Expect lo que hace es, como su propio nombre indica, esperar determinadas cadenas de texto e introducir los datos que se hayan programado. Pongamos un ejemplo práctico. Cuando haces un telnet tienes la siguiente secuencia de eventos:

[osus@servidor ~]# telnet 192.168.0.100
Trying 192.168.0.100...
Connected to 192.168.0.100.
Escape character is '^]'.

Username:

Password:

Es decir, cuando haces un telnet “esperas” la cadena “Username:” para introducir tu usuario y después introduces tu clave cuando recibes “Password:“.

Esto es exactamente lo que automatiza expect. Veamos cómo con un script práctico.

[osus@servidor scripts]# cat router.sh
#!/usr/bin/expect -f
set force_conservative 1 ;
if {$force_conservative} {
        set send_slow {1 .010}
        proc send {ignore arg} {
                sleep .2
                exp_send -s -- $arg
        }
}
spawn telnet 192.168.0.100
expect "Username :*"
send -- "USUARIOr"
expect "Password :*"
send -- "CLAVEr"
expect "ROOT :>*"
send -- "rebootr"
expect "figuration(y/n) ? :*"
send -- "yr"
expect -gl "\[*]$*"
exit

Creo que habla por sí sólo el script. Esperamos a recibir cada cadena de texto para enviarle nuestros datos. Una vez estamos logueados esperamos la cadena inicial que nos devuelve el router, en mim caso “ROOT :>“. Ahí es cuando le pedimos el reboot y lo confirmamos. Ya está, el router se reinicia sólo. Obviamente todas las cadenas que esperas recibir deben coincidir con las de tu router, las aquí indico son las del mío.

Creando enlaces punto a punto entre servidores Linux con OpenVPN

Si hace unas semanas veíamos como crear un servidor VPN, hoy veremos como crear un túnel seguro dedicado entre dos servidores que esté permanentemente levantado y que se cree automáticamente al reiniciar alguna de las máquinas. ¿La utilidad? Tener una conexión directa con la máquina de backups, con un servidor de bases de datos, con la oficina, con otro centro de datos… seguro que se te ocurren más 😛 .

Como comentábamos entonces, PPTP no es el paradigma de la seguridad, pero la ventaja que tiene es la facilidad con que un cliente se conecta contra el servidor sin apenas conociemientos.  El ejemplo de hoy no nos servirá para crear túneles bajo demanda, pero veremos lo sencillo que puede ser crear un túnel dedicado. Siempre que se habla de VPN se termina en IPSec, pero ¿quién no se vuelto loco con la instalación de un túnel de este tipo? ¿Es realmente necesario utilizar IPSec para cualquier túnel? Yo creo que no, cada cosa para lo que está. Igual que con el primer artículo creábamos un sistema de VPN sencillo para el usuario, ahora que simplemente queremos conectar máquinas entre sí recurrimos a otro software que lo hace sin quebraderos de cabeza.

Necesitaremos, obviamente, máquinas Linux (aunque también se pueden emplear Windows) y el software que utilizaremos en este artículo: OpenVPN.

Tal y como reza en la home de OpenVPN:

Starting with the fundamental premise that complexity is the enemy of security, OpenVPN offers a cost-effective, lightweight alternative to other VPN technologies that is well-targeted for the SME and enterprise markets.

Y además lo cumple, ligero y sencillo.

Configuración

Lo primero será instalar el software. En mi CentOS no tendremos más que hacer

yum install openvpn lzo

Lzo nos proporcionará la compresión a través del túnel.

Aunque no lo parezca, ya queda poco 🙂 . Ahora debemos generar la clave SSL  que asegurará las comunicaciones a través del tunel. Muy sencillo, sólo necesitaremos un comando:

openvpn --genkey --secret clave.key

Esta clave debemos copiarla a /etc/openvpn de los dos servidores que se quieren conectar. Para copiarla al segundo lo puedes hacer con scp:

scp clave.key tuservidor.com:/etc/openvpn

Finalmente sólo nos queda el archivo de configuración. En el primer servidor creo un archivo con el nombre del segundo para identificar fácilmente qué conexión es puesto que podemos haber definido varios túneles.

[osus@servidor1 openvpn]# cat servidor2.conf
port 1194
proto udp
remote servidor2.com 1194
dev tun
ifconfig 192.168.2.2 192.168.2.1
secret clave.key
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
log /var/log/vpn.log

Como se puede ver, la configuración es muy sencilla, no necesita apenas explicación. En servidor2.com pones la IP del servidor al que se va a conectar, defines el puerto, las IPs privadas del servidor y del cliente y voilà, ya tienes la primera máquina preparada.

Vamos ahora con el segundo servidor.

[osus@servidor2 openvpn]# cat servidor1.conf
port 1194
proto udp
remote servidor1.com
dev tun
ifconfig 192.168.2.1 192.168.2.2
secret clave.key
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
log /var/log/vpn.log

Casi lo mismo que en el caso del servidor, sólo cambiamos la IP del servidor remoto y el orden de las IP’s privadas.

¡Ya está!

Sólo nos queda probarlo. Lanzamos el servicio en las dos máquinas y veremos si todo ha ido bien:

[osus@servidor1 ~]# service openvpn start
Starting openvpn:                                          [  OK  ]

[osus@servidor1 ~]# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:192.168.2.1  P-t-P:192.168.2.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP 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:100
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Parece que sí. Para verificar que, en efecto nos hemos conectado satisfactoriamente revisaremos el log.

[osus@servidor1 ~]# tail -f /var/log/vpn.log
Mon Feb  2 20:36:11 2009 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Mon Feb  2 20:36:11 2009 LZO compression initialized
Mon Feb  2 20:36:11 2009 TUN/TAP device tun0 opened
Mon Feb  2 20:36:11 2009 /sbin/ip link set dev tun0 up mtu 1500
Mon Feb  2 20:36:11 2009 /sbin/ip addr add dev tun0 local 192.168.2.1 peer 192.168.2.2
Mon Feb  2 20:36:11 2009 UDPv4 link local (bound): [undef]:1194
Mon Feb  2 20:36:11 2009 UDPv4 link remote: servidor2.com:1194
Mon Feb  2 20:36:16 2009 Peer Connection Initiated with servidor2.com:1194
Mon Feb  2 20:36:16 2009 Initialization Sequence Completed

Parece que sí, que ha funcionado. ¿Veremos la segunda máquina desde la primera?

[osus@servidor1 ~]# ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=276 ms
64 bytes from 192.168.2.2: icmp_seq=2 ttl=64 time=197 ms

Eso es un sí ¿no? 😛 .

Consideraciones adicionales

Obviamente habrá que abrir el puerto que hemos configurado para el túnel en el router (si lo hubiese) y verificar que el firewall no está bloqueando el tráfico desde o hacia ese puerto, suele ser el principal problema a la hora de conectarse, si tu firewall está bien configurado bloqueará automáticamente todo el tráfico que no sea el permitido (http, smtp, dns…).

Si queremos que el túnel se inicie automáticamente al reiniciar las máquinas habrá que añadirlo a los servicios de arranque. En el caso de CentOS/RHEL sería:

chkconfig --level 2345 openvpn on

Finalmente nos queda un comentario. Supongamos que la primera máquina es nuestro servidor remoto y el segundo está en nuestra oficina y que queremos poder llegar desde el primero a otros servidores de la oficina. Supongamos también que la red de la oficina es del rango 192.168.0.0/24 (el túnel, como hemos visto, está en la red 192.168.2.0). En el servidor enrutamos el tráfico a las IP’s de la oficina a través del túnel añadiendo esta línea al archivo de configuración de la VPN, OpenVPN añadirá la ruta cada vez que se levante el túnel.

route-up "route add -net 192.168.0.0/24 tun0"

Ya sólo te queda añadir en el servidor cliente las reglas iptables adecuadas para que el tráfico se diriga hacia donde tú quieres que lo haga.

Éso es todo. Como os prometí, es un sistema muy sencillo a la vez que potente y ligero.