SSH

De Astillas.net

SSH es el nombre de un protocolo y del programa que lo implementa para abrir un terminal de órdenes sobre una vía de comunicación segura.

Enlaces y referencias

Recetario

Conexión vía clave pública

Para permitir una conexión segura sin introducir contraseñas por teclado se pueden emplear una clave pública y usarla como parámetro en la conexión. Para esto es necesario seguir los siguientes pasos:

  1. Crear un par de claves en la máquina cliente
  2. Enviar la clave pública al usuario del servidor
  3. Emplear la clave privada en la máquina cliente para iniciar la conexión.

Creación de claves

Para crear un par de claves (pública y privada) sin contraseña y almacenadas en un archivo concreto utilizamos lo siguiente:

$ ssh-keygen -t rsa -f .ssh/remesas
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): [ENTER]
Enter same passphrase again: [ENTER]
Your identification has been saved in .ssh/remesas.
Your public key has been saved in .ssh/remesas.pub.
The key fingerprint is:
11:93:70:71:b6:02:92:a4:c4:b8:f2:48:d3:f9:33:bb ulises@helena
The key's randomart image is:
+--[ RSA 2048]----+
| o..o.o.=oo      |
|...... o.= .     |
| .o .   o .      |
|oo o     o       |
|oo. .   S        |
|. .  +           |
|      +          |
|     .           |
|     E.          |
+-----------------+
$ 

Y tendremos la clave pública en ~/.ssh/remesas.pub y la parte privada en ~/.ssh/remesas.

Enviar claves al servidor

Enviar las claves significa enviar únicamente la parte pública al servidor con el que queremos conectar y almacenarla allí en un sitio específico donde irá a comprobarlas en las siguientes conexiones. Lo mejor y lo habitual es emplear la orden ssh-copy-id pero si no disponemos de ella o preferimos ajustar más podemos hacerlo a mano:

$ scp ~/.ssh/remesas.pub usuario@servidor: 
usuario@servidor's password: [CONTRASEÑA]
remesas.pub                                     100%  395     0.4KB/s   00:00 
$ ssh usuario@servidor
usuario@servidor's password: [CONTRASEÑA]
[servidor] $ cat remesas.pub >> .ssh/authorized_keys 
[servidor] $ chmod 0600 .ssh/authorized_keys
[servidor] $ rm remesas.pub
[servidor] $ exit

Añadir comentarios a las claves

Cuando creamos la clave podemos añadir un breve texto empleando el parámetro -C:

$ ssh-keygen -t rsa -C "Envío de archivos de remesas" -f .ssh/dbserver
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in .ssh/dbserver.
Your public key has been saved in .ssh/dbserver.pub.
The key fingerprint is:
cc:2d:df:0d:ec:e2:e5:1b:5c:bc:f0:89:83:03:ea:89 Envío de archivos de remesas
The key's randomart image is:

para posteriormente poder echarle un vistazo simplemente mirando su contenido

$ cat .ssh/dbserver.pub 
ssh-rsa   
AAAAB3NzaC1yc2EAAAADAQABAAABAQDswP2/28g0 ...
...
...
sPoRovMp2HBgiVYgD Envío de archivos de remesas

Usar claves en la conexión

Pues nada más sencillo que el parámetro -i para indicar a ssh' que emplee los contenidos del archivo que le indiquemos como parte privada de la clave con la que crear la conexión:

$ ssh -i ~/.ssh/remesas usuario@servidor 
...
[servidor] $

Para predeterminar este uso podemos emplear el archivo de configuración $HOME/.ssh/config y crear una entrada concreta de esta forma:

Host         servidor 
Hostname     servidor.local
User         usuario
IdentityFile ~/.ssh/remesas

Empleando multiplexado

El mecanismo de multiplexado de SSH permite acelerar las nuevas conexiones con un destino. Para ello la primera conexión TCP con el sitio se emplea como maestro y las siguientes comparte la conexión ya abierta por él.

La configuración es bastante flexible. Añadiendo al archivo ~/.ssh/config las siguientes estrofas

 Host *
 ControlMaster auto
 ControlPath ~/.ssh/master-%r@%h:%p

permiten en cualquier momento restringirlo para destinos de red cuyo servicio SSH no tenga soporte de multiplexado.

Controlando el proceso maestro

Para controlar el proceso maestro de conexiones se utiliza el parámetro -O del programa ssh:

check
verifica que la conexión maestra esté activa
forward
solicita una redirección de puertos sin ejecutar ninguna orden remota
cancel
cancela una redirección de puertos
exit
pide al proceso maestro que termine su ejecución
stop
pide al proceso maestro que no acepte nuevas conexiones multiplexadas

Conexión persistente

Junto al anterior se puede utilizar el parámetro ControlPersist para mantener la conexión maestra abierta en segundo plano esperando a futuras conexiones cliente.


  ControlPersist yes|no|time
yes
El control maestro permanecerá abierto en segundo plano indefinidamente hasta que el proceso sea eliminado, bien empleando kill, bien utilizando el parámetro de control correspondiente.
time
Si se especifica un periodo de tiempo la conexión maestra terminará cuando transcurra dicho periodo sin conexiones cliente.

Ejecución silenciosa

Para ejecutar órdenes en sistemas remotos de forma silenciosa podemos emplear:

$ ssh -q -o "ConnectTimeout=4" -i ~/.ssh/identity usuario@host orden

Siendo los parámetros utilizados:

  • -q: suprime la mayor parte de los avisos y diagnósticos.
  • -o: Define una opción de configuración para la que no existe un parámetro. En este caso fija en cuatro segundos el tiempo límite para conectar.
  • -i: indica que se emplee una clave privada (como identidad) para autentificarse en el servidor remoto.

Envío de variables de entorno

Cuando se crea una conexión remota ssh permite enviar variables de entorno desde el sistema que inicia la conexión hasta el sistema que la acepta. En éste último es necesario indicar el nombre de aquellas variables que aceptará pasar a la sesión nueva empleando el parámetro AcceptEnv en el archivo /etc/ssh/sshd_config.

 # Variables a aceptar 
 AcceptEnv  MYVAR VAR_*

En el sistema desde el que se origina la conexión se debe indicar qué variables leer y enviar a la nueva sesión:

 $ export MYVAR="lista de valores que quiero pasar" 
 $ ssh -o SendEnv=MYVAR victor@remote

Ejecución de múltiples órdenes

Para ejecutar varias órdenes en una única conexión es posible invocar un shell tras conectarse y leer órdenes en el sistema local empleando un operador bash de fin de datos:

$ ssh user@remote /bin/bash <<EOF 
mkdir $HOME/tmp 
touch $HOME/tmp/i_was_here
EOF
$ 

ssh-agent

El agente SSH es un programa que guarda las claves privadas empleadas en la autentificación por clave pública (RSA,DSA). La idea es que se ejecute al inicio de la sessión (gráfica o no) y que todas las otras ventanas o procesos desciendan de él. De esta forma y mediante la herencia del entorno se podrá localizar al agente y usarlo automáticamente para autentificarnos en otras máquinas vía SSH.

ssh-askpass

Este programa permite solicitar una contraseña de acceso vía X11 que después envía a su salida estándar para ser empleada por un tercero.

En el caso de SSH se debe definir la variable de entorno SSH_ASKPASS con la ruta de este programa y ejecutar ssh sin un terminal de control y con la variable de entorno DISPLAY definida.


Creación de túneles

Accediendo a un servidor interno

Creando un túnel hacia un servidor interno

Según he dibujado en el gráfico el problema es acceder desde la máquina A a una máquina interna de una red llamada C -que lógicamente no dispone de una IP pública- empleando para hacerlo un puente con la máquina B porque es la que sí tiene una IP pública. En este caso además, queremos que la conexión final también sea al puerto SSH, el 22, aunque podríamos hacerlo con cualquier otro puerto, siempre que sea posible dicha conexión entre B y C.

Los parámetros a emplear son:

[A] $ ssh -P -N -L 33333:C:22 victor@B &
[A] $ telnet localhost 33333
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
...

Y lo que estamos consiguiendo con ésto es la siguiente secuencia de hechos:

  1. La máquina A se conecta al servidor remoto B empleando el puerto 22 habitual en las conexiones SSH.
  2. A se pone a la escucha en el puerto local 33333 y espera recibir datos.
  3. El servidor B abre una conexión con la máquina C (a la que tiene acceso directo) en el puerto 22 y espera datos de A.
  4. Cualquier paquete que la máquina A reciba en el puerto 33333 lo transmite a la máquina B que a su vez lo reenvía a C y viceversa: cualquier cosa recibida desde la conexión que tiene B con C es enviado de vuelta a la máquina A.

Usando SSH como proxy para navegar

SSH dispone de la opción -D que permite emplearlo como servidor proxy y saltarse así las restricciones que pueda tener la red a la que estemos conectados.

Basta con abrir el túnel con los parámetros adecuados

$ ssh -N -D 1080 user@remote
user@remote's password: 

y configurar el navegador para que utilice como proxy uno SOCKS de nivel 5.

Servicio sftp

El servicio sftp viene incluido de serie en el servidor sshd y para activarlo es necesario añadir una estrofa en el archivo de configuración /etc/ssh/sshd_config.

AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server -u 0002

UsePAM yes
Match Group www-data
        ChrootDirectory /chroot
        AllowTCPForwarding no
        X11Forwarding no
        ForceCommand internal-sftp

Lo anterior establece, además, que el grupo www-data verá sus conexiones contenidas bajo una jaula en el directorio /chroot.