martes, 4 de mayo de 2010

SSH Agent, sudo y ejecución de scripts con cifrado y sin contraseñas

Vamos a realizar una serie de pasos para poder ejecutar un script que contenga sentencias ssh y sudo sin que pida la contraseña más que una vez. También se puede hacer sin que pida nunca la contraseña aunque es más inseguro.

Tenemos la máquina ubults00 con ubuntu 10.04 server. Este ejecutará el script y este script ejecutará comandos en otras máquinas a las que accederá mediante ssh para encriptar la comunicación y usará un usuario que ejecutara comandos root con sudo. El usuario que ejecutará el script es "administrador" y tendrá contraseña "password".

Tendremos otras máquina llamadas deb01,deb02...

Instalar SSH

Todas las máquinas deben tener instalado ssh. En cada máquina ejecutamos

$ sudo aptitude install openssh-server
$ ssh -version
OpenSSH_5.3p1 Debian-3ubuntu3, OpenSSL 0.9.8k 25 Mar 2009

Configurar SUDO para que no pida contraseña

Para cada tarea que use sudo se pedirá la contraseña si ejecutamos con ssh una operación con la cuenta autorizada que requiera derechos de administrador. Como en la siguiente operación remota de ejemplo.

ubults00:~# ssh administrador@deb01 sudo aptitude update

En la operación anterior pedirá contraseña ssh y después la contraseña de sudo pero podemos configurar el archivo /etc/sudoers para que esta cuenta no necesite autenticación sudo. Debemos editarlo con visudo y como root. Así si tenemos algún error nos lo dirá al guardar y salir.

$sudo visudo

# /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the man page for details on how to write a sudoers file.
#

Defaults        env_reset

# Por defecto ponemos que el usuario administrador no deba
# autenticarse.
Defaults:administrador !authenticate

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL) ALL

# ponemos el usuario administrador para que pueda ejecutar en 
# cualquier maquina: ALL=
# cualquier comando como root: (root) ALL
# Se puede especificar muchisimo más pero nos vale así
administrador ALL=(root) ALL
...

Una vez hecho esto debemos realizar los cambios en todas las máquinas que queramos gestionar con este usuario "administrador". Editamos los ficheros /etc/sudoers igual con visudo o con scp copiamos el /etc/sudores con los cambios a todas las máquinas (solo si es el mismo archivo ya que lo sobreescribiremos en la maquina remota)

scp /etc/sudoers root@[maquinaremota]:/etc/

Con esto evitaremos las contraseñas de sudo y ejecutaremos como root tareas en todas las maquinas del tipo sudo aptitude install paquete.

Creación de claves SSH

Una vez configurado sudo, primero hay que generar unas claves (keys) publica y privada en ssh para poder automatizar las tareas de administración de sistemas sin tener que meter una contraseña en cada operación cifrada con ssh.

Creamos el usuario administrador en cada máquina implicada (ubults00, deb01, deb02...) Este usuario tiene que tener permisos para ejecutar las tareas como root(ver apartado anterior)

ubults00:~$ sudo useradd -d /home/administrador -m -s /bin/bash -c "Usuario para ejecutar scripts ssh" administrador
ubults00:~$ sudo passwd administrador
Introduzca la nueva contraseña de UNIX: 
Vuelva a escribir la nueva contraseña de UNIX: 
passwd: password updated successfully

Creamos una clave pública y otra privada en ubults00.

La clave privada, reside en el directorio $HOME/.ssh/ de la máquina que va a ejecutar el script o las operaciones. Nosotros llamaremos al archivo de clave privada id_rsa_administrador. El archivo debe tener permisos 0600 para el usuario que ejecuta las operaciones. Nadie debe tener esta clave privada.

La clave pública que se creará en el archivo id_rsa_administrador.pub en el directorio $HOME/.ssh de la máquina que va a ejecutar las operaciones (ubults00) debe tener permisos 0600 para el usuario que ejecuta las operaciones.

Esta llave pública, y solo la publica, se distribuirá a las máquinas remotas donde se ejecutan las operaciones. En este caso serán deb01, deb02, deb03... La llave pública se incluirá en el archivo remoto $HOME/.ssh/authorized_keys de cada cuenta de usuario que queremos autorizar (administrador) Si no existe este archivo se debe crear y darle los permisos 0600 al usuario de la cuenta remota (administrador).

Ahora vamos a hacer lo que hemos dicho. Cambiamos al usuario administrador y creamos las llaves publica y privada en ubults00.

$ su - administrador
Contraseña: 
administrador@ubults00:~$

Cuando nos pida la contraseña tenemos dos opciones:
  1. Dejarla en blanco. No se cifrará y será menos seguro pero no nos pedirá la contraseña al ejecutar los scripts con tareas que hagamos al conectar por ssh.
  2. O poner la contraseña. Al ejecutar el script con varias tareas ssh nos pedirá la primera vez la contraseña, y solo la primera vez, ya que usaremos ssh-agent. Todo estará correctamente cifrado y asegurado. La forma que elegimos nosotros.
administrador@ubults00:~$ ssh-keygen -b 2048 -t rsa -C "administrador@localhost" -f /home/administrador/.ssh/id_rsa_administrador
Generating public/private rsa key pair.
Created directory '/home/administrador/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/administrador/.ssh/id_rsa_administrador.
Your public key has been saved in /home/administrador/.ssh/id_rsa_administrador.pub.
The key fingerprint is:
da:d6:e8:53:75:1e:68:67:86:29:71:36:d8:7a:37:b6 administrador@localhost
The key's randomart image is:
+--[ RSA 2048]----+
|           o     |
|          o =    |
|           = =   |
|          o B X  |
|        S  = O + |
|       o o.   E  |
|      . +..      |
|       o.        |
|        ..       |
+-----------------+

Como vemos el directorio .ssh se ha creado en el proceso. También la clave privada y la publica. Las hemos creado del tipo rsa (-t), de 2048 bites (-b) y con un comentario con el correo del usuario administrador (es opcional -C)

administrador@ubults00:~$ cd .ssh
administrador@ubults00:~/.ssh$ chmod 600 id_rsa_administrador
administrador@ubults00:~/.ssh$ chmod 600 id_rsa_administrador.pub
administrador@ubults00:~/.ssh$ ls -l
total 8
-rw------- 1 administrador administrador 1743 2010-05-04 18:28 id_rsa_administrador
-rw------- 1 administrador administrador  405 2010-05-04 18:28 id_rsa_administrador.pub

Hemos cambiamos los permisos y vemos los ficheros creados.

Ahora creamos el directorio .ssh en cada maquina y copiamos la clave publica al fichero authorized_keys remoto copiando id_rda_administrador.pub con con ese nombre mediante scp. Si existiera authorized_keys, añadiríamos el contenido de id_rsa_administrador.pub al fichero. En nuestro caso no existen el directorio y el fichero ya que hicimos nuevo el usuario administrador. La IP es la del host deb01, repetiremos con cada host o IP cada comando scp o ssh. Lo hacemos todo desde la maquina ubults00.

administrador@ubults00:~/.ssh$ ssh administrador@192.168.1.37 mkdir /home/administrador/.ssh
administrador@192.168.1.37's password: 
administrador@ubults00:~/.ssh$ ssh administrador@192.168.1.37 chmod 0700 /home/administrador/.ssh
administrador@192.168.1.37's password: 

administrador@ubults00:~/.ssh$ ls
id_rsa_administrador  id_rsa_administrador.pub

administrador@ubults00:~/.ssh$ scp id_rsa_administrador.pub administrador@192.168.1.37:/home/administrador/.ssh/authorized_keys
The authenticity of host '192.168.1.37 (192.168.1.37)' can't be established.
RSA key fingerprint is 81:01:19:77:26:40:a8:72:9c:48:b5:04:c8:8f:53:a9.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.37' (RSA) to the list of known hosts.
id_rsa_administrador.pub                                                                                                       100%  405     0.4KB/s   00:00

administrador@ubults00:~/.ssh$ ssh administrador@192.168.1.37 chmod 0600 /home/administrador/.ssh/authorized_keys
administrador@192.168.1.37's password:
administrador@ubults00:~/.ssh$ ssh administrador@192.168.1.37 ls -lah /home/administrador/.ssh/
administrador@192.168.1.37's password: 
total 16K
drwx------ 2 administrador administrador 4,0K 2010-05-04 20:29 .
drwxr-xr-x 7 administrador administrador 4,0K 2010-05-04 20:18 ..
-rw------- 1 administrador administrador  405 2010-05-04 20:29 authorized_keys
-rw-r--r-- 1 administrador administrador  442 2010-05-04 19:25 known_hosts

Hemos creado los directorios remotos en deb01 y demás máquinas y generado authorized_keys a partir de id_rsa.pub en cada máquina. Si quisiéramos añadir más llaves simplemente se añaden al archivo authorized_keys. También hemos puesto los permisos apropiados. Como vemos, después de crear el archivo ya solo pide la passphrase “password” al ejecutar la operación ssh. Esto es lo que evitaremos con ssh-agent.

Configurar el agente ssh

Para que solo se pida la primera vez la contraseña de la clave ssh y se mantenga en memoria durante la ejecución de las operaciones ssh debemos ejecutar ssh-agent. Para poder usarlo debemos ejecutar una terminal, como por ejemplo, bash con dicho agente.

administrador@ubults00:~/.ssh$ ssh-agent bash

Esto nos abre otra consola con unas variables de ssh inicializadas por el agente. Ahora añadimos la clave privada y ponemos la contraseña (si es que la pusimos).

administrador@ubults00:~/.ssh$ ssh-add id_rsa_administrador
Enter passphrase for id_rsa_administrador: 
Identity added: id_rsa_administrador (id_rsa_administrador)

Cuando ejecutemos ahora la sentencia

administrador@ubults00:~/.ssh$ ssh administrador@192.168.1.37 sudo aptitude update
Obj http://security.ubuntu.com lucid-security Release.gpg
Ign http://security.ubuntu.com/ubuntu/ lucid-security/main Translation-es
Ign http://security.ubuntu.com/ubuntu/ lucid-security/restricted Translation-es
Ign http://security.ubuntu.com/ubuntu/ lucid-security/universe Translation-es
Ign http://security.ubuntu.com/ubuntu/ lucid-security/multiverse Translation-es

Vemos que no nos ha pedido ni contraseña ssh ni de sudo :-). Esta actualizando los repositorios de deb01 desde ubults00. Pero lo mejor es usarlo con un script y ver la potencia de lo que podemos hacer.

Un script de ejemplo

Supongamos que estamos con nuestro usuario administrador en ubuntults00 y creamos el siguiente script y lo llamamos actualizacion_servidores.sh.

administrador@ubults00:~$ vim actualizacion_servidores.sh

#!/bin/bash

USERSSH=administrador
HOSTS="deb01 deb02 deb03 deb04 deb05 deb06 deb07"


# Usamos el agente y añadimos la clave
eval `ssh-agent -s`
ssh-add /home/administrador/.ssh/id_rsa_administrador

# Actualizacion del Host base

echo "****************** $HOSTNAME *************************"
sudo aptitude update
sudo aptitude safe-upgrade
echo "$HOSTNAME: Actualizado."


# Actualizacion de los demas hosts

for DEST in $HOSTS
do
        if ping -c 3 $DEST > /dev/null
                then
                        echo "*************** $DEST **********************"
                        ssh $USERSSH@$DEST sudo aptitude update
                        ssh $USERSSH@$DEST sudo aptitude safe-upgrade
                        echo "$DEST: Actualizado."
                else
                        echo "[WARNING]: No se puede actualizar $DEST. No se encuentra."
        fi
done

# Cerramos el agente
ssh-agent -k
exit 0

Guardamos y le damos permisos de ejecución.

Cuando ejecutemos el script se actualizará nuestro sistema ubults00 y todos los hosts (deb01, deb02,...) que tengamos en la variable HOSTS pidiendo solamente la contraseña de la clave privada al ejecutar ssh_add. Si no le pusimos contraseña simplemente actualizara todos sin pedir contraseñas de nada.

Si no usaramos ssh-agent, cada vez que ejecutara la actualizacion en un host pediria la contraseña del usuario ssh y despues la contraseña de sudo para aptitude update y despues lo mismo para aptitude safe upgrade y despues todo esto lo mismo pero para el segundo hosts.

De esta manera podemos automatizar tareas cifradas y como root sin contraseñas.

Vemos la salida del script resumida:

administrador@ubults00:~$ ./actualizacion_servidores.sh
Agent pid 10501
Enter passphrase for /home/administrador/.ssh/id_rsa_administrador: 
Identity added: /home/administrador/.ssh/id_rsa_administrador (/home/administrador/.ssh/id_rsa_administrador)
****************** ubults00 *************************
Obj http://archive.canonical.com lucid Release.gpg
Ign http://archive.canonical.com/ubuntu/ lucid/partner Translation-es                                                          
...
Obj http://archive.ubuntu.com lucid-backports/universe Sources
Obj http://archive.ubuntu.com lucid-backports/multiverse Sources
Leyendo lista de paquetes... Hecho

Leyendo lista de paquetes... Hecho
...
No se instalará, actualizará o eliminará ningún paquete.
0 paquetes actualizados, 0 nuevos instalados, 0 para eliminar y 0 sin actualizar.
...
Leyendo la información de estado extendido      
Inicializando el estado de los paquetes... Hecho

ubults00: Actualizado.
*************** deb01 **********************
Obj http://security.ubuntu.com lucid-security Release.gpg
Ign http://security.ubuntu.com/ubuntu/ lucid-security/main Translation-es
...
Obj http://es.archive.ubuntu.com lucid-updates/multiverse Sources
Leyendo lista de paquetes...
Leyendo lista de paquetes...
Creando árbol de dependencias...
...
No se instalará, actualizará o eliminará ningún paquete.
0 paquetes actualizados, 0 nuevos instalados, 0 para eliminar y 0 sin actualizar.
...
Inicializando el estado de los paquetes...
deb01: Actualizado.
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 10501 killed;

Tachán!! Solo una contraseña y todos actualizados de forma segura. Espero que os sea de utilidad.
Related Posts with Thumbnails