Sirviendo información sobre Linux desde 1998

Combinando SSH, cron y at

Informacion 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:

  1. 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.
  2. 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.

A continuacion teneis algunos enlaces que os pueden ayudar a profundizar en el tema:

SSH: http://en.wikipedia.org/wiki/Ssh
RSA: http://en.wikipedia.org/wiki/RSA
Public-key_encryption: http://en.wikipedia.org/wiki/Public-key_encryption
Cron: http://en.wikipedia.org/wiki/Cron
At: http://en.wikipedia.org/wiki/At_%28Unix%29

Packet_sniffer: http://es.wikipedia.org/wiki/Packet_sniffer
Criptografia asimetrica: http://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

preguntar como copio de remoto a servidor local

excelente articulo, me funciono a la perfeccion mi duda es como copio un archivo(respaldo de mysql gzip)de un servidor que esta en tlaxcala a un servidor que uso k esta en el df mediante la conexion ssh?

checa el comando scp no me

checa el comando scp no me recuerdo como se usa o usa un servidor ftp

muy buen material

muy buen material

informacion

por favor facilitenme esta informacion:
proceso
definicion y actuacion sobre los procesos, rediccionar la salida de un programa/proceso, conexcion entre dos procesos(tuberias), introcuccion a las estructuras asociadas a los comando, metacaracteristicas relacionados con los archivos y comando, tilizacion del entrecomillado y empleo de caracteres especiales.

expresiones reculares y flitros
uso de expreciones regulares. otros

muy bueno

esta de lo mejor la explicacion que dan espero continuen asi para seguir fomentando el software libre
GRACIAS

uso de ssh remoto y cron

Tengo un problema y no se cual es la causa para darle una solucion, y se trata de que cree un archivo.sh donde invoca comandos por ssh remotamente de otro servidor como ssh usuario@hostremoto comando, por ejemplo para borrar un archivo cada hora.

El problema que este archivo esta para ejecutarse cada hora, desde el cron, se ejecuta el comando remoto borra el archivo pero cuando hago un ps -fu cuentalocal, aparecen como colgados la ejecucion de estos comandos y me colgo mi cron de dicha cuenta. Pueden ayudarme cual puede ser el problema? (plataformas solaris 10) gracias. (chritian007@gmail.com)

coemmtario anomino

Excelente articulo, tengo algunas dudas espero y no salirme del tema.
Con que comandos puedo obtener mi ip estatica y como puedo obtener el numero de matricula de mi placa madre. Y tambien quisiera saber si ay otras maneras de conectarme en red y cuales serian.

no me muestra el valor de mi variable de ambiente

Como le hago para que por medio de mi script remoto me respete las variables que voy creando al vuelo dependiendo de la situacion ya que yo las inicializo asi

ORACLE_BASE=/u01/app/oracle/; export ORACLE_BASE;
ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1; export ORACLE_HOME;

pero trato de ejecutar algo que esta en esa ruta de mi variable anteriormente inicializada no me lo encuentra y si la trato de despeglar con echo $ORACLE_BASE no muestra nada

Imagen de orvtech

A mi si me funciona,

A mi si me funciona, ejecuto:

#ORACLE_BASE=/u01/app/oracle/; export ORACLE_BASE;
#ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1; export ORACLE_HOME;

y Luego ejecuto:
#env | grep -i ora

y el resultado es:
#ORACLE_BASE=/u01/app/oracle/
#ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1