lunes, 17 de octubre de 2016

OpenSSH: Asegurando la instalación por defecto de nuestro servidor SSH


En la empresa en la que trabajo tenemos algunos servicios implementados bajo GNU/Linux, uno de ellos es el de SSH para la administración remota de los servidores. Actualmente me encuentro en un sano proceso de revisión de configuraciones, con la finalidad de tener una mayor seguridad, más allá de la provista en una instalación por defecto.

Aprovechando todas estas tareas, el presente post reúne las configuraciones en el servicio de SSH que acabo de aplicar en los servidores esta última semana. De seguro hay muchas mas cosas por hacer, pero aún estoy en proceso de lectura/prueba/error de las diversas opciones de configuración.
  • IMPORTANTE: Estoy partiendo del hecho de que tengo instalado un servidor OpenSSH (Version 5.5p1) sobre un Debian 6.0.1. Adicionalmente debo confesar que me estoy conectando a través de PuTTY.
TAREAS:
Editamos el archivo sshd_config:
nano /etc/ssh/sshd_config
Y procedemos a realizar los siguientes cambios:

Cambio de Puerto
Port 22222
El cambio de puerto para mí significó doble beneficio, el primero es dificultar un poco el trabajo a un posible atacante al no brindar el servicio de SSH, por el habitual puerto 22. Y el segundo beneficio es que puedo usar BBSSH para conectarme desde mi blackberry al Servidor, ya que mi operadora celular tiene como política bloquear todo el tráfico hacia puertos bajos. Si se va a proveer el servicio SSH por varios puertos, lo único que tenemos que hacer es agregar tantas directivas Port como puertos se necesiten.

Si tratamos de conectarnos hacia el puerto 22, obtendremos un error del tipo: Network error: Connection timed out 

Restricción de la Interface de Escucha
ListenAddress 192.168.3.1
Esto es útil si el servidor cuenta con más de una interface. En mi caso cuento con 3 interfaces : 2 internas (192.168.3.1 y 192.168.31.1) y 1 externa (186.42.x.x); por lo que decidí permitir el acceso a través de sólo una de ellas. Si necesitamos escuchar por otras interfaces, sólo tenemos que agregar más líneas con la directiva ListenAddress, una por cada interface.

Si tratamos de conectarnos desde alguna dirección IP que ingrese a través de otra interface, obtendremos un error del tipo: Network error: Connection refused 

Deshabilitar el acceso remoto al usuario root
PermitRootLogin no
Existen muchos motivos para deshabilitar el acceso remoto a través del usuario root. En mi caso, al inicio era una sola persona (yo) la que accedía al servidor, por lo que tener una traza de auditoría no me interesaba mucho, pero la empresa crece y tenemos ahora a más usuarios accediendo, lo cual trajo la necesidad de implementar cierto control al respecto. Al deshabilitar que el usuario root pueda iniciar una sesión SSH, obligo a que cada usuario se conecte con sus credenciales, lo cual me deja un rastro en el archivo /var/log/auth.log:
Jun 14 15:55:14 svpx03 sshd[23031]: Accepted password for fliberio from 192.168.3.14 port 10319 ssh2
Jun 14 15:55:14 svpx03 sshd[23031]: pam_unix(sshd:session): session opened for user fliberio by (uid=0)
Si tratamos de conectarnos como root, obtendremos un error del tipo: Access denied  

Permitir el Acceso Remoto sólo a Usuarios y Grupos Específicos OpenSSH tiene directivas deny/allow para restringir el acceso de usuarios y grupos, las cuales son aplicadas en el siguiente orden:
  1. DenyUsers
  2. AllowUsers
  3. DenyGroups
  4. AllowGroups
No voy a entrar en detalle de lo que hace cada una, porque es bastante obvio, sino siempre queda la documentación ;). El modo de uso es el siguiente:
DenyUsers user1 user2 ...
Para mi caso yo parto de la existencia de 3 usuarios de sistema y un grupo. Los mismos que los cree de la siguiente forma:
groupadd fcmeadmins
adduser --ingroup fcmeadmins fliberio
adduser --ingroup fcmeadmins imarx
adduser --ingroup fcmeadmins ehurtado
Por lo que aplique en el archivo sshd_config la siguiente configuración:
AllowGroups fcmeadmins
Si tratamos de conectarnos con un usuario no autorizado, obtendremos un error del tipo: Access denied  

Cambiar el Tiempo de Gracia para Iniciar la Sesión
LoginGraceTime 45
Este es el tiempo (generalmente en segundos) que tenemos para ingresar nuestro usuario/contraseña una vez que establecemos conexión con el servidor SSH. El valor por defecto es 120 segundos, lo cual me parece mucho :P. 

En directivas como ésta, que requieren como valor alguna unidad de tiempo se pueden usar las siguientes opciones:
  seconds
s | S   seconds
m | M   minutes
h | H   hours
d | D   days
w | W   weeks
Si sobrepasamos el tiempo de gracia para ingresar nuestras credenciales, obtendremos un error del tipo: Server unexpectedly closed network connection  
Limitar el número de intentos fallidos para ingresar el password de acceso
MaxAuthTries 3
Este es el número máximo de intentos que tengo para ingresar el password, luego de establecida la conexión con el servidor SSH. Esto va relacionado con la directiva anterior ya que tengo MaxAuthTries intentos durante LoginGraceTime de tiempo.

Si sobrepasamos el número de intentos para escribir nuestra password, obtendremos un error del tipo: Too many authentication failures for userX  

Desconectar al usuario después de un tiempo de inactividad
ClientAliveCountMax 0
ClientAliveInterval 600
Para esto se utilizan dos directivas:
  • ClientAliveCountMax: El numero máximo de mensajes checkalive (sigues allí/estas vivo?) que el servidor SSH envía al cliente sin recibir respuesta.
  • ClientAliveInterval: El intervalo de tiempo entre cada mensaje checkalive.
En mi caso ClientAliveCountMax 0, no envia mensajes checkalive desde el servidor y ClientAliveInterval 600, espera 600 segundos (10 min) para desconectar al usuario si durante este lapso no recibe algún tipo de interacción. 

Si sobrepasamos el tiempo de inactividad permitido, obtendremos un error del tipo: Server unexpectedly closed network connection  

Algo de seguridad por oscuridad
PrintLastLog no
Evita que cuando se conecten los usuarios les aparezca una línea igual a:
Last login: Tue Jun 14 15:19:19 2011 from 192.168.25.1
También tenemos
PrintMotd no
Para que al conectarse el usuario no le aparezca el Mensaje del Dia. En Debian no me funcionó la desactivación y tuve que hacer un:
>/etc/motd
Recomiendo:
Revisar la directiva Match, se le ve buena pinta. Yo pienso revisarla luego ;).

Para finalizar
Guardamos el archivo

Y reiniciamos el servicio
/etc/init.d/ssh restart
Espero que les sea de utilidad.

Saludos :D  

Referencias:

"Transporta un puñado de tierra todos los días y construirás una montaña" - Confucio