SSH
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.
Sumario
Enlaces y referencias
- Ref: Sitio oficial del programa OpenSSH
- Ref: SSH Tunneling
- Ref: Using and limiting SSH keys by Juliet Kemp
- Ref: Quick-Tip: SSH Tunneling Made Easy
- Ref: 16 ultimate openssh hacks by Carla Schoder
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:
- Crear un par de claves en la máquina cliente
- Enviar la clave pública al usuario del servidor
- 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
- Ref: Speed Up Multiple SSH Connections to the Same Server
- Ref: OpenSSH/Cookbook/Multiplexing
- Ref: SSH: Tips And Tricks You Need
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
- Ref: How to set up ssh so you aren't asked for a password
- Ref: Pantallazos del programa con diferentes estilos
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
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:
- La máquina A se conecta al servidor remoto B empleando el puerto 22 habitual en las conexiones SSH.
- A se pone a la escucha en el puerto local 33333 y espera recibir datos.
- 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.
- 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.
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.
- Ref: Proxy Firefox through a SSH tunnel
- Ref: How to Create a SOCKS Proxy through an SSH Tunnel
- Ref: Proxy SOCKS con SSH: más fácil imposible
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.