El servicio SSH es, sin duda, el servicio más utilizado para realizar conexiones remotas a nuestros servidores. Es por esta razón que deberemos gestionar debidamente la seguridad de los mismos. OpenSSH nos permitirá también, entre otras opciones, enviar archivos a nuestros servidores o simplemente bajarnos un archivo desde nuestros servidores a nuestra máquina. Aunque sin duda, la principal ventaja que tenemos con OpenSSH es la de hacer login con nuestras claves SSH. No obstante, es frecuente encontrar organizaciones que no aprovechen nada o que lo aprovechen muy poco este recurso.

Antes de nada, empecemos por lo más básico. Algunas opciones que están por defecto.

1. El puerto de SSH en TCP es el 22 (por default). Esto es algo que podemos comprobar desde nuestro GNU/Linux con el siguiente comando.

cat /etc/services | grep "ssh"
ssh 22/tcp # SSH Remote Login Protocol

2. El servidor OpenSSH utiliza el archivo de configuración /etc/ssh/sshd_config. Y aquí en este punto es donde más confusión he encontrado ¿Por qué? Porque hay 2 archivos que, aunque son muy similares (sólo se distinguen en una letra), uno nos servirá para la configuración del cliente y otro para la configuración del servidor. Pero ¿Cómo podríamos saber esto?

  • Consultando el propio manual de OpenSSH. Aquí lo dejo. Observamos como claramente nos lo especifican:

ssh_config(5) — The client configuration file
sshd_config(5) — The daemon configuration file

Obtenido del propio manual de OpenSSH

Otra opción, aunque un poco más avanzada si se disponen de conocimientos de programación es:

  • Consultar el propio código del paquete. Esto, para la mayoría de usuarios que no estén acostumbrados a utilizar GNU/Linux les puede parecer algo raro o incluso muy complejo, mas no podemos olvidar que GNU/Linux y la gran mayoría de sus paquetes son software libre, lo que nos capacita para poder comprobar el código de cada paquete. Hacer esto es bastante sencillo.

apt-get source openssh (En nuestro caso openssh por ser el que estamos tratando)

Tras esto, si listamos nuestro directorio donde lo hayamos descargado (yo recomiendo crear uno personalizado para estas tareas como ~/sources.

hippi3c0w# pwd; ls -ltrah
/home/manu/sources
total 1,7M
-rw-r--r-- 1 root root 683 oct 21 2018 openssh_7.9p1.orig.tar.gz.asc
-rw-r--r-- 1 root root 1,5M oct 21 2018 openssh_7.9p1.orig.tar.gz
-rw-r--r-- 1 root root 3,1K abr 8 12:41 openssh_7.9p1-10.dsc
-rw-r--r-- 1 root root 169K abr 8 12:41 openssh_7.9p1-10.debian.tar.xz
drwxr-xr-x 24 manu manu 4,0K jul 31 17:21 ..
drwxr-xr-x 3 root root 4,0K jul 31 17:30 .
drwxr-xr-x 7 root root 12K jul 31 17:30 openssh-7.9p1
hippi3c0w#

Para nosotras lo importante será la carpeta del paquete, en este caso openssh-7.9p1. Así que busquemos cuáles son nuestros archivos de configuración.

hippi3c0w# cat openssh-7.9p1/Makefile.in| grep "sshd_config"
MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
CONFIGFILES_IN=sshd_config ssh_config moduli
-e 's|/etc/ssh/sshd_config|$(sysconfdir)/sshd_config|g' \
-$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
@if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \
$(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \
echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \
-rm -f $(DESTDIR)$(sysconfdir)/sshd_config
hippi3c0w#

No es muy complicado de entender. En primer lugar tenemos los MANPAGES que, en esencia, es la ayuda (el comando man [comando] para mostrar las opciones de otro comando que queramos ejecutar. ). Y en segundo lugar, tenemos los CONFIGFILES, que es aquí donde se especifica qué archivos(s) van a servir como archivos de configuración para servidor y cliente. Nos especifican ambos como ya hemos visto y explicado (CONFIGFILES_IN=sshd_config ssh_config).

Vamos a centrarnos fundamentalmente en 2 archivos para esta primera parte que consiste en analizar algunos archivos del paquete openSSH que hemos descargado en nuestro Debian 10 Buster, porque sí, nosotras somos fieles a Debian.

El primer archivo que vamos a analizar será el auth.c, donde tendremos, fundamentalmente lo principal a la hora de autenticarnos contra nuestro servidor. Por ejemplo, es posible que alguna vez hayamos visto que no nos deja acceder alegando que es problema de permisos. Pues bien, esto viene especificado en el segundo if dentro de ese bucle for que se utilizará para cada elemento.

También podemos encontrarnos que no nos dejen acceder porque simplemente, no se nos ha añadido a la lista de usuarios permitidos o directamente nos han denegado el acceso. Esto lo veremos más adelante dentro de este artículo y vendrá por las directivas AllowUsers y DenyUsers que, como se comprueba por el fragmento de código anterior, viene especificado su comportamiento y validación en los 2 ifs fundamentales y sus if anidados correspondientes.

Si además bajamos un poco más, veremos la función auth_log que será la responsable de completar nuestro /var/log/auth.log cuando hagamos nuestra conexión. Para esto utiliza un operador ternario con, obviamente, 3 opciones que son authenticated, accepted o failed. Un ejemplo que podríamos observar en nuestro log sería

Jul 30 13:03:19 Debian-99-stretch-64-minimal sudo[3741]: pam_ssh_agent_auth: Authenticated: usuarioX as usuarioX using /home/usuarioX/.ssh/authorized_keys

Aquí vemos que nos aparece una de las opciones que nos aparecían anteriormente en authmsg.

Otro error que podemos observar al tratar de conectarnos es el de “Permission Denied”. En este caso el responsable es otro archivo. Concretamente el sshconnect2.c

hippi3c0w# cat sshconnect2.c | grep -i "permission denied"
fatal("%s@%s: Permission denied (%s).",
error("Permission denied, please try again.");
hippi3c0w#

¿A dónde queremos llegar con esto? Que cuando analicemos los logs tenemos que tener muy en cuenta cómo funciona cada paquete. Podríamos ver que a un usuario le da problemas de “bad ownership”, pero no significa que este error se vaya a dar en todos los usuarios, puede que otro no tenga acceso porque esté en el DenyUsers. Es importante no malinterpretar los logs, de lo contrario podríamos realizar modificaciones en nuestro servidor que sean contraproducentes para nuestra seguridad y la de nuestro server.

Pero entremos ahora en las propias configuraciones que podríamos realizar en nuestro servidor SSH para mejorar su seguridad.

  1. Seguridad por oscuridad eliminando el banner de Debian. Esto lo podemos conseguir simplemente añadiendo DebianBanner no a nuestro /etc/ssh/sshd_config. No eliminará toda la información, pero sí la relativa a Debian. Para comprobar mejor esto, lanzaremos un nmap contra el servidor de pruebas que estoy utilizando para elaborar este artículo.

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10 (protocol 2.0)
25/tcp open smtp Exim smtpd 4.92
80/tcp open http Apache httpd 2.4.38 ((Debian))
631/tcp open ipp CUPS 2.2
9050/tcp open tor-socks Tor SOCKS proxy

Esta es la información que muestra antes de modificar nuestro /etc/ssh/sshd_config y añadirle nuestra directiva DebianBanner no. Esto es lo que veríamos después de añadirlo y reiniciar el servicio con /etc/init.d/ssh restart

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 (protocol 2.0)
25/tcp open smtp Exim smtpd 4.92
80/tcp open http Apache httpd 2.4.38 ((Debian))
631/tcp open ipp CUPS 2.2
9050/tcp open tor-socks Tor SOCKS proxy

Ya no nos aparecería la versión de Debian que estamos utilizando. (Sí, ya hemos actualizado a Debian 10 y en algunos de nuestros equipos ya hemos añadido nuestros repos de testing para bullseye, que será el nombre de la próxima Debian. En un futuro artículo podríamos comentar las novedades que trae Debian 10).

2. Utilizar llaves ssh para hacer login. Ya hemos dicho que uno de los potenciales de SSH es que podemos hacer login con nuestra clave pública. Es por esta razón que deberemos de aprovecharlo y hacerlo es tan sencillo como, en primer lugar, generar nuestra clave ssh.

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_manu_$(date +%Y-%m-%d) -C "Clave de manu"

Posteriormente lo que tendremos que hacer es mandar esta clave ssh a nuestro servidor remoto. Para ekki

ssh-copy-id user@remote-server-ip-or-dns-name

3. Deshabilitar el acceso de root mediante ssh. Si nos ponemos en el lugar de un atacante que quiera acceder a nuestro servidor y sabe que nuestro servidor es GNU/Linux, sabe que sí o sí, existe el usuario root, por lo que podría intentar acceder a nuestro servidor realizando ataques de fuerza bruta. Por esta razón es importante que eliminemos esta opción, aunque para ello primero deberemos asegurarnos de que nuestro usuario tiene acceso como sudo, para esto:

a. Añadimos a sudoers a nuestro usuarios si, por ejemplo, manualen es SysAdmin por lo que tiene sentido que tenga permisos de sudo.

b. Añadirlo al grupo de sudo directamente.

Una vez que nos hemos asegurado que, al menos uno de nuestro usuarios puede acceder como sudo, lo que haremos será denegar el acceso a root con la siguiente línea.

PermitRootLogin no

4. Deshabilitar el acceso a nuestro servidor mediante contraseña. El acceso mediante contraseña es corre un riesgo innecesario, por lo que debe ser eliminada esta opción de acceder al servidor. Con 3 líneas nos bastarían para configurar nuestro server para que sólo se pueda acceder mediante clave pública.

PasswordAuthentication no
AuthenticationMethods publickey
PubkeyAuthentication yesPasswordAuthentication no

5. Especificar qué usuarios tienen acceso a nuestro sistema. Esto lo hemos visto antes cuando hemos analizado el código de auth.c. Lo que tendremos que especificar qué usuarios van a tener acceso a nuestro servidor mediante AllowUsers y a cuáles se os vamos a denegar mediante DenyUsers. Un ejemplo sería:

AllowUsers manualen user2
DenyUsers root capitalismo

6. No permitir el acceso a cuentas que no tengan establecida una password. Esto lo vamos a hacer modificando la directiva PermitEmptyPasswords. Tendremos que poner:

PermitEmptyPasswords no

7. Cambiar el puerto por defecto de ssh. Como ya hemos comentado y sabemos, ssh utiliza el puerto 22, por lo que podríamos cambiarlo simplemente cambiando el número de puerto en nuestro /etc/ssh/sshd_config.

Port 666

Para comprobar que se nos ha cambiado el puerto (recordad que cuando terminéis de modificar el sshd_config tenéis que reiniciar el servicio), podéis lanzar netstat buscando el nuevo puerto que le habéis asignado.

hippi3c0w# netstat -tlupn | grep "666" | grep "tcp "
tcp 0 0 0.0.0.0:666 0.0.0.0:* LISTEN -

8. Evitar ataques de fuerza bruta. Esto lo podemos conseguir utilizando fail2ban y, dentro del jail, estableciendo el apartado de sshd de una forma similar a la siguiente

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 600

Para comprobar que funciona, podemos comprobar los logs de fail2ban

hippi3c0w# tail -f /var/log/fail2ban.log

[401]: INFO [sshd] Found 61.177.172.158 - 2019-08-02 17:26:17
[401]: INFO [sshd] Found 61.177.172.158 - 2019-08-02 17:26:19
[401]: INFO [sshd] Found 61.177.172.158 - 2019-08-02 17:26:23
[401]: INFO [sshd] Found 61.177.172.158 - 2019-08-02 17:26:26
[401]: INFO [sshd] Found 61.177.172.158 - 2019-08-02 17:27:18
[401]: NOTICE [sshd] Ban 61.177.172.158

Para evitar ataques de fuerza bruta, también podemos utilizar DenyHosts o sshguard.

9. Desconectar a los usuarios inactivos. Muchas veces tenemos usuarios dentro de nuestro sistemas que se han hecho login, han realizado sus tareas pero han dejado la sesión abierta y, por no cerrarla, están consumiendo recursos innecesarios de nuestro sistema, por lo que esto lo vamos a controlar de la siguiente forma

ClientAliveInterval 300
ClientAliveCountMax 0

Lo he hemos dicho es básicamente que si un usuario está inactivo por más de 300 segundos, lo desconectamos para que no siga consumiendo recursos.

10. Habilitar un banner ssh. Puede resultarnos habilitar un banner disuasorio y alertando que el acceso a dicho servidor es privado y que podríamos monitorizar su actividad. Para hacer esto

Banner /etc/mi_bannerSSH

Lógicamente tendremos que crear este archivo y añadir lo que nosotras queramos.

11. Deshabilitar los archivos .rhosts y los host-based auth. Simplemente tendremos que añadir las siguientes 2 líneas para lograr esto.

IgnoreRhosts yes
HostbasedAuthentication no

Y esta sería una configuración más o menos básica para tener un SSH un poco más seguro. Aclarar también algo que suelo escuchar y que es:

“Deja el sshd_config por defecto por si acaso, que podría fallar algo. Además, con el archivo por defecto funciona bien”

Un programador cualquiera

Lógicamente que con el archivo de configuración por defecto funciona, pero porque GNU/Linux y sus servicios está pensado para que pueda funcionar en cualquier máquina, desde la más potente a la menos potente. Este error de no modificar los archivos de configuración y centrárse únicamente en la programación del proyecto, es lo que ocasiona muchos de los errores que suelen darse y muchas veces la solución es modificar 2 directivas que se deberían cambiar. Además, como administradores de sistemas, es nuestro trabajo y si falla, estamos ahí para eso.

Por lo demás esperamos que este artículo os haya servido a todas. Como hemos comentado, como próximos artículos (por mi parte) podremos traer cómo configurar de una forma relativamente segura nuestro servidor y/o hablar de las novedades que nos trae Debian 10.

Manu Alén – @hippi3c0w



Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: