Soy Aitor Roma, CEO de RedAven.com una empresa dedicada a la administración de sistemas y a partir de ahora una nueva incorporación de CloudAdmins.org
Antes de escribir este post hice unas votaciones en Facebook i en las listas de CloudAdmins (Donde os recomiendo que os inscribáis ya que se pueden producir debates muy interesantes), para ver el interés que podría tener varios artículos que tenía pensados. Este es el articulo ganador en las votaciones!

LO QUE HE OBSERVADO
He observado que con todo esto del cloud, acabamos gestionando un montón de máquinas ya que con la virtualización, es relativamente fácil empezar a hacer uso de las buenas practicas y  separar servicios por cada máquina. pero siempre acaban ocurriendo problemas sobretodo con el acceso remoto.
Un caso muy típico es que una empresa, tenga sus propios servidores dentro de su red y en muchas ocasiones otros proveedores gestionan las comunicaciones, no  tenemos la password del router y cuando preguntas nadie la sabe.
Con esta solución lograríamos hacer un bypass de la NAT del router y tener acceso a una terminal mediante un navegador web, sin recordar ips de los servidores y sin necesidad de IPs fijas del ADSL, solo debemos acordarnos de un puerto.
EMPEZANDO A PENSAR
Básicamente la idea era la siguiente, buscar una forma para que los clientes se conectaran a nosotros en vez de nosotros a ellos. Eso nos permite desde un principio no tener que saber donde esta cada servidor y cada ip.
así que lo primero que pensemos fue  crear  un tunel ssh, de forma que nos saltaremos la NAT que pueda tener el router.  pero con esto seguíamos teniendo un problema… ¿Que pasa si se corta la conexión?
EL PROBLEMA Y COMO LO SOLUCIONEMOS
Cuando por primera vez hicimos el experimento usemos ssh a pelo , y pronto nos dimos cuenta que este no reconectava la sessión en el caso que se reiniciara el servidor.
Solucionemos este problema usando autossh, que no hace mas que reconectar las sesiones caidas.
En el servidor (login.redaven.com)

# useradd -m -s /bin/bash gesrem
# passwd gesrem

Cliente

# apt-get install openssh-server sshpass autossh
# useradd -m -u999 -s /bin/bash gesrem
# passwd gesrem
# su -s /bin/bash gesrem
$ ssh-keygen
$ cat /home/gesrem/.ssh/id_rsa.pub | ssh gesrem@login.redaven.com 'cat >> ~/.ssh/authorized_keys'

Añadir a /etc/rc.local

# su -s /bin/sh gesrem -c 'autossh -M 29001 -q -f -N -R 3000:localhost:22 gesrem@login.redaven.com’

Conectar desde servidor

$ ssh localhost -l gesrem -p 3000

El puerto marcado en negrita debe cambiar por cada máquina a administrar.

AUTOMATIZANDO
El escenario anterior, esta muy bien y hace su prometido, pero la verdad es que es un coñazo tener de configurar todos los clientes a mano, así que he decidido crear un Servidor web que nos aporte una consola web para gestionar las diferentes máquinas de esta forma ganamos varias ventajas.

  • Seguridad ( No damos acceso directo al servidor ssh)
  • Comodidad ( funcionamiento desde cualquier dispositivo con navegador web)
  • Gestión de los puertos automático
  • Distribución del paquete
  • Integración en contextos de migasfree

Para ello me he valido del software libre siguiente:

Ahora, procederé a explicar como se instala nodeJS , tty.js , y todas las modificaciones que hice a tty.js para que ejecutara mi bash de conexión.
Instalación Dependencias

# apt-get install python g++ make

Instalación de NodeJS

# mkdir ~/nodejs && cd $_
# wget -N http://nodejs.org/dist/node-latest.tar.gz
# tar xzvf node-latest.tar.gz && cd `ls -rd node-v*`
# ./configure
# make install

Para ver como puedes instalar en Otros sistemas
https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
Una vez instaldo nodeJS instalaremos tty.js

Instalación de tty.js
La instalación es trivial se puede usar el gestor de paquetes de Node que es npd este actua igual que instaladores de otros lenguajes de programación, como cpan para perl o pip o easy_install para python , o pear para php.

# npm install tty.js

Configurando tty.js
Una vez instalado el modulo tty.js, es el momento de sacarle jugo y hacerlo funcionar. Para ello nos colocamos en el directorio donde está instalado

# cd /root/node_modules/tty.js/bin/

y creamos con nano el siguiente archivo:

nano remote.js

var tty = require(‘tty.js’);
var app = tty.createServer({
shell: ‘3001‘,
users: {
admin: ‘la_password
},
“https”: {
“key”: “./server.key”,
“cert”: “./server.crt”
},
port: 443
});
app.get(‘/admin‘, function(req, res, next) {
res.send(‘la_password‘);
});
app.listen();

En el codigo he remarcado dos valores admin y la la_password Estos dos valores son usados para la autenticación al entra a https://login.redaven.com y se hacen mediante auth_basic.

NOTA: Teneis todos los archivos en nuestro repositorio de github https://github.com/redaven/gesrem

Para aumentar la seguridad, usamos SSL para la conexión.
No entro en la creación del certificado, pues cada uno, es caprichoso en la creación de estos.
debemos crear los archivos:

  • server.key
  • server.crt ( Obtenido desde la CA Certificadora)

Ayuda para creación de certificados: http://goo.gl/UgP9i

Una vez creados los certificados, si os fijás en rojo aparece 3001, es el nombre que le he dado al script bash que hace la magia. ¡Lo creamos!.
nano /usr/bin/3001

#!/bin/bash
echo ” ”
echo RedAven RemoteAdmin version 1.0
echo ———————————————-
echo Introduce el puerto Administrativo del Servidor. echo ” “

read -p “Puerto Administrativo: ” port
sshpass -p ‘la_password_client‘ ssh -o StrictHostKeyChecking=no gesrem@localhost -p $port

Le damos permisos de ejecución.

# chmod +x /usr/bin/3001

En este caso, la_password_client, es la que usara el usuario gesrem, indicado en los pasos de configuración del cliente ( no tiene nada que ver con la password que usara para el usuario gesrem del servidor)

NOTA:La opción StrictHostKeyChecking=no es para que nos autoacepte la huella SSH
Una vez todo hecho, en mi caso, he modificado el script de inicio de nodejs para que inicie el servidor.

Servicio en el arranque
Usaremos el mismo script de nodejs añadiendo en start que también levante el servidor, lo editamos así.

nano /etc/init.d/nodejs


case “$1” in
start)
log_begin_msg “Starting $DESC…”
start-stop-daemon –start –chuid “$CHUID” –background –make-pidfile –pidfile $PIDFILE
–exec $NODEJS_EXEC — $LOGFILE log_action_end_msg $?
node /root/node_modules/tty.js/bin/remote.js -daemonize

Reiniciamos el servicio

# service nodejs restart

Ya podríamos acceder mediante https://login.redaven.com
AUTOMATIZANDO TODO.
Para nuestro entorno, tenemos de usar un servidor con soporte php escuchando en el puerto 80 de nuestro servidor, en mi caso utilizo nginx pero es valido cualquier otro.
Instalamos la base de datos mysql o usamos una de externa eso lo dejo a la elección del implantador.
Lcremote funciona con una base de datos sql llamada gesrem con una sola tabla llamada hosts.
Esta es la estructura.

CREATE TABLE `hosts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(255) NOT NULL,
`hostname` varchar(255) NOT NULL,
`ext_ip` varchar(255) NOT NULL,
`os` varchar(255) NOT NULL,
`port` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=167 DEFAULT CHARSET=utf8;

Una vez tenemos ya creada la base de datos, es el momento de crear los diferentes php, que serviran para operar en ella.
La función principal es tener localizados los puertos administrativos con los nombres de host, y la IP externa.
Los campos de la base de datos son los siguientes y esto es lo que contienen..

  • id ( campo autoincremental )
  • key ( Este campo es un md5 generado con la mac de la tarjeta de red sirve paraidentificar unequivocamente la máquina)
  • hostname ( Nombre del host)
  • ext_ip ( La ip externa)
  • os ( Distribucion de Linux que utiliza)
  • port ( Este es el campo puerto y se asigna incrementalmente)Una vez creada la base de datos, le toca el turno a los php que hay 3 :
  • register.php – Registra la máquina en la Base de datos.
    http://login.redaven.com/register.php.txt
  • Install.php – Crea la configuración de el cliente de lcremote.
    http://login.redaven.com/install.php.txt

NOTA: El primer puerto por el que quieres que empiece se tiene de indicar en la tabla la primera vez

  • puerto.php – Muestra el proximo puerto disponible

http://login.redaven.com/puerto.php.txt

  • Script de inicio

http://login.redaven.com/lcremote
Con todo esto ya tenemos lo necesario para funcionar.
Creación Paquete Deb Cliente
En mi caso he usado debreate ( http://debreate.sf.net)
Os adjunto el project hecho en debreate:
http://login.redaven.com/lcremote-project.dbp
De todas formas adjunto La configuración por si quisieraís hacer el paquete con la forma tradicional.
Lo más importante a la hora de crear el paquete.
Predependencias.
• Openssh-server
• sshpass
• autossh
• wget
Una vez creada la sección de predependencias vamos al:
Script de Pre-install

#!/bin/bash
if [ -f /etc/lcremote.conf ] then
kill -9 `ps aux |grep gesrem |awk {'print $2'}`
rm /etc/lcremote.conf
userdel gesrem
update-rc.d -f lcremote remove
rm -rf /home/gesrem
rm /etc/init.d/lcremote
else
echo Instalando dependencias....

Script de postInstall

#!/bin/bash
function RegisterSystem () {
SERVER=login.redaven.com
id=`ifconfig eth0 |grep HW | awk {'print $5'} |tr ":" "@" |md5sum - |cut -d " " -f1`
ext_ip=`dig myip.opendns.com @resolver1.opendns.com +short` os=`lsb_release -si`
FECH='http://'$SERVER'/register.php?key='$id'&hostname='$HOSTNAME'&ext_ip='$ext_ip'&os='$os''
wget -qO- $FECH
}
function InstallSystem () {
SERVER=login.redaven.com
id=`ifconfig eth0 |grep HW | awk {'print $5'} |tr ":" "@" |md5sum - |cut -d "-" -f1`
wget -q http://$SERVER/install.php?key=$id -O- |bash -
}
RegisterSystem
InstallSystem
/etc/init.d/lcremote start

Script Pre-Remove

#!/bin/bash
kill -9 `ps aux |grep gesrem |awk {'print $2'}`
rm /etc/lcremote.conf
userdel gesrem
update-rc.d -f lcremote remove
rm -rf /home/gesrem
rm /etc/init.d/lcremote

Script Post-Remove

#!/bin/bash
echo "lcremote uninstalled [ OK ]"

Con esto ya tendréis el paquete deb para poderlo instalar en los servidores.
Si gestionáis una gran cantidad de servidores os aconsejo usar repositorios propios, nosotros usamos migasfree que es un proyecto del ayuntamiento de Zaragoza.
Para ver como subir el deb al repositorio podéis visitar la documentación de migasfree.
Resultado final…