dec07mvp01

En esta entrada vamos a detenernos en la capa de aplicaciones del modelo de defensa en profundidad y en concreto en una de las herramientas básicas para cualquier administrador de sistemas: SSH; el servicio que nos permite conectarnos a una máquina remota de forma segura y sin necesidad de tener un entorno gráfico ni en origen ni en destino.

Este servicio en sistemas Linux suele implementarse en forma del paquete OpenSSH, un demonio que instalamos con sudo apt-get install ssh y que loguea por defecto en  /var/log/auth.log.

La configuración que trae por defecto está muy expuesta, facilitándole mucho a los crackers ataques tipo man in the middle o subirnos una shell que ejecute malware a nuestro servidor, por poner dos ejemplos típicos.

Entonces, ¿cómo nos protegemos?. Os propongo cinco recomendaciones sencillas y para toda la familia que nos ahorrarán más de un disgusto:

1. Cambiando el puerto

Esto es lo primero que hago nada más tener una shell en una máquina. Es importante siempre poner el puerto más alto que tengamos disponible y que sea uno que nada tenga que ver con el de por defecto (22), ya que así minimizaremos el impacto de bots que se conectan a puertos frecuentemente utilizados (8022, 2222, 8888, etc). Para ello, modificamos el fichero /etc/ssh/sshd_config, en concreto la linea que incluye:

# What ports, IPs and protocols we listen for
Port 50683

A continuación, reiniciaremos el servicio: /etc/init.d/ssh restart y por último nos conectaríamos mediante : ssh -p 50683 usuario@ip

2. Retocando los ficheros de configuración

Tenemos dos ficheros de configuración que podremos tocar para fortificar nuestro servidor/cliente de SSH en sistemas Linux:

  • Fichero de configuración del servidor:/etc/ssh/sshd_config
  • Fichero de configuración del cliente: /etc/ssh/ssh_config

2.1. Configuración de servidor SSH

NOTA: Entre paréntesis indico el valor recomendado.

  • PermitRootLogin (no) -> Así evitamos poder hacer login en el SSH como root
  • MaxAuthTries (3) -> Establecemos a 3 el número máximo de intentos de login
  • LoginGraceTime (60) -> Establecemos a 60 minutos el tiempo máximo de login
  • AllowGroups (ssh_users) -> De esta forma, y teniendo el grupo “ssh_users” previamente creado, sólo permitiremos el login via SSH a los usuarios de dicho grupo
  • AllowUsers (usuario1,usuario2) -> También podemos restringir el acceso de cada usuario a una IP determinada (p.ej., usuario1@91.121.18.211)
  • Ciphers (blowfish) -> Cifrados admitidos “well-studied”
  • ClientAliveInterval (600) -> limita el tiempo de sesiones SSH desatendidas, activando mensajes Keep Alive cada X segundos
  • ClientAliveCountMax (5) -> nº de mensajes Keep Alive a enviar antes de cerrar
  • DenyGroups (group_1,group_2) -> La directiva contraria a AllowGroups
  • DenyUsers (user_1, user_2) -> La directiva contraria a AllowUsers
  • ListenAddress (XX.XX.XX.XXX) -> forzaremos que SSH sólo escuche en una interfaz (ip pública) determinada
  • UsePrivilegeSeparation (yes)  -> permitirá ejecutar fragmentos de código como root en un entorno jail al conectarnos
  • PermitEmptyPasswords (no) -> Permite contraseñas vacías
  • AddressFamily (Inet) -> Capamos el tipo de tráfico que soportará el servidor, los valores son: Inet, Inet6,Any
  • AuthorizedKeysFile (ruta) -> indicaremos en qué ruta se van a almacenar las claves a guardar, por defecto %h/.ssh/authorized_keys

Una vez realizados todos los cambios, tendremos que reiniciar el servicio:

/etc/init.d/sshd restart ó service ssh restart

2.2. Configuración de cliente SSH

Añadiremos o modificaremos, si lo necesitamos, los siguientes parámetros del fichero /etc/ssh/ssh_config para tener una configuración fortificada del cliente SSH:

          # Site-wide defaults for various options

          Host *
          ForwardAgent no
          ForwardX11 no
          RhostsAuthentication no
          RhostsRSAAuthentication no
          RSAAuthentication yes
          PasswordAuthentication yes
          FallBackToRsh no
          UseRsh no
          BatchMode no
          CheckHostIP yes
          StrictHostKeyChecking no
          IdentityFile ~/.ssh/identity
          Port 22
          Cipher blowfish
          EscapeChar ~

 

3. Comunicándonos vía certificados

Otro punto de fortificación sería conectarnos a nuestro servidor de SSH a través de certificados en vez de utilizar contraseñas. Para ello, tenemos que tener claro las siguientes partes:

  • ssh_host_rsa_key: parte privada de la clave RSA para la versión 2 del protocolo SSH. Es la que OpenSSH utiliza por defecto.
  • ssh_host_rsa_key.pub: parte pública de la clave RSA para la versión 2 del protocolo SSH.
  • ssh_host_dsa_key: parte privada de la clave DSA. Es la alternativa a RSA.
  • ssh_host_dsa_key.pub: parte pública de la clave DSA.
  • ssh_host_key: parte privada de la clave RSA para la versión 1 del protocolo SSH . Se desaconseja el uso de la versión1 del protocolo SSH ya que éste fue roto.
  • ssh_host_key.pub: parte pública de la clave RSA para la versión 1 del protocolo SSH.

Autenticación con clave pública

ssh-keygen –q –f ~/.ssh/id_rsa –t rsa o ssh-keygen (a secas)
Con esto añadimos al authorized_keys de la clave pública.

Una vez tengamos configuradas nuestras claves SSH, podemos añadir un punto más de seguridad si entramos en el fichero de configuración /etc/ssh/sshd_config y modificamos las siguiente lineas (y después reiniciamos el servicio):

PasswordAuthentication no

AuthorizedKeysFile (ruta) -> indicaremos en qué ruta se van a almacenar las claves a guardar, por defecto %h/.ssh/authorized_keys

Distribución segura de la clave de host

Los clientes, cuando se conecten al servidor, durante el proceso de handshake SSL deberán identificar correctamente al servidor. En los sistemas Linux se encuentra en la ruta ~/.ssh/known_hosts

4. Accediendo sólo desde ubicaciones confiables

A mayores de la defensa a nivel de capa de aplicación, podríamos configurar a nivel de capa de red el tráfico entrante al puerto del SSH a nuestra máquina sólo desde ubicaciones determinadas. Para ello, podemos tirar conjuntamente de directivas IPTables y de estrategias de Port-Knocking.

5. Utilizando herramientas seguras

Existen varias herramientas que nos permitirán realizar operaciones securizadas contra nuestra máquina, transferencia de ficheros (SCP, SFTP), sistemas de ficheros montados únicamente por SSH (SSHFS) ó herramientas de protección avanzadas (fail2ban, ssh-audit).

En mi caso, fail2ban (apt-get install fail2ban) es un fijo dentro de los paquetes que instalo siempre al echarle el guante a una máquina. Permite realizar búsquedas (regexp) en los logs de ciertas aplicaciones para inferir que están siendo atacadas y banear direcciones IP (a través de iptables) o ayudar en el bloqueo de DDOS.

Sus ficheros principales son:

  • /etc/fail2ban/jail.conf->Configuración del servicio
  • /etc/fail2ban/filter.d/*->Filtros (regexp) del servicio
  • /etc/fail2ban/action.d/*->Acciones en iptables
  • /var/log/fail2ban.log -> Fichero de log

Por su parte, ssh-audit nos permite hacer auditoría y pasar un listado de buenas prácticas de configuración e implementación sobre un servicio SSH. La podemos encontrar en su Github.

Si tenéis algún truco o configuración más, animaos a compartirlo en los comentarios.

2 thoughts on Hardening Unix: Fortificando SSH

  1. Rodrigo RegaRodrigo Rega

    No se recomienda publicar el servicio ssh en un puerto mayor a 1024 ya que en caso de que el servicio se parase un usuario malintencionado sin privilegios podría levantar un sshd troyanizado.

    Un saludo.

    Reply

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.