Combinando SSH, cron y at


Table Of Contents

De nuevo vamos a tratar de un tema en donde la terminal en modo texto y programas desde la linea de comandos son los protagonistas. Probablemente, este articulo no le sirva de mucho a un usuario domestico, con un solo ordenador en casa, pero si quieres ir conociendo tu sistema mas a fondo, y tienes que administrar mas de una maquina/servidor, sigue leyendo que puede que aprendas algo.

En este articulo vamos a ver como conectarse sin clave de acceso a otros ordenadores, de una manera segura, con ssh. Tambien veremos como configurar nuestro sistema para que trabaje por nosotros, automatizando tareas con cron y at. Y por ultimo, como combinando estas tecnicas, podemos ejecutar trabajos y recoger informacion de forma automatica de muchos ordenadores a un servidor central.

SSH sin clave de acceso

No vamos a tratar como instalar SSH (cliente/servidor) en vuestras maquinas. Esto no deberia de ser un problema en las distribuciones de hoy en dia y muchas de ellas instalan este programa por defecto. Suponemos antes de seguir que tanto el cliente como el servidor SSH estan instalados y funcionando en vuestros ordenadores.

SSH (Security SHell) es un programa que permite conectarse de forma segura entre maquinas que tengan este programa instalado (cliente y servidor). Entre muchas de las cosas que SSH ofrece, la mas importante es que todo el trafico entre dos maquinas (incluido cuentas y claves de acceso) es encriptado. Con esto se evita que informacion importante y confidencial caiga en manos ajenas en el caso que alguien este ‘escuchando’ lo que viaja por la red con un programa ‘packet sniffer’.

Para conectarse con SSH, como el usuario ‘user’, de una maquina llamada ‘servidor1’ a otra llamada ‘servidor2’, podemos escribir en una terminal lo siguiente:

[user@servidor1]# ssh user@servidor2
user@servidor2's password: xxxxxxx

Last login: Sun Oct  1 15:46:02 2006
[user@servidor2]# 

Lo normal es que haya que escribir la clave de acceso cuando nos conectamos a otro servidor. Esto no es un problema siempre y cuando estemos trabajando de forma interactiva y podamos escribir la clave, tampoco es un gran problema si nos conectamos pocas veces. Pero si queremos que una maquina se conecte de forma automatica a otra para realizar un trabajo, o tenemos que conectar muchas veces a diferentes maquinas, el tener que escribir la clave todo el tiempo termina siendo un problema. Esto lo podemos solucionar usando lo que se llaman claves privadas y publicas. No vamos a explicar que significa esto, esto se escapa del tema del articulo, pero al final damos unos enlaces que podeis usar para profundizar en el tema si quereis.

Para generar nuestras claves publica y privada vamos a utilizar el programa ssh-keygen que forma parte de SSH. A continuacion teneis un ejemplo de como podemos generar estas claves:

[ralf@servidor1]# ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/ralf/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/ralf/.ssh/id_rsa.
Your public key has been saved in /home/ralf/.ssh/id_rsa.pub.
The key fingerprint is:
09:f7:58:bc:07:3f:f4:70:7b:d7:ce:cb:6b:61:f8:9c ralf@servidor1

En este ejemplo hemos generado dos claves, una privada (/home/ralf/.ssh/id_rsa) y otra publica (/home/ralf/.ssh/id_rsa.pub) del tipo RSA con una longitud de 2048 bits. No hemos utilizado ‘passphrase’ para no tener que escribirla cada vez que nos conectemos.

A continuacion podeis ver el contenido de la clave privada y publica del ejemplo:

[ralf@servidor1]# cat /home/ralfm/.ssh/id_rsa

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAw0a4dn8wGAaRcMuIPY8/pk11YPV5Nk6R5VCtHNLnH2+hmsMw
47wMdJ8PC9Vu6bDYLgSwRIpV83kEJSE1DdHB93qExqjXnA7EWOzgmjjbSTbi2kfN
xB4Vh9tS3dXCy/9xfcUrYj8LZH931I3y46YQAswmDqS9nZCvoE9xmzDmt9uecSOE
39e5aZiHwOGXlyNkExRRBT2JIDcL9aeAa1HclnRTbsZVWsxX8+K6koVvsmMhRZNq
XoSuU+CWGse/UsLbo2sWHUKaFVMBVc2h0E4j08Rm/R85BgwzgxXr+ql6Tv1qJjyd
lFJkUuD6RJ78X/Wp9HqVwM9i9v/hyE6FK9GtMQIBIwKCAQB6vr0XSKHjN1QbA5d3
JteNGr7POzY/ZJY4XpizCDmBeV5EBamzuAfURrkAH8IPO/WZRMaRe4Z7yGkBZVSM
V/ZDyVrGA7q53WV5uXc8XkCxrXimdkbTC5iBSAgzqu946bUNOhtFEa9jvdZLF2V5
Jo24nZRDuAIohtTLKp8uWUCQ0hbq+NIg85tZhHuIgQtqFZNBF2YIOTNN6v532Ena
YvNZUGfmYwJG1CurA1dUseL06bSB9LpOIaOG2j5bYWnhogshih0CYShzi1S8tJCN
tpfMz2WWYGN/Mxa6Itq0xI+kVH0hLFkhoU/ryJ76toklFs7yZR2APPcgCJVxX3b/
DLoTAoGBAOvAd5Raz+Wc1LU5sH5diHNEYz+6etyUR3p5k7cLLMQ9Ye7u1NjBLWzF
NRpF3md+I88X4qZCu6OKL/Dj4+ah9uXoi850D/G9rLfUIgtpLwxpx6jeseJuvGLr
GB49lE6wFDlf460eaHhB5ndLX2i9UQ0Oqbyp0n9zYSpmqUsyQBqfAoGBANQMTqI5
Vbm+WcguBrWceJ3P3UwPIdrtEPymJGsnnvJK+zORaz7L2QLNKE+LupOAEVXqlCdZ
qsxzJuTrVIGyj/tLVQI8r1xaAs5VdQ2FqyXp+JyApXJ7fomHI3HMCwFIBa+F73nu
9OzrUp1THS3QXWrv0uRWm+X/M/gtR4hMiPYvAoGAf/rEkl0vB55HlZRYfxzVC1+j
l5+/CgdaAKhmIYm5N1SFnvauD0RL2/YG4mBxa2G7qu+1jXSvAQHfgsTazahhdX49
RDBgbUm1iF03DYI+HK5zs3GTxBA6YZWQv/WLBiUSSwgrI3boQUhYiecWiVDUOknJ
23Ih0CixFwSHybwxbYkCgYEAwd9d1iXKuHOFSU6nDHHNXRXRpKAe9AvyRhQ+jdsU
+sg2IIT0Vqu/GIEO6aRS0AAP2YYDzDS5anfpC8/YPBD4qz2PjQRIjvM1w/ZcZCJw
l7FYVJLgaKtsYHuOHuZwdjM4ZfbMUjmPeYax7uznelga5W2NnZEDkHRMxaW9vnHc
TssCgYEAifwa8oq5eVl5qw/gh4s3Tv3Qjk6SCxIXCF2FwKUfYmkl7v/Yq4xL1Owp
kQ7jT6Zi20endNT2a4mCFu79rztDzfPR/7BgOCFxu88IYO+0fgp4VeBZb0G9T3GG
g/k0XSpd5Zjgn9SHVD1u5NRacUpeIPqX3cbwPxP5Xh7XlfEXcmw=
-----END RSA PRIVATE KEY-----

[ralf@servidor1]# cat /home/ralfm/.ssh/id_rsa.pub ssh-rsa

AAAAB3NzaC1yc2EAAAABIwAAAQEAw0a4dn8wGAaRcMuIPY8/pk11YPV5Nk6R5VC
tHNLnH2+hmsMw47wMdJ8PC9Vu6bDYLgSwRIpV83kEJSE1DdHB93qExqjXnA7EWO
zgmjjbSTbi2kfNxB4Vh9tS3dXCy/9xfcUrYj8LZH931I3y46YQAswmDqS9nZCvo
E9xmzDmt9uecSOE39e5aZiHwOGXlyNkExRRBT2JIDcL9aeAa1HclnRTbsZVWsxX
8+K6koVvsmMhRZNqXoSuU+CWGse/UsLbo2sWHUKaFVMBVc2h0E4j08Rm/R85Bgw
zgxXr+ql6Tv1qJjydlFJkUuD6RJ78X/Wp9HqVwM9i9v/hyE6FK9GtMQ==ralf@desktop 

Antes de seguir, hay dos cosas muy importantes a tener en cuenta con respecto a la seguridad de nuestros sistemas cuando utilicemos SSH sin clave de acceso:

  • La primera es que, nuestra clave privada nunca se debe hacer publica. Tenemos que tener cuidado de que nadie, tenga acceso a nuestra clave privada para no comprometer la seguridad de nuestro sistema.
  • La segunda es que, al no utilizar ‘passphrase’ (vacia), tenemos que estar seguros que la maquina servidor (maestra) desde donde nos vamos a conectar a los demas servidores, debe de ser segura. Tenemos que tener un cuidado extra con esta maquina, ya que si alguien indeseado consigue acceder a la misma como ‘root’, obtendra a su vez acceso (sin necesidad de clave) a todos los demas servidores de nuestra red. Para aumentar la seguridad del sistema, y si no necesitamos acceso ‘root’, podemos crear un usuario de sistema con privilegios restringidos, el cual podra ser utilizado para acceder a los demas servidores.

Una vez que hemos generado nuestra clave privada y publica en nuestro servidor principal (el que tendra acceso al resto de nuestras maquinas), tenemos que copiar el contenido del fichero /home/ralf/.ssh/id_rsa.pub (clave publica) a el fichero ~/.ssh/authorized_keys del usuario que va a tener acceso sin clave. Esto se debe de hacer en todas las maquinas a las que queremos tener acceso.

El contenido de ~/.ssh/authorized_keys en las diferentes maquinas se puede actualizar, por ejemplo, de la siguiente manera:

[ralf@servidor1]# scp /home/ralf/.ssh/id_rsa.pub ralf@servidor2:~/
[ralf@servidor1]#$ ssh ralf@servidor2
[ralf@servidor2]#$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

Despues de hacer esto, podremos conectarnos desde ‘servidor1’ a ‘servidor2’, como el usuario ‘ralf’ y sin clave, de la siguiente manera:

[ralf@servidor1]# ssh ralf@servidor2
Last login: Thu Sep 28 17:00:17 2006

[ralf@servido2]# 

Este procedimiento lo tenemos que repetir en todos los servidores a los que deseemos acceder sin clave desde la maquina ‘servidor1’.

Para mejorar todavia mas la seguridad, podemos actualizar en todos nuestros servidores los ficheros /etc/hosts.allow y /etc/hosts.deny con la IP o el nombre completo de el ‘servidor1’ (servidor maestro/principal). Estas son las lineas que deberiamos de añadir o actualizar si ya existen:

En /etc/hosts.allow:
sshd: IP o hostname de 'servidor1'

Y en /etc/hosts.deny:
sshd: ALL

Con todo lo que hemos hecho hasta ahora, podremos ejecutar comandos remotamente en ‘servidor2’ desde ‘servidor1’ sin necesidad de claves. El formato seria el siguiente:

[user@servidor1]# ssh user@servidor2 'comando a ejecutar en servidor2'

CRON

Para los que no lo saben, cron es un administrador de procesos en segundo plano que ejecuta trabajos a intervalos regulares. Cron se utiliza para automatizar tareas que hay que realizar periodicamente. Los procesos que deben ejecutarse y la hora en la que deben hacerlo se especifican en el archivo crontab del usuario que ejecutara los procesos.

Para editar este fichero podemos utilizar nuestro editor favorito. Para ello tenemos que tener la variable de entorno EDITOR definida y usar crontab -e para editar nuestro crontab. Un ejemplo usando el editor emacs:

[ralf@servidor1]# export EDITOR=/usr/bin/emacs
[ralf@servidor1]# crontab -e

En el fichero crontab se define una linea por tarea/trabajo a ejecutar y el formato de la misma es el siguiente:

 ------------- minutos (0 - 59)
 | ----------- horas (0 - 23)
 | | --------- dia del mes (1 - 31)
 | | | ------- mes (1 - 12)
 | | | | ----- dia de la semana (0 - 6) (domingo=0, lunes=1, ... sabado=6)
 | | | | |
 * * * * * comando a ejecutar


* significa todos los valores validos
/ permite definir una repeticion
- permite definir un rango
, permite definir varios valores

Las lineas que comienzan con ‘#’ se consideran comentarios. Podemos utilizar la linea MAILTO=“usuario@ejemplo.com” al comienzo para que cron nos mande un mensaje cuando se ejecute un trabajo. Un ejemplo nos ayudara a entender todo esto mejor. Listamos el contenido de nuestro crontab despues de haberlo actualizado con crontab -e:

[ralf@servidor1]# crontab -l

MAILTO="usuario@ejemplo.com"

# Generar estadisticas web todos los dias a las 12:01 y als 23:01 
1 12,23 * * * /usr/local/bin/webalizer -c /etc/webalizer.conf

# Limpiar copias de seguridad de la base de datos (guardar ultima
# semana). Ejecutar trabajo de lunes a viernes a la 01:01
01 01 * * 1-5 for files in `/usr/bin/find /backups/pgsql/ -mmin +10000`; do rm -f $files; done

# Ejecutar 'mi_script.sh' un minuto pasado la hora en punto, cada dos horas.
01 */2 * * * /usr/local/bin/mi_script.sh 

En fin las posibilidades son muchas. Podeis usar vuestra imaginacion.

AT

at tambien se puede usar para ejecutar, solamente una vez, un trabajo a una determinada hora. Al contrario de cron que ejecuta de forma periodica hasta que no definamos lo contrario en el crontab del usuario.

Podemos definir los comandos a ejecutar o bien por la entrada estandar o en un fichero. El formato en uno u otro caso seria, at hora:minuto o at -f fichero hora:minuto. Un ejemplo nos aclarara las cosas. (^D significa que pulsamos las teclas Ctrl + D). Estos dos ejemplos hacen lo mismo (arrancan de nuevo la maquina) aunque se definen de manera distinta.:

[ralf@servidor1]# at 12.12.2006 21:30
> reboot
> ^D

[ralf@servidor1]# cat /tmp/at_reboot
reboot

[ralf@servidor1]#  at -f /tmp/at_reboot 12.12.2006 21:30

Para ver y borrar los trabajos definidos se pueden usar los comandos at -l y at -r ‘ID del trabajo a borrar’

Combinando SSH, cron y at

El uso combinado de SSH sin clave y cron/at es una tecnica usada muchisimo por administradores de sistemas Unix/Linux con responsabilidad de muchas maquinas/servidores. Es una manera facil y eficaz de recoger informacion o ejecutar un trabajo en muchas maquinas de manera rapida. Vamos a poner un par de ejemplos para ver como podemos hacer esto.

Estos ejemplo necesitan acceso como root para funcionar, lo mas facil es actualizar el fichero ~/.ssh/authorized_keys de ‘root’ en las maquinas a acceder, con nuestra clave publica. Otra alternativa seria usar sudo.

En este ejemplo vamos a arrancar de nuevo todas las maquinas de nuestra subred 10.1.1.0/24 para que arranquen con el nuevo kernel que hemos instalado. El trabajo lo vamos a ejecutar mañana a las 23:00 horas.:

[ralf@servidor1]# at 23:00 tomorrow
>for ip in `seq 1 254`; do ssh root@10.1.1.${ip} '/sbin/shutdown -r now'; done
>^D
job 3 at 2006-10-05 23:00

[ralf@servidor1]#  at -l
3       2006-10-05 23:00 a ralf

En este otro ejemplo vamos a recoger los datos de uso de disco de todos los directorios /var de nuestros servidores, en nuestra subred 10.1.1.0/24. Esta lista la ordenaremos de mayor a menor uso, la grabaremos en /tmp/uso_var.txt y el trabajo lo ejecutaremos todos los dias a las 03:00:

[ralf@servidor1]# export EDITOR=/usr/bin/emacs
[ralf@servidor1]# crontab -e

Actualizamos y grabamos crontab con estas dos lineas:

# Uso de /var en 10.1.1.0/24
00 03 * * * for ip in `seq 1 254`; do echo -n 10.1.1.${ip}: ;ssh
root@10.1.1.${ip} '/usr/bin/du -sk /var '; done | sort -r +2 > /tmp/uso_var.txt

Supongo que os podreis hacer una idea de las posibilidades infinitas de automatizacion que tenemos con lo que hemos explicado y la ayuda indispensable que da a los administradores de sistemas Unix/Linux. En fin, espero que este articulo os ayude un poco mas a tener control de vuestros sistemas, esto es todo por hoy.

Enlaces: