Conexiones seguras con SSH

SSH es un protocolo de comunicaciones que proporciona seguridad criptográfica cuando nos conectamos a un servidor para iniciar una sesión o transfereir archivos por SFTP o SCP.

Los comandos SSH, SFTP y SCP utilizan el mismo puerto de comunicaciones, que es el 22.

De hecho, SSH se ha convertido en el estándar de conexión a cualquier servidor UNIX, precisamente, para que los hackers no puedan espiar los datos que enviamos a los servidores a los que nos conectamos, como nuestro usuario y contraseña, por ejemplo.

Antiguamente, nos conectábamos a los servidores mediante telnet o relogin, por ejemplo, pero estos protocolos no estaban cifrados y, por lo tanto, eran vulnerables a un ataque.

En Linux, el demonio SSH se arranca con el boot del sistema y está configurado como servicio.

Ejemplo en Centos 7:

# ps -ef |grep ssh |grep -v grep
root 965 1 0 Sep23 ? 00:00:17 /usr/sbin/sshd -D
root 30020 965 0 10:18 ? 00:00:00 sshd: centos [priv]
centos 30022 30020 0 10:18 ? 00:00:00 sshd: [email protected]/0
# systemctl list-unit-files |grep -i ssh
sshd-keygen.service static
sshd.service enabled
[email protected] static
sshd.socket disabled
#

Si el servicio SSH está arrancado y disponemos de un usuario y contraseña, podremos utilizar un cliente SSH para conectarnos al servidor o utilizar el comando SSH.

# ssh 192.168.1.2
[email protected]'s password: 
#

Creación de una relación de confianza SSH entre dos servidores

A los administradores de sistemas y aplicaciones les puede ser muy útil conectarse por SSH a un servidor remoto sin que éste pida usuario y contraseña.

Para ello podemos crear una relación de confianza entre un usuario y servidor origen y un usuario y servidor destino.

Lo primero que tenemos que hacer es crear un fichero de intercambio de claves:

[[email protected] ~]$ ssh-keygen -t rsa Generating public/private rsa key pair. 
Enter file in which to save the key (/home/usuario1/.ssh/id_rsa): 
Created directory '/home/usuario1/.ssh'. 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/usuario1/.ssh/id_rsa. 
Your public key has been saved in /home/usuario1/.ssh/id_rsa.pub. 
The key fingerprint is: 
1f:2a:14:34:4c:fb:22:37:c4:45:79:1f:d6:6f:c3:11 [email protected] The key's randomart image is: 
+--[ RSA 2048]----+ 
| o.. | 
| o +.. | 
| . + .o | 
| . E .o | 
| =S.+ . | 
| oo+o o | 
| . .+o . | 
| o.... | 
| .oo. | 
+-----------------+ 
[[email protected] ~]$

Con este comando habremos generado el fichero de clave pública y el de clave privada.

[[email protected] .ssh]$ ls -la 
total 12 drwx------ 2 usuario1 usuario1 36 nov 25 19:23 . drwx------ 8 usuario1 usuario1 4096 nov 25 19:23 .. -rw------- 1 usuario1 usuario1 1679 nov 25 19:23 id_rsa 
-rw-r--r-- 1 usuario1 usuario1 399 nov 25 19:23 id_rsa.pub 
[[email protected] .ssh]$

El contenido del fichero de la clave pública lo añadiremos al fichero $HOME/.ssh/authorized_keys del usuario y servidor destino. Lo podemos copiar y pegar, directamente o utilizar el comando ssh-copy-id de la siguiente manera:

ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

Una vez creada la relación de confianza ya podemos entrar al servidor de destino sin que nos pida contraseña. Por ejemplo:

[[email protected] .ssh]$ ssh [email protected]
[[email protected] .ssh]$

Evitar que SSH pregunte por la autenticidad del servidor

La primera vez que establecemos una conexión SSH contra un servidor remoto, SSH nos avisa de que la autenticidad del servidor todavía no ha sido establecida:

-bash-4.1$ ssh lremdot1
The authenticity of host 'lremdot1 (10.49.0.186)' can't be established.
RSA key fingerprint is 7d:56:4e:b0:8f:42:4d:01:40:0b:f0:67:10:82:8b:46.
Are you sure you want to continue connecting (yes/no)?

Para evitar que SSH nos haga esta pregunta, algo que viene bien cuando administramos cientos de servidores y tenemos playbooks con Ansible para administrarlos, tenemos que configurar el siguiente fichero:

[[email protected] .ssh]# pwd
/root/.ssh
[[email protected] .ssh]# cat config
Host *
   StrictHostKeyChecking no
   UserKnownHostsFile=/dev/null
[[email protected] .ssh]#

Copiar ficheros por SCP a un servidor remoto

El comando scp copia ficheros o directorios completos de manera recursiva de un servidor origen a un servidor y path destinos de manera completamente cifrada. La sintaxis es muy sencilla:

# scp -p vgdisplay.txt servidor2:$PWD
vgdisplay.txt 100% 16KB 
16.3KB/s 00:00 
#

Exportar una variable de entorno por SSH

Es posible que necesitemos exportar el valor de una variable al servidor remoto para que pueda funcionar correctamente la ejecución de un script. Lo haremos de la siguiente manera:

ssh remote_server -n “export PATH=$PATH:/scripts; mi_script.sh”

Creación de un túnel SSH

Los túneles SSH se utilizan para conectarnos a una IP y un puerto remotos a los que no tenemos acceso directo pero sí mediante un servidor intermedio.

Hace tiempo creé el siguiente manual para un equipo de aplicaciones de mi empresa que me servirá:

Escenario

  • Queremos acceder desde nuestro PC local hacia una IP y puerto remota a la que no tenemos acceso directamente.
  • Servidor destino:
    • caifor.es
    • IP fija del servidor destino: 172.23.66.42
    • IP NAT del servidor destino, al que solamente tenemos acceso desde la estación de salto sshgreiemea01.omc.hp.com: 29.80.0.22
    • IP virtual del servicio al que realmente queremos acceder (ubicada en el servidor secaiasp05): 172.23.66.55:7009.
    • Desde la estación de salto no hay conexión directa a la IP y puerto del servicio. Solamente tenemos conexión SSH.

Creación del primer túnel

  • Nos conectamos por SSH a la estación de salto.
  • Desde la estación de salto nos conectamos al servidor de destino por SSH, pero redirigimos el puerto del servicio (172.23.66.55:7009) al puerto local de la estación de salto 1234.

-bash-3.2$ netstat -an |grep 1234
-bash-3.2$ ssh -L 1234:172.23.66.55:7009 secaiasp05.caifor.es
Password:

  • Si volvemos a entrar en la estación de salto, podremos comprobar que ahora hay escuchando el puerto 1234.
-bash-3.2$ netstat -an |grep 1234
tcp        0      0 127.0.0.1:1234              0.0.0.0:*                   LISTEN
tcp        0      0 ::1:1234                    :::*                        LISTEN
-bash-3.2$

Creación del segundo túnel

Como desde nuestro PC local no tenemos acceso al puerto 1234 de la estación de salto, tenemos que crear un segundo túnel. Lo haremos con nuestro cliente de SSH que utilizamos actualmente.

En este ejemplo, abriremos el puerto 1234 en nuestro PC local, para que se conecte al puerto 1234 de la estación de salto (que está redirigido a la IP y puerto del servicio al que queremos acceder 172.23.66.55:7009).

Lo haremos de la siguiente manera. En este caso, utilizo el cliente de ssh SecureCRT.

A continuación, abriremos nuestro navegador local para acceder al servicio mediante la URL: http://localhost:1234/console (en realidad, el servicio está sirviendo en el servidor mediante la URL http://172.23.66.55:7009/console).

Túnel SSH con Putty

Si usamos Putty, uno de los programas más utilizados para conexiones SSH, en vez de SecureCrt, crearemos el túnel desde el menú «Tunnels», tal y como muestro en la siguiente captura de pantalla:

Creacion de un Tunel SSH con putty

Túnel SSH con Moba XTerm

Moba XTerm es otro de los clientes SSH más utilizados. El mismo túnel que hemos creado previamente con Putty, lo haríamos de la siguiente manera con Moba XTerm:

Túnel SSH con Moba XTerm
Arrancar el tunel SSH creado con Moba XTerm

Conexiones SFTP enjauladas

Cuando configuramos un servicio SFTP para transferir archivos de manera segura, es conveniente que el usuario externo que se conecta únicamente pueda ver el contenido del directorio donde están los datos que queremos que vea y nunca los directorios del resto del sistema.

Por ejemplo, podemos enjaular una conexión SFTP en el directorio /sftp y el usuario no podrá ir más atrás. Por ejemplo, no podrá ir a «/» o a «/opt».

Mejor vemos con un ejemplo cómo enjaular usuarios por SFTP:

  • Creamos el usuario que vamos a enjaular:
# groupadd -g 60000 sftpusers
# useradd -c "chrooted SFTP user" -s /bin/false -G sftpusers -u 50016 sftpuser
# id sftpuser
uid=50016(sftpuser) gid=50016(sftpuser) groups=50016(sftpuser),60000(sftpusers)
#

A modo de recordatorio, en caso de que te equivoques a la hora de crear el usuario o el grupo, siempre puedes modificarlos con los comandos usermod groupmod, respectivamente.

  • Habilitamos la shell de SFTP:
# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/tcsh
/bin/csh
/bin/dash
/bin/mksh
/usr/libexec/openssh/sftp-server
/bin/false
#
  • Configuramos los permisos correspondientes en el directorio /sftp:
# chown root:root /sftp
# chown sftpuser:sftpusers /sftp/sftpuser
#
  • Configuramos las siguientes directivas el fichero /etc/ssh/sshd_config:
UsePAM yes 
UsePrivilegeSeparation yes 
StrictModes yes 
PermitEmptyPasswords no 
# change default 
# Subsystem sftp /usr/libexec/openssh/sftp-server 
Subsystem sftp internal-sftp 
#Enjaulamiento del usuario sftpuser en /sftp
Match User sftpuser
ChrootDirectory /sftp
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
  • Reiniciamos el servicio ssh (service sshd restart o systemctl restart sshd).
  • Nos conectamos por SFTP:
$ sftp [email protected]
Connecting to testserver...
[email protected]'s password: 
sftp> cd /
sftp> ls -la
drwxr-xr-x 4 0 0 1024 Feb 11 07:50 .
drwxr-xr-x 4 0 0 1024 Feb 11 07:50 ..
drwx------ 2 0 0 12288 Feb 11 07:34 lost+found
drwxr-xr-x 2 50016 60000 1024 Feb 11 07:50 sftpuser
sftp>

Como vemos, el directorio raíz es /sftp y no podemos ir más atrás.

Puede que te interese saber cómo crear una clave informática en Amazon AWS IAM, que nos servirá para la conexión por SSH a los servidores Linux del cloud de Amazon.

Conexión SFTP en modo Batch

Podemos ejecutar instrucciones por lotes por SFTP para enviar comandos SFTP en una línea de comandos:

  • Opción 1 – Los comandos SFTP los guardamos en un fichero de texto
[root]# cat mia.batch 
ls
[root]#

[root]# ./prueba_sftp.sh 217.125.40.69 55689 mia_sftp mia314987 mia.batch 
spawn /usr/bin/sftp -o BatchMode no -b mia.batch -o port=55689 [email protected]
[email protected]'s password: 
sftp> ls
IN_DES    IN_PROD   OUT_DES   OUT_PROD  
[root]#
  • Opción 2 – Los comandos SFTP son introducidos en una sola línea de comandos:
[root]# sftp -oBatchMode=no -b - lhpilox01 << END
> lcd /var/opt/OV/conf/OpC
> get /planific/bin/admsys/menu_post_provisioning/menu/aprov/OVO/UXMONperf_PRO.cfg
> END
sftp> lcd /var/opt/OV/conf/OpC
sftp> get /planific/bin/admsys/menu_post_provisioning/menu/aprov/OVO/UXMONperf_PRO.cfg
Fetching /planific/bin/admsys/menu_post_provisioning/menu/aprov/OVO/UXMONperf_PRO.cfg to UXMONperf_PRO.cfg
[root]#

¿Te ha gustado? ¡Compártelo!

Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Share on telegram
Share on email

Deja un comentario

Tal vez también te gustaría leer...

Corrompiendo un filesystem ext4 a propósito

He tenido la necesidad de corromper un filesystem ext4 en un RedHat 6 a propósito para realizar un test de chequeo de filesystem. En mi caso, el filesystem era el /dev/sdb. Para corromperlo, he utilizado el siguiente comando: Rebajas Lenovo S145-15IWL – Ordenador portátil 15.6″… 549,99 EUR Comprar en Amazon Rebajas HP 15s-fq1013ns – Ordenador

Leer más »

GlusterFS – Filesystems con Alta Disponibilidad en Linux

Alguna vez os he hablado de ServiceGuard para montar entornos de alta disponibilidad robustos, que monten filesystems y levanten servicios, pero este es un software de pago que no quería utilizar para montar un único filesystem con alta disponibilidad. En su lugar, he elegido GlusterFS, que es opensource y con soporte de RedHat. Tabla de

Leer más »

Tutorial de Ansible

Recientemente me he estado mirando el funcionamiento de Ansible para automatizar tareas de manera masiva en servidores Linux remotos mediante esta aplicación. Hasta ahora utilizo otra pero como Ansible está cada vez más extendida y considero que vale la pena mirárselo. Más aún si RedHat está apostando por esta herramienta como estándar de automatización. Su

Leer más »

RHEL y Oracle RAC – Paquetes Dropped

En un entorno de dos servidores Linux RedHat 6.9 con un cluster de Oracle RAC, hemos detectado muchos paquetes dropped en las tarjetas de red (dropped: 311815750): El equipo de Oracle ejecuta un análisis del sistema (OSWatcher) donde se indica que debemos aumentar el valor de MTU de todos los nodos del cluster, y así

Leer más »

lun4194304 has a LUN larger than allowed by the host adapter

En un RedHat 7.6 he pedido una LUN para ampliar un filesystem. Esta es una tarea rutinaria de cualquier técnico de sistemas Linux, si embargo, hoy me he encontrado con que la LUN estaba asignada al servidor pero no la veía. En el log del sistema operativo (/var/log/messages) aparecía el siguiente mensaje: Es decir, que

Leer más »

root: fork failed: Cannot allocate memory

En uno de los servidores que administro me ha ocurrido que no podía entrar con SSH ni ejecutar procesos en remoto a través de un software que tiene un agente instalado, etc. dando el error root: fork failed: Cannot allocate memory. Sin embargo, la aplicación del usuario no se estaba viendo afectada. Toshiba Canvio Basics

Leer más »