Tutorial de SSH – ¿Qué es y cómo se configura? Conexiones seguras en Linux

¿Qué es SSH?

SSH o Secure Shell, es un protocolo de comunicaciones que proporciona seguridad criptográfica, mediante el intercambio de claves pública y privada, 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.

El proceso de autenticación es el paso final antes de que se le otorgue acceso a un usuario. De manera predeterminada, los usuarios se autentican con una contraseña, pero es posible deshabilitar la autenticación de contraseña. El usuario ingresa un nombre de usuario y una contraseña y las credenciales pasan a través de un túnel cifrado simétricamente. Aunque las contraseñas están encriptadas, no son un método de autenticación seguro porque los bots pueden forzar fácilmente a los brutos. Una mejor manera de asegurar la conexión es usar pares de claves SSH.

El protocolo SSH proporciona un fuerte cifrado y protección de integridad. Los datos se cifran utilizando algoritmos de cifrado fuertes estándar de la industria. También tiene mensajes para garantizar que sean auténticos. Un HMAC es un tipo de criptografía que garantiza que los datos no sean manipulados por un tercero. El software SSH maneja la generación de claves, compartir claves públicas, emitir desafíos y controlar el acceso.

Podemos invocar SSH a través de la línea de comandos (comando ssh) o a través de programas especializados que aportan entorno gráfico y una serie de herramientas adicionales.

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

En Linux, el demonio (daemon) 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: centos@pts/0
# systemctl list-unit-files |grep -i ssh
sshd-keygen.service static
sshd.service enabled
sshd@.service 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
root@testserver's password: 
#

¿Cómo habilitar el servicio de SSH?

En distribuciones de Linux basadas en RedHat, habilitaremos y arrancaremos el servicio de SSH de la siguiente manera:

systemctl enable sshd
systemctl start sshd

Conexión SSH con Timeout

Establecer un timeout a una conexión SSH es una buena práctica cuando creamos scripts o jobs de ansible automatizados que se van a ejecutar en cientos de servidores. Si no establecemos un timeout, el script se quedará colgado cuando en uno de los servidores falle la conexión y el proceso de SSH se quede a la espera de respuesta indefinidamente.

Para establecer un timout en una conexión SSH, lo haremos de la siguiente manera:

[root@server1 ~]# ssh -o ConnectTimeout=10 HostnameInventado
ssh: connect to host hostnameinventado port 22: Connection timed out
[root@server1 ~]#

Creación de una relación de confianza SSH entre dos servidores para acceder sin contraseña

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:

[usuario1@noname00 ~]$ 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 usuario1@noname00 The key's randomart image is: 
+--[ RSA 2048]----+ 
| o.. | 
| o +.. | 
| . + .o | 
| . E .o | 
| =S.+ . | 
| oo+o o | 
| . .+o . | 
| o.... | 
| .oo. | 
+-----------------+ 
[usuario1@noname00 ~]$

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

[usuario1@noname00 .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 
[usuario1@noname00 .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 root@hostname

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

[usuario1@noname00 .ssh]$ ssh usuario2@test2
[usuario2@test2 .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:

[root@lhpilox01 .ssh]# pwd
/root/.ssh
[root@lhpilox01 .ssh]# cat config
Host *
   StrictHostKeyChecking no
   UserKnownHostsFile=/dev/null
[root@lhpilox01 .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:

  • Copia de ficheros: scp -p fichero usuario@servidor_remoto:PATH
  • Copia recursiva de directorios: scp -pr fichero usuario@servidor_remoto:PATH
# 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 en bash. 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.

securecrt
securecrt tunel

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

Probemos un túnel SSH con Moba Xterm al puerto 22 para conectarnos a un servidor final al que sólo podemos conectarnos a través de una estación de salto:

Tunel SSH al puerto 22 de un servidor remoto con Moba XTERM

La conexión SSH desde mi portátil a localhost:22 llega al servidor de destino:

Conexion SSH con un tunel creado con Moba Xterm

Evitar la desconexión de una sesión SSH en Linux

Es una buena práctica configurar reglas de firewalls para eliminar las conexiones «zombies», por ejemplo, cada 2h, ya que no sería normal establecer una sesión durante tanto tiempo sin que se envíe nada de tráfico. De esta manera, cuidamos de los recursos de red del entorno y liberamos los sockets que no están en uso.

Sin embargo, puede ser útil en algunos casos establecer un parámetro de Keep alive para enviar algo de tráfico cada cierto tiempo para que no se nos caiga la conexión. Esto lo podemos hacer tanto del lado del servidor SSH como del cliente.

Configuración del KeepAlive para conexiones SSH desde el cliente MoBaXTerm

Ejemplo de activación del keepAlive desde el cliente SSH Moba XTerm:

MovaXTerm KeepAlive SSH

Configuración de KeepAlive desde el servidor SSH en Linux

En cuanto a la configuración del servidor SSH, en Linux RedHat configuraremos los siguientes parámetros:

[root ~]# grep -i alive /etc/ssh/sshd_config
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 5
[root ~]#

Una vez configurados, reiniciaremos el servicio de SSH.

El parámetro ClientAliveInterval 60 se refiere a que se enviará tráfico cada 60 segundos para que no muera la sesión SSH.

Conexión de SSH a través de un proxy

Si queremos utilizar SSH detrás de un proxy, lo podremos hacer de la siguiente manera:

RHEL6

[root@server1 ~]# ssh -o ConnectTimeout=3 -o ProxyCommand='/usr/bin/nc -X connect -x 192.168.47.162:8080 %h %p' usuario@169.50.223.146
usuario@169.50.223.146's password:

[root@server1 ~]#


RHEL7

[root@server1 ~]# sftp -o "ProxyCommand nc --proxy 192.168.47.162:8080 %h %p" usuario@169.50.223.146
usuario@169.50.223.146's password:
Connected to 169.50.223.146.
sftp> ls -la
drwxr-xr-x    3 0        0            4096 Oct 18  2017 .
drwxr-xr-x    3 0        0            4096 Oct 18  2017 ..
drwxr-xr-x    5 1001     100          4096 Feb 22  2019 data
sftp>

En el ejemplo anterior, la IP y puerto del proxy son: 192.168.47.162:8080.

Permitir conexiones SSH con root solamente desde una IP origen

Si solamente queremos permitir el acceso con root desde una IP origen, editaremos el fichero /etc/ssh/sshd_config, añadiendo las siguientes directivas:

PermitRootLogin yes
AllowUsers root@10.48.0.29

Pero esta opción solamente va a permitir conexiones para el usuario root del servidor con IP 10.48.0.29. Así que no sería la opción correcta para la mayoría de los casos, ya que el resto de usuarios no se podrán conectar.

Si lo que queremos es que cualquier usuario pueda conectarse por SSH al servidor pero con root solamente desde una IP concreta, la solución pasa por configurar las siguientes directivas:

PermitRootLogin no

### Resto de directivas SSH ###

Match host 10.48.0.29
PermitRootLogin yes

Ejecutar un script local en un servidor remoto con SSHPASS

Pongamos que tengo un script en un servidor local que quiero que se ejecute en un servidor remoto en el que no existe este script:

# ll
total 4
-rwxr--r-- 1 hpddpers uxsup3 249 May 4 10:31 luns.sh
#

Para hacerlo, ejecutaré el siguiente comando:

# sshpass -p MiContraseñaSecreta -q root@la01wai0.7376.1286.ecs.hp.com "bash -s" -- < luns.sh 
la01wai0;/dev/sda;107.4;GB
la01wai0;/dev/sdb;53.7;GB
#

Como podemos observar, con sshpass, envío la contraseña con la que acceder en el servidor remoto y con < luns.sh especifico mi script local a ejecutar en el destino.

Acceso SFTP enviando la contraseña con SSHPASS

También podemos utilizar SSHPASS para acceder por SFTP con el usuario y la contraseña enviada por parámetros en la misma línea. Veamos un ejemplo:

[root@servidor1 ~]# sshpass -p test sftp -oBatchMode=no -b - test@localhost << !
> ls
> bye
> !
sftp> ls
sftp> bye
[root@servidor1 ~]# sshpass -p test sftp -oBatchMode=no -b - test@localhost << !
ls -la
bye
!

sftp> ls -la
drwx------    3 test     test         4096 Mar  6 08:05 .
drwxr-xr-x   33 root     root         4096 Mar  6 08:05 ..
-rw-r--r--    1 test     test           18 Feb 15  2017 .bash_logout
-rw-r--r--    1 test     test          176 Feb 15  2017 .bash_profile
-rw-r--r--    1 test     test          124 Feb 15  2017 .bashrc
-rw-r--r--    1 test     test          500 Nov 27  2014 .emacs
-rw-r--r--    1 test     test          124 Feb  5  2018 .mkshrc
drwxr-xr-x    4 test     test         4096 Nov 23  2017 .mozilla
sftp> bye
[root@servidor1 ~]#

El parámetro «-p test» indica la contraseña del usuario «test@localhost».

Y si queremos ejecutar un put por SFTP en una sola línea:

[root@servidor1 pced]# (echo ls; echo "put /interfases/tresoreria/CEPD/CEPD_08082019_050506.txt") | sshpass -p test sftp -oBatchMode=no -b - test@lgecgcx1.8799.1286.ecs.hp.com >> status.log
+---------------------------------------------------------------------+
|                                                                     |
|  Use of this network is restricted to authorized users only. User   |
|  activity may be monitored and/or recorded. Anyone using this       |
|  network expressly consents to such monitoring and/or recording.    |
|                                                                     |
|  BE ADVISED: if possible criminal activity is detected, these       |
|  records, along with certain personal information, may be provided  |
|  to law enforcement officials.                                      |
|                                                                     |
+---------------------------------------------------------------------+

[root@servidor1 pced]# cat status.log
sftp> ls
CEPD_08082019_050506.txt
sftp> put /interfases/tresoreria/CEPD/CEPD_08082019_050506.txt
Uploading /interfases/tresoreria/CEPD/CEPD_08082019_050506.txt to /home/test/CEPD_08082019_050506.txt
[root@servidor1 pced]#

Las ventajas de una VPN SSH

Si estás buscando una manera de conectar dos máquinas a través de Internet, es posible que desees usar una VPN SSH. Como hemos comentado anteriormente en este artículo, SSH es un protocolo de código abierto que permite asegurar las comunicaciones de la red encriptando los datos entre dos servidores.

La combinación de una VPN segura más el uso de SSH, hará que la conexión esté muy bien protegida ante ataques de piratas informáticos.

El túnel SSH se desarrolló por primera vez en 1995 y utilizó algoritmos de cifrado de última generación. Sin embargo, a medida que avanza la tecnología, los algoritmos originales se han vuelto anticuados. Por lo tanto, es importante verificar si la VPN SSH que utilizamos usa algoritmos más nuevos.

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 sftpuser@testserver
Connecting to testserver...
sftpuser@testserver'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 mia_sftp@217.125.40.69
mia_sftp@217.125.40.69'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]#

Modificación de la máscara por defecto de un SFTP enjaulado (umask)

Si nos interesa que un usuario que se conecta por SFTP deje los ficheros con unos permisos concretos, lo que tenemos que hacer es configurar la máscara de SFTP para ese usuario concreto.

Para ello, editaremos el fichero /etc/ssh/sshd_config y reiniciar el servicio de SSH. Veamos un ejemplo:

  • Configuramos el fichero sshd_config para el usuario «test»:
Match User test
#OpenSSH inferior a 5.4
ForceCommand internal-sftp -m 700
# OpenSSH igual o superior a 5.4
# ForceCommand internal-sftp -u 007
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

Importante: La directiva «ForceCommand internal-sftp -m 700» tiene que estar debajo de «Match User», sino, se ignora.

  • Reiniciamos el servicio de ssh con el comando service sshd restart en RedHat 6 o systemctl restart sshd en RedHat 7.
  • Subimos un fichero de test para comprobar que su máscara es la que hemos configurado:
[root@la07wai0 ssh]# sftp test@localhost
Connecting to localhost...
+---------------------------------------------------------------------+
|                                                                     |
|  Use of this network is restricted to authorized users only. User   |
|  activity may be monitored and/or recorded. Anyone using this       |
|  network expressly consents to such monitoring and/or recording.    |
|                                                                     |
|  BE ADVISED: if possible criminal activity is detected, these       |
|  records, along with certain personal information, may be provided  |
|  to law enforcement officials.                                      |
|                                                                     |
+---------------------------------------------------------------------+

test@localhost's password:
Permission denied, please try again.
test@localhost's password:
sftp> put /tmp/test.txt
Uploading /tmp/test.txt to /home/test/test.txt
/tmp/test.txt                                                                                                                                                   100%    0     0.0KB/s   00:00
sftp> ls -la
drwx------    2 test     test         4096 Feb 25 12:50 .
drwxr-xr-x   20 root     root         4096 Feb 25 12:46 ..
-rw-r--r--    1 test     test           18 Feb 15  2017 .bash_logout
-rw-r--r--    1 test     test          176 Feb 15  2017 .bash_profile
-rw-r--r--    1 test     test          124 Feb 15  2017 .bashrc
-rw-r--r--    1 test     test          500 Nov 27  2014 .emacs
-rw-r--r--    1 test     test          124 Oct 21  2016 .mkshrc
-rwx------    1 test     test            0 Feb 25 12:50 test.txt
sftp> exit

Como vemos, el fichero «test» tiene máscara rwx para el propietario del fichero y ningún permiso para el grupo y resto de usuarios.

Ataque de fuerza bruta por SSH

¿Qué es un ataque por fuerza bruta?

Esta mañana me he dado cuenta de que se estaba llenando el filesystem /var de un servidor Linux (SFTP público) y visto que el motivo era que había crecido mucho el fichero /var/log/secure.

En este fichero se guardan los accesos por SSH que se realizan al servidor, con qué usuario y desde qué IP, así que le he echado un vistazo y me he dado cuenta de que habían muchos accesos por segundo, desde diferentes IPs y con múltiples usuarios distintos para intentar acceder al servidor con cualquiera de ellos que funcione.

Obviamente, se trata de un ataque por fuerza bruta para entrar al servidor.

[root@server1 log]# grep "Invalid user" secure |head -20
Jan 30 11:45:38 server1 sshd[29355]: Invalid user kuyil from 37.59.58.142
Jan 30 11:45:41 server1 sshd[29361]: Invalid user aafreen from 104.236.124.45
Jan 30 11:45:42 server1 sshd[29367]: Invalid user sugita from 177.54.150.70
Jan 30 11:46:01 server1 sshd[29390]: Invalid user najma from 222.41.193.211
Jan 30 11:46:08 server1 sshd[29411]: Invalid user aprajit from 65.60.182.212
Jan 30 11:46:12 server1 sshd[29416]: Invalid user devabrata from 123.207.92.254
Jan 30 11:46:13 server1 sshd[29422]: Invalid user trilochana from 35.199.154.128
Jan 30 11:46:15 server1 sshd[29426]: Invalid user shaweta from 177.54.150.70
Jan 30 11:46:44 server1 sshd[29433]: Invalid user radhavallabh from 37.59.58.142
Jan 30 11:46:45 server1 sshd[29442]: Invalid user antonia from 124.156.99.213
Jan 30 11:46:47 server1 sshd[29448]: Invalid user kavana from 177.54.150.70
Jan 30 11:46:54 server1 sshd[29460]: Invalid user sourabhi from 104.236.124.45
Jan 30 11:47:08 server1 sshd[29516]: Invalid user thshin from 222.41.193.211
Jan 30 11:47:15 server1 sshd[29526]: Invalid user yatiraja from 157.230.30.229
Jan 30 11:47:19 server1 sshd[29530]: Invalid user havish from 177.54.150.70
Jan 30 11:47:29 server1 sshd[29535]: Invalid user saumyi from 65.60.182.212
Jan 30 11:47:31 server1 sshd[29547]: Invalid user ukti from 128.199.184.196
Jan 30 11:47:42 server1 sshd[29552]: Invalid user padminish from 109.75.216.201
Jan 30 11:47:45 server1 sshd[29556]: Invalid user kehar from 35.199.154.128
Jan 30 11:47:51 server1 sshd[29565]: Invalid user meenu from 177.54.150.70
[root@server1 log]#

¿Cómo protegerse de un ataque por fuerza bruta por SSH en Linux?

En primer lugar, los firewalls de comunicaciones deberían detectar este tipo de comportamiento. Es decir, si tenemos 60 intentos fallidos de login desde una misma IP origen y en pocos segundos, pues el propio firewall debería cortar las comunicaciones desde esta IP, pero está claro que en este caso no está configurada esta opción.

Como administrador de Linux, podemos realizar varias acciones:

  • Configurar el firewall de Linux (iptables/firewalld) para cortar el tráfico por IP origen. El problema es que este tipo de ataques suelen cambiar la IP origen cada poco tiempo.
  • Configurar el fichero /etc/hosts.deny para denegar el tráfico desde esas IPs. Ejemplo
[root@server1 ~]# cat /etc/hosts.deny |grep -v "#" |grep -v ^$
ALL: 144.121.28.206, 65.60.182.212, 222.41.193.211, 35.199.154.128, 124.156.99.213, 130.185.155.34, 92.242.240.17, 104.236.124.45, 37.59.58.142, 15.206.79.57, 179.222.97.194, 88.198.90.165, 213.32.23.58, 103.8.119.166, 177.54.150.70, 128.199.184.196, 5.30.101.76, 157.230.30.229, 195.69.222.166, 41.223.142.211, 188.131.218.217, 123.207.92.254, 45.136.108.85, 117.50.1.12, 109.75.216.201, 62.227.251.138, 223.95.81.159, 180.167.137.103, 92.63.194.90, 136.49.202.36, 118.98.43.121, 103.89.90.194
[root@server1 ~]#
  • Configurar la directiva «LoginGraceTime 30» en el fichero /etc/ssh/sshd_config, para esperar 30 segundos antes de que se cierre la pantalla de login.
  • Configurar la directiva «MaxAuthTries 2» para que SSH cierre la conexión si nos equivocamos dos veces con la contraseña.
  • No permitir el acceso directo como root al servidor. Directiva «PermitRootLogin no» del fichero de configuración de SSH.
  • No permitir el acceso con contraseña, si no con claves públicas y privadas.
  • Modificar el puerto de escucha de SSH. En este caso, sería un problema, ya que es un servicio de SFTP público. En cualquier caso, si lo quieres hacer, has de cambiar el puerto en el fichero de configuración de SSH (Directiva «Port 22»).
  • Instalar un producto como fail2ban, denyhosts, sshguard o sentry, para proteger este tipo de ataques por fuerza bruta.
  • Tener el sistema operativo y sus aplicaciones actualizadas con los últimos parches de seguridad.

¿Cómo hacer un ataque por fuerza bruta?

Cuando vemos tantos intentos de login por segundo, obviamente, no se trata de una persona que esté intentando entrar a un servidor de forma manual, si no que se utilizan robots que automatizan los accesos a través de una base de datos de usuarios y contraseñas.

Kali Linux es una distribución Linux que trae muchas herramientas de hacking preinstaladas, pero también podemos utilizar otras muchas como, por ejemplo, estas:

  • Cain y Abel
  • THC Hydra
  • Ncrack
  • John the Ripper
  • Hashcat
  • Aircrack-Ng
  • Ophcrack
  • L0phtcrack
  • SAMInside
  • Rainbow crack

¿Cuál es el objetivo de un ataque por fuerza bruta?

El objetivo no es otro que el de acceder a un servidor con el usuario administrador o un usuario sin privilegios que luego podríamos utilizar para adueñarnos del servidor si encontramos algún agujero de seguridad o lanzar algún proceso que no necesite ser administrador.

Las intenciones del atacante pueden ser múltiples:

  • El propio administrador de seguridad quiere probar su sistema.
  • Un hacker con malas intenciones busca secuestrar el servidor y pedir dinero.
  • Robar datos sensibles.
  • Minar criptomonedas.
  • Almacenar datos.
  • Tumbar el sistema informático de un servicio importante o de la competencia.

Pueden ser cientos.

Instalar el cliente SSH en Windows 10

Por defecto, la instalación de Windows 10 no incorpora ningún cliente SSH, pero lo podemos instalar fácilmente.

Para ello, iremos al menú de configuración del sistema y buscaremos el «botón» para añadir características opcionales.

Windows10 Optional features

Entre todas las aplicaciones disponibles a instalar, buscaremos OpenSSH Client y la instalaremos.

Windows10 OpenSSH Client
Windows10 OpenSSH Client Installing

Si abrimos la línea de comandos como administrador, ya podremos ejecutar el comando SSH.

Windows10 SSH

También disponemos de otros productos externos, como pueden ser putty o MobaXTerm, entre muchos otros para iniciar una sesión SSH en un servidor Linux remoto.

Configurar SSH para que utilice el doble factor

Configurar el servicio SSH en Linux para utilizar la autenticación de doble factor (2FA) puede mejorar significativamente la seguridad de tu sistema. Generalmente, esto se hace mediante la integración de un módulo PAM (Pluggable Authentication Module) con un método de 2FA, como Google Authenticator. Aquí te detallo los pasos:

1. Instalar Google Authenticator

Primero, instala el módulo PAM de Google Authenticator en tu servidor Linux:

sudo apt-get update
sudo apt-get install libpam-google-authenticator

Esta instrucción es para sistemas basados en Debian, como Ubuntu. Si estás usando un sistema basado en Red Hat, como CentOS, usa yum en lugar de apt-get.

2. Configurar Google Authenticator

Ejecuta el siguiente comando para configurar Google Authenticator para tu usuario:

google-authenticator

Responde a las preguntas que aparecen en pantalla. Esto generará un código QR que puedes escanear con la aplicación Google Authenticator en tu teléfono.

3. Modificar la Configuración de SSH

Abre el archivo de configuración de SSH:

sudo nano /etc/ssh/sshd_config

Asegúrate de que las siguientes líneas estén configuradas como se muestra (o modifícalas si es necesario):

ChallengeResponseAuthentication yes
PasswordAuthentication no
UsePAM yes

Esto habilita la autenticación basada en desafío-respuesta y deshabilita la autenticación solo con contraseña.

4. Configurar el Módulo PAM de SSH

Ahora, configura PAM para usar Google Authenticator. Edita el archivo PAM de SSH:

sudo nano /etc/pam.d/sshd

Agrega la siguiente línea al principio del archivo:

auth required pam_google_authenticator.so

5. Reiniciar el Servicio SSH

Después de realizar los cambios, reinicia el servicio SSH para aplicar la configuración:

sudo systemctl restart sshd

6. Prueba de Conexión

Ahora, cuando intentes conectarte a tu servidor mediante SSH, se te pedirá tu contraseña habitual y un código de verificación generado por la aplicación Google Authenticator en tu teléfono.

Consideraciones Adicionales

  • Backup de Códigos: Asegúrate de guardar los códigos de respaldo generados durante la configuración en un lugar seguro.
  • Usuarios Múltiples: Si tienes múltiples usuarios en el servidor, cada uno debe configurar Google Authenticator individualmente.
  • Permisos de Archivos: Verifica los permisos de los archivos de configuración para garantizar la seguridad.

La configuración de 2FA puede variar ligeramente dependiendo de la distribución de Linux y la versión de los paquetes. Si encuentras problemas, verifica la documentación específica de tu sistema.

Te puede interesar

COMPÁRTEME

Deja un comentario