configurar sftp



Cada vez que me toca configurar un sftp me toca buscar la forma como se hace, pero me encontré este excelente articulo, en este link http://itfreekzone.blogspot.com/2011/03/automatizacion-de-transferencias-por.html , y transcribo aquí el documento tal cual lo publico el autor mas con ánimo de tenerlo a la mano cuando lo necesite, que cualquier otra cosa, lo único que le agregaría el manejo de puertos, que para mi es cosa de todos los días, pues les ha dato a todos proveedores donde tengo alojados mis sistemas de cambiar el bendito puerto 22 por cualquier otra, generandome no pocos quebraderos de cabeza en diferentes circunstancias ("doctores tiene la santa madre iglesia").
la opción con puerto quedaría:
sftp -o Port=xxxx usr@host :file
Por lo demás todo igual, excelente artículo.


Por otra parte en este enlace
http://www.jcraft.com/jsch/examples/
Está el desarrollo para empotrar el manejo de sftp directamente en código java nativo con las librerias jcraft, aunque aún vengo haciendo pruebas me parece una opción alternativa válida , porque no tengo que hacer llamadas alsistema operativo lo cual no deja de ser un inconveniente en algunos casos.


 -------------------------------------------------------------------------------------------------------------------------
Automatización de transferencias por SFTP
 
Ante la necesidad de transferir archivos entre servidores de forma automatizada (sin intervención humana) recordé la excelente opción que otorga openSSH en su suite de herramientas: autenticación mediante clave pública/privada.
Dado que en un script es bastante feo lograr la interacción requerida por SFTP para autenticar un usuario (comportamiento default), contar con esta opción es extremadamente útil. Sí, no es imposible realizar la autenticación de forma interactiva, algo que está muy bien explicado en varias páginas e hice en un script de backup hace un par de años, pero es mucho más elegante usar la otra opción.

La idea de este artículo es explicar en pocos pasos cómo configurar tanto el cliente como el servidor SSH para utilizar autenticación de clave pública/privada. Además les mostraré cómo escribir un script que, utilizando esta autenticación, sirve para enviar archivos de forma automática.
Como si esto fuera poco (?!), también les mostraré como escribir un script que utilice autenticación interactiva, a través de la herramienta expect. Todo claro?, entonces "a darle átomos".


Generación del par de claves pública/privada

Como la autenticación será a través de estas claves, necesitaremos generar un par por cada usuario que utilicemos. La generación es muy simple, gracias a la herramienta ssh-keygen (si suena a generador de seriales para crackear aplicaciones). Las claves se pueden generar en cualquier máquina, no necesariamente el servidor o el cliente. El comando a ejecutar es:
$ ssh-keygen -f id_rsa -t rsa
donde:
-f especifica el nombre del archivo. Se generan dos archivos, la clave privada con el nombre que pasamos en el parámetro, y la pública con el nombre concatenado a .pub
-t especifica el algoritmo que deriva las claves (puede ser RSA o DSA, lo más común es usar RSA, aunque DSA es más seguro).
Ejemplo:
$ ssh-keygen -f id_rsa -t rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
68:82:cb:67:8d:b1:4c:e1:3c:da:22:c0:c3:22:48:c2 demasiadovivo@192.168.1.1
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|.                |
|.E  .            |
|*  + . .         |
|=+. B o S        |
|+..* O           |
|. = B .          |
| . +             |
|                 |
+-----------------+
Cuando intentemos generar las claves, el programa preguntará si deseamos asignarle un passphrase para proteger la clave privada. En este caso hay que dar enter porque si asignamos una passphrase, cada vez que deseemos autenticar un cliente, tendremos que poner dicha passphrase a mano, para desbloquer la clave privada... esto no serviría a nuestros propósitos de utilizar un script automático...

Del par generado, utilizaremos la clave pública en el servidor (id_rsa.pub en el ejemplo) y la privada en el cliente (id_rsa).


Configuración del servidor SSH/SFTP

En el servidor lo primero que tenemos que hacer es habilitar las opciones que permiten la autenticación con clave pública/privada, es decir, editando el archivo /etc/ssh/sshd_config (o /etc/sshd_config en otras distros):
RSAAuthentication yes
PubkeyAuthentication yes
Luego debemos copiar la clave pública del cliente en el archivo de claves autorizadas para ese usuario /home/usuario/.ssh/authorized_keys:
cat id_rsa.pub >> /home/usuario/.ssh/authorized_keys

Conexión desde el cliente

En el cliente tenemos dos alternativas: pasar la clave privada como parámetro de la llamada sftp, o copiar la clave privada en /home/usuario/.ssh/. En el segundo caso, al intentar loguearnos en el servidor remoto, sftp utilizará por default la clave que encuentre en el directorio ssh del home, es decir, podemos ejecutar:
sftp <usuario>@<hostname>
por ej: sftp demasiadovivo@192.168.1.2
Si necesitamos pasar la clave por parámetro (algo en muchos casos necesario porque el usuario que ejecuta el script puede no tener home), debemos ejecutar el siguiente comando:
sftp -o "IdentityFile=<clave-privada>" <nombre-usuario>@<hostname>
por ej: sftp "IdentityFile=/datos/id_rsa" demasiadovivo@192.168.1.2
Me costó bastante encontrar la forma de armar este último comando, es necesario leer bien el manual de ssh_config =S


Automatizar copiado de archivos

Como les comenté, la razón por la cual necesitaba lo anterior es para automatizar el envío de archivos de un servidor a otro. Una vez que tenemos la configuración necesaria, en el servidor1 o servidor cliente del servidor2, podemos colocar el siguiente script:
#!/bin/bash

CMDFILE="sftp-commands"

echo "put <path-archivo>
bye" > $CMDFILE
sftp -o "IdentityFile=<clave-privada>" -b $CMDFILE <nombre-usuario>@<hostname>
rm $CMDFILE
Como pueden observar, el script es muy simple. Lo que hace es usar sftp en modo batch (-b $CMDFILE) para poder enviar los comandos de forma no-interactiva, ya que en el comportamiento default sftp espera recibir de la standar input los comandos a ejecutar en el servidor.
En resúmen, crea un archivo temporal cuyo nombre es sftp-commands, en el cual coloca los comandos a ejecutar (por ejemplo, el put de un archivo). Luego llama a sftp utilizando autenticación de clave pública/privada y el modo batch, donde le pasa el archivo recién creado como input. Finalmente borra el archivo temporal.


Automatización, opción 2

El segundo script que les quería mostrar es cómo hacer lo anterior, pero con autenticación interactiva, algo un poco más sucio, pero igualmente útil:
#!/usr/bin/expect

spawn sftp <usuario>@<hostname>
expect "password:"
sleep 3
send "<mi-contraseña>\r";
expect ">"
send "put <path-archivo>\r"
expect ">"
send "bye\r"
Como el script es interactivo, si bien no hace falta que ingresemos manualmente ningún comando, éste se verá en la standar output, así que cuando llamemos al script es necesario redirigir la salida a /dev/null. Por ejemplo:

Nota: muy iportante tener en cuenta que el anterior script es un script expect , no un shell por lo tanto se debe tener instalado /usr/bin/expect
o instalar mediante yum install expect.
y ejecutar como

 /usr/bin/expect script
 o
$ ./sftp-command &>/dev/null
Este ultimo si la primera lilnea de script es reconocida por el shell.

para que los comandoa spawmn y expect sean reconocidos.


Comentarios

Entradas populares