Logo OpenSSH

Asegurando el servicio SSH en Linux

 
 

Índice General

  1. Introducción
  2. Restricción por clientes o equipos conocidos
  3. Restricciones establecidas en el archivo /etc/ssh/sshd_config
  4. Reiniciar el servidor
  5. Consideración a tener en cuenta si deshabilitamos el acceso con RSA
  6. El programa fail2ban

Enlaces externos
 

  1. Introducción (Volver al índice General)
    La restricción de este servicio es una buena política para fortificar la seguridad de nuestros servidores y en concreto del servicio SSH.

    En ZeppelinuX«>ZeppelinuX encontrarás el artículo Instalar y configurar el servicio SSH en Debian, si aún no lo tienes instalado.

    En este artículo señalaremos algunos parámetros de configuración del servidor SSH que fortifican su seguridad y hablaremos de otros aspectos relacionados con la seguridad del mismo.

    Hablaremos de como restringir que equipos conocidos pueden conectarse a nuestro servidor SSH, como restringir que usuarios podrán conectarse al servidor SSH y otros parámetros a tener en cuenta a la hora de asegurar el servidor.

    NOTA: es importante hacer copia de seguridad de todo archivo de configuración antes de realizar cualquier cambio.

  2.  

  3. Restricción por clientes o equipos conocidos (Volver al índice General)
    La restricción por clientes, equipos o hosts se puede realizar mediante reglas de control de tráfico de red con iptables o bien con el fichero /etc/hosts.allow.

    • Restricciones con iptables (Volver al índice General)
      Partimos de que el equipo en el que está instalado el servicio SSH tiene instalado iptables como firewall, que nuestro servidor SSH escucha por el puerto 22/TCP y como ejemplo, supongamos que los equipos a los que queremos permitir conexiones a nuestro servidor pertenecen a la red 192.168.1.0/24. Tanto el puerto por el que escuche el servidor, como la red o IPs permitidas serán de vuestra elección o necesidad.

      De acuerdo a la configuración de nuestro ejemplo, las reglas de filtrado para iptables serían las siguientes:

      iptables –A INPUT –p tcp –dport 22 –s 192.168.1.0/24 –j ACCEPT
      iptables –A OUTPUT –p tcp –sport 22 –d 192.168.1.0/24 –j ACCEPT
    • Restricciones con el archivo /etc/hosts.allow (Volver al índice General)
      En el caso de utilizar el fichero /etc/hosts.allow, añadiremos la línea siguiente al mismo:

      sshd: 192.168.1.0/24
  4.  

  5. Restricciones establecidas en el archivo /etc/ssh/sshd_config (Volver al índice General)
    Existen directrices sobre el control de usuarios, hosts, puertos, algoritmos criptográficos, etc. que se configuran en el servidor SSH. Para configurar dichas directrices, habrá que editar el archivo /etc/ssh/sshd_config, que en nuestro ejemplo lo modificaremos con el editor de texto plano nano, presente en casi todas las distribuciones Linux:

    $ sudo nano /etc/ssh/sshd_config

    Sobre el fichero de configuración por defecto (no olvidar hacer una copia de seguridad del archivo antes de modificar), modificaremos aquellas directrices que no estén establecidas a los valores indicados en este artículo y añadiremos aquellas directrices que no estén indicadas en el archivo de configuración.

    A continuación se muestran las directrices que reforzarán la seguridad de nuestro servidor SSH:

    • Evitar ataques a un puerto conocido (Volver al índice General)
      De forma predeterminada, el servicio SSH escucha por el puerto 22. La directriz por defecto sería:

      Port 22

      Una forma de elevar la seguridad del servidor SSH, consiste en cambiar el número de puerto predeterminado por otro que sólo el administrador del sistema conozca. A este tipo de técnicas se les conoce como seguridad por oscuridad.
      Los atacantes buscarán servidores que estén escuchando por el puerto 22/TCP. Cambiar de puerto disminuye considerablemente la posibilidad de una intrusión. Podemos cambiarlo a otro puerto, preferiblemente entre el 1024 y 65535. En nuestro ejemplo, configuraremos el servidor para que escuche por el puerto 54312:

      Port 54312

      Si trabajamos tras un encaminador/NATP y no queremos cambiar el puerto estándar del servidor SSH, podemos filtrar el puerto 22/TCP en el encaminador/NATP prohibiendo todas las conexiones entrantes al puerto 22 y por otro lado, redirigir las conexiones entrantes al puerto 54312 del encaminador/NATP al puerto 22 del servidor SSH.

    • Restringir el acceso a IPv4 (Volver al índice General)
      Si no se utiliza IPv6 no tenemos que tenerlo habilitado.

      AddressFamily inet
    • Escuchar sólo en la red interna (Volver al índice General)
      Si no tenemos intención de dar servicio SSH fuera de la red interna, otra opción para asegurar el servidor es obligar a que sólo escuche por la interfaz de red, si tuviese más de una, conectada a la red interna.

      ListenAddress 192.168.1.0

      Al día de la fecha que se escribe este artículo, con la versión OpenSSH_6.7p1 Debian-5+deb8u3, OpenSSL 1.0.1t 3 May 2016, esta opción falla. Al reiniciar el equipo, el servicio se ejecuta pero no escucha por ningún puerto. Estoy a la espera que parcheen la versión. Por lo tanto si ves que tu demonio se lanza pero no escucha por ningún puerto, puede ser debido a la configuración de esta directriz. Para corregir el fallo no queda más remedio que establecer la directriz al valor por defecto:

      ListenAddress 0.0.0.0
    • Usar sólo versión 2 de protocolo SSHv2 (Volver al índice General)
      Existen dos versiones de SSH en cuanto a su protocolo de comunicación, SSHv1 y SSHv2. SSHv1 esta en desuso pero todavía se incluye por compatibilidad. SSHv1 tiene varias vulnerabilidades conocidas, una de ellas en concreto, es un agujero de seguridad que potencialmente permite a un intruso insertar datos en la corriente de comunicación, por lo que su uso ya no es recomendable. Un error frecuente es dejar que el demonio SSH permita el uso de las dos versiones. Para evitar el uso de la versión SSHv1 y los posibles ataques a esta, basta con indicar en esta directriz que solo admita comunicaciones de SSH basadas en el protocolo SSHv2, el cual tiene un algoritmo de intercambio de claves mejorado y que no es vulnerable a los agujeros de seguridad de la versión SSHv1.

      Protocol 2
    • Deshabilitar XForwarding (Volver al índice General)
      Esta directriz establece si se permite o no la ejecución remota de aplicaciones gráficas. Si se accede al servidor SSH desde la red local, la directriz puede quedarse con el valor yes. Si se accede al servidor SSH desde redes públicas, sería prudente establecer esta directriz con el valor no.
      El forwarding de tráfico de X11 es considerado inseguro por naturaleza. Aquellos usuarios con la capacidad de evitar las restricciones a nivel de permisos en el archivo de base de datos de autorización de X, pueden acceder al display X11 a través de la conexión reenviada. Un atacante puede entonces ser capaz de realizar actividades tales como el monitoreo de teclado (keylogger).

      X11Forwarding no
    • Deshabilitar TCPKeepAlive (Volver al índice General)
      Nos indica que el servidor sshd enviará mensajes de keepalive al cliente después de que detecta alguna inactividad. Es aconsejable deshabilitarlo para prevenir ataques de suplantación de identidad (spoofing).

      TCPKeepAlive no
    • Directriz ClientAliveInterval (Volver al índice General)
      Esta directriz especifica el intervalo de tiempo en segundos en el cual después de que no se ha recibido ningún dato de el cliente, sshd enviara un mensaje a través del canal cifrado para requerir una respuesta de el cliente, el valor predeterminado es 0, el cual significa que no se envía tal mensaje. Esta opción sólo se aplica al protocolo SSHv2. Es útil cuando se tiene una conexión intermitente y se requiere que la sesión esté abierta sin que se cierre la sesión. En nuestro caso, estableceremos un intervalo de tiempo:

      ClientAliveInterval 600
    • Directriz ClientAliveCountMax (Volver al índice General)
      Nos indica las veces que el servidor sshd enviará mensajes keepalive cuando el cliente está inactivo. Si el cliente no envía ninguna respuesta, entonces el servidor terminara la conexión y por lo tanto la sesión. Si tenemos conexiones intermitentes es recomendable subir el numero a este valor. Hay que notar que esta opción es diferente la opción TCPKeepAlive, estos mensajes son enviados a través de el canal cifrado, por lo tanto no puede ser explotado por técnicas de spoofing como el TCPKeepAlive. En nuestro caso, estableceremos un valor que tras alcanzarse y no obtener validación del cliente, se desconectará la sesión:

      ClientAliveCountMax 3
    • Directriz UsePrivilegeSeparation (Volver al índice General)
      Significa que después de que la sesión SSH se ha establecido, se pasaran los privilegios de ese proceso al usuario de quien inicie la conexión, si se deshabilita, el proceso estará a nombre de root. Muy importante para evitar elevación de privilegios.

      UsePrivilegeSeparation yes
    • Directriz PubkeyAuthentication (Volver al índice General)
      Esta directriz especifica el uso de autenticación por medio de la llave pública. En nuestro caso lo habilitaremos.

      PubkeyAuthentication yes
    • Directriz AuthorizedKeysFile (Volver al índice General)
      Esta directriz se usa conjuntamente con PubkeyAuthentication cuando se usa autenticación por llave pública, y especifica donde se guardaran las llaves en el host remoto. El valor por defecto es ~/.ssh/authorized_keys. Esta ruta es por defecto para el protocolo SSHv2 de SSH.

      AuthorizedKeysFile .ssh/authorized_keys

      En algunas publicaciones el valor de la directriz se asigna con la siguiente sintaxis:

      AuthorizedKeysFile %h/.ssh/authorized_keys
    • Deshabilitar claves en lista negra (Volver al índice General)
      Si esta directriz se establece a yes permitirá hacer login con claves en lista negra. En nuestro caso, logicamente la ponemos en no.

      PermitBlacklistedKeys no
    • Directriz AllowUsers (Volver al índice General)
      Con esta directriz limitamos los usuarios del sistema que pueden ingresar vía SSH. Es el equivalente a una lista blanca.

      AllowUsers mortadelo filemon anacleto

      En el ejemplo anterior, los usuarios mortadelo, filemon y anacleto podrán acceder desde cualquier ordenador, no se valida el host desde el que se conectan. Si se quiere más seguridad, es posible indicar también el host o hosts (desde los cuales el usuario se puede conectar) mediante el símbolo @. Veamos los siguientes ejemplos:

      AllowUsers mortadelo@192.168.0.2          (Solo desde la IP indicada)
      AllowUsers mortadelo@10.33.0.*            (Toda la red indicada)
      AllowUsers mortadelo@*.zeppelinux.es      (Todo el dominio indicado)
      AllowUsers mortadelo@ventas.zeppelinux.es (Solo el equipo del dominio indicado)

      Combinación de varias:

      AllowUsers mortadelo@192.168.1.2 filemon@10.33.0.* anacleto@*.zeppelinux.es sacarino

    •  
       

    • Directriz IgnoreRhosts y RhostsRSAAuthentication (Volver al índice General)
      Con estas directrices denegamos el uso de relaciones de confianza establecidas en los ficheros ~/.rhosts y ~/.shosts de los usuarios:

      IgnoreRhosts yes
      RhostsRSAAuthentication no
    • Directriz PermitRootLogin (Volver al índice General)
      Probablemente sea la directriz de seguridad más importante que podemos establecer para asegurar nuestro servidor SSH. En los sistemas Unix y Linux se crea por defecto al usuario root, lo que implica que ya conocemos la existencia de al menos un usuario, ¡y que usuario!, con privilegios de adnimistrador. Muchos ataques de fuerza bruta se concentran en atacar al usuario root con la esperanza de que tenga una contraseña débil.
      Sabiendo una parte de la ecuación (root) solo será cuestión de tiempo para que alguien con paciencia y suerte vulnere el sistema. En esta directriz denegamos el acceso al usuario root y por lo tanto, cualquier intento de ataque directo al usuario root será inútil.
      Al denegar el acceso al usuario root, cada vez que necesitemos realizar tareas administrativas, accederemos como un usuario normal y una vez dentro, utilizando alguno de los comandos su o sudo podremos realizar dichas tareas administrativas. Por lo tanto, denegando el acceso al usuario root, el atacante tendrá que acertar tanto el nombre de un usuario del sistema como su contraseña, algo que disminuye notablemente la probabilidad de una intrusión.

      PermitRootLogin no
    • Directriz LoginGraceTime (Volver al índice General)
      En esta directriz se establece el tiempo, en segundos, durante el cual la pantalla de login estará disponible para que el usuario introduzca su nombre de usuario y contraseña, si no lo hace durante ese período de tiempo el login se cerrará, evitando así dejar por tiempo indeterminado pantallas de login sin que nadie las use, o que alguien este intentando mediante un script adivinar un usuario y su contraseña. Si el valor es 0, no hay límite de tiempo para que un usuario se autentique, lo cual no es recomendable ya que de esta forma un atacante podría utilizar ataques de fuerza bruta o usando métodos de diccionario para adivinar la contraseña, por lo tanto no es recomendable dejar esta directriz a 0. En nuestro ejemplo lo estableceremos en 40 segundos.

      LoginGraceTime 40
    • Directriz StrictModes (Volver al índice General)
      En esta directriz se establece que sshd revisara los modos y permisos de los archivos de los usuarios y el directorio $HOME de el usuario antes de aceptar la sesión. Esto es normalmente deseable porque a veces algunos usuarios dejan sus directorios, accidentalmente, con permiso de escritura para cualquiera. El valor predeterminado es yes, por lo tanto, lo dejaremos con su valor predeterminado.

      StrictModes yes
    • Directriz HostbasedAuthentication (Volver al índice General)
      Deshabilitar autenticación basada en host.

      HostbasedAuthentication no
    • Directriz IgnoreUserKnownHosts (Volver al índice General)
      En esta directriz establecemos no confiar en el archivo ~/.ssh/known_hosts para RhostsRSAAuthentication.

      IgnoreUserKnownHosts yes
    • Directriz PasswordAuthentication (Volver al índice General)
      La directriz PasswordAuthentication habilita o deshabilita la autenticación con contraseñas. Por defecto está permitida la autenticación con contraseña. Si establecemos el valor no sólo se permitirá el acceso a través de firmas digitales. Es muy importante no cambiar el valor de esta directriz a no hasta haber instalado nuestra firma digital.

      PasswordAuthentication no
    • Directriz PermitEmptyPasswords (Volver al índice General)
      La directriz PermitEmptyPasswords especifica si se permite el uso de contraseñas vacías, es decir, autenticarse sin contraseña (no recomendable por motivos de seguridad). Esta directriz es válida cuando se usa conjuntamente con PasswordAuthenticacion yes.

      PermitEmptyPasswords no
    • Directriz UsePAM (Volver al índice General)
      Si usamos claves no necesitamos PAM (Módulos de autenticación Conectables) y permitimos a sshd funcionar como un usuario no root.

      UsePAM no
    • Directrices de registro de eventos (Volver al índice General)
      El registro de eventos del servicio es importante así como la ruta donde guardarlos, un atacante experimentado intentará limpiar los logs para evitar ser atrapado.
      En estas directrices se especifican los parámetros para el registro de eventos:

      • SyslogFacility especifica el tipo de registros que generará, en este caso es AUTH, es decir, de las autenticaciones que se hacen contra el servidor. El parámetro AUTH es el predeterminado.
      • LogLevel con el valor INFO es el valor predeterminado. Otros parámetros están especificados en la página del manual de sshd_config (mansshd_config), los parámetros DEBUG2 y DEBUG3 cada uno de ellos especifican el nivel más alto de registro. Guardar registros con el nivel DEBUG viola la privacidad de los usuarios y por lo tanto no es recomendable.
        SyslogFacility AUTH
        LogLevel INFO
    •  

    • Directriz PrintLastLog (Volver al índice General)
      Aquí se especifica si se mostrara un mensaje mostrando la dirección IP de donde se conecto el usuario la ultima vez. Muy útil para saber si alguien más se está conectando con un usuario en especifico.

      PrintLastLog yes
    • Directriz Banner (Volver al índice General)
      Por medio de esta directriz podemos presentar un banner de acceso que nos permitirá mostrar un mensaje antes de la autenticación. Enseñar un cartel de advertencia exponiendo temas legales de un acceso no autorizado.
      El banner de acceso no es más que el contenido de un fichero de texto plano ubicado en algún sitio del sistema y que podremos personalizar a nuestro gusto. El banner de acceso se presenta antes de autenticarnos en el servidor.

      Banner /etc/ssh/ssh_pre-login

     

  6. Reiniciar el servidor (Volver al índice General)
    Tras realizar cambios en el archivo /etc/ssh/sshd_config tendremos que reiniciar el servicio para que los cambios surtan efecto. Para ello, ejecutaremos el siguiente comando:

    $ sudo service sshd restart

    o también:

    $ sudo /etc/init.d/ssh restart
  7. Consideración a tener en cuenta si deshabilitamos el acceso con RSA (Volver al índice General)
    Si optamos por deshabilitar en el servidor SSH el algoritmo de cifrado RSA, en favor del algoritmo DSA, en el equipo cliente, antes de intentar conectarnos al servidor SSH remoto, debemos de:

    • Borrar el archivo ~/.ssh/known_hosts el cual mantiene el fingerprint del servidor generado con RSA y que se genere uno nuevo cuando realicemos la conexión.
      usuario@cliente:~$ rm -rf .ssh/known_hosts
    • O también utilizar esta otra forma más elegante, que explicamos en el apartado de Archivos de configuración, la cual nos permite actualizar los fingerprint guardados. Este comando elimina la entrada correspondiente en el archivo ~/.ssh/known_hosts, permitiendo añadir de nuevo al anfitrión con una nueva firma digital.
      $ ssh-keygen -R nombre.o.ip.del.servidor.SSH
  8.  

  9. El programa fail2ban (Volver al índice General)
    No quiero terminar este artículo sin hablar de fail2ban. Solo hablaré brevemente sobre este programa que en conjunción con iptables es una solución potente para asegurar nuestro servidor contra ataques por fuerza bruta. Creo que fail2ban se merece un artículo dedicado exclusivamente a él y espero, que en un futuro no muy lejano, poder redactar dicho artículo y complementarlo con otro sobre iptables (Netfilter).

    Cuando se administra un servidor público es muy frecuente recibir ataques por fuerza bruta para acceder al sistema. Un ataque por fuerza bruta sobre SSH consiste en intentar iniciar sesión en el sistema con todas las combinaciones de nombres y contraseñas posibles. Si no se toman las medidas adecuadas el atacante podrá acceder al sistema.
    Con fail2ban, cuando se realizan un número de intentos (número establecido en la configuración) fallidos de autenticación en el sistema, fail2ban se comunica con el cortafuegos iptables y bloquea la dirección IP desde donde se está llevando a cabo el ataque.

    • Instalación de fail2ban (Volver al índice General)
      Para instalar fail2ban realizaremos los siguientes pasos:
      Antes de comenzar la instalación actualizamos los repositorios con la siguiente orden:

      $ sudo apt-get update

      A continuación procedemos a la instalación del paquete.

      $ sudo apt-get install fail2ban

      Tras la instalación lo iniciamos:

      $ sudo service fail2ban start
    • Comprobar que fail2ban está iniciado (Volver al índice General)
      Para comprobar que el fail2ban esta iniciado ejecutaremos la siguiente orden:

      $ sudo ps -ef | grep fail2ban
      root      3352     1  0 11:11 ?        00:00:00 /usr/bin/python /usr/bin/fail2ban-server -b -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid
    • Configuración básica de fail2ban (Volver al índice General)
      En primer lugar copiamos el archivo de configuración por defecto jail.conf de fail2ban con el nombre de jail.local:

      $ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

      Editaremos el fichero /etc/fail2ban/jail.local con la siguiente orden:

      $ sudo nano /etc/fail2ban/jail.local

      Para terminar, habilitaremos la jaula llamada ssh, si es que no se encuentra ya activa por defecto, y la modificaremos de tal forma que aparezcan las siguientes líneas:

      [ssh]
      enabled = true
      port = 54312 #Puerto por el que escucha el servidor SSH
      filter = sshd
      logpath = /var/log/auth.log
      maxretry = 3
      findtime = 1200
      bantime  = 3600

      Con las líneas arriba indicadas, declaramos una regla para el demonio sshd que escucha por el puerto 53212 y le indicamos en maxretry la cantidad máxima de intentos fallidos de autenticación antes de ser bloqueado.
      El parámetro findtime indica la ventana de tiempo en segundos durante la cual se toma en cuenta el parámetro maxretry.
      El parámetro bantime indica el tiempo en segundos que durará el bloqueo de la dirección IP.

      Para que surtan efecto los cambios, habra que reiniciar el servicio fail2ban con la siguiente orden:

      $ sudo service fail2ban restart

      Para ver los LOGS de conexión ejecutaremos una de las siguientes ordenes:

      sudo less /var/log/auth.log

      o

      sudo nano /var/log/auth.log

 
Enlaces externos (Volver al índice General)

 

Espero que este artículo os haya sido de utilidad. Si pensáis que podéis colaborar para mejorar este artículo, que hay algo erróneo en él o simplemente deseáis comentarlo, por favor, dejad vuestra opinión más abajo.
 
Seguir J. Carlos:

Técnico Informático - Desarrollo Web - Administración de Redes

Técnico Informático. Desarrollo Web. Administración de redes.

Últimas publicaciones de

Deja una respuesta

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.