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 rootMaxAuthTries
(3) -> Establecemos a 3 el número máximo de intentos de loginLoginGraceTime
(60) -> Establecemos a 60 minutos el tiempo máximo de loginAllowGroups
(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 grupoAllowUsers
(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 segundosClientAliveCountMax (5) ->
nº de mensajes Keep Alive a enviar antes de cerrarDenyGroups (group_1,group_2)
-> La directiva contraria aAllowGroups
DenyUsers
(user_1, user_2
) -> La directiva contraria aAllowUsers
ListenAddress
(XX.XX.XX.XXX) -> forzaremos que SSH sólo escuche en una interfaz (ip pública) determinadaUsePrivilegeSeparation (yes)
-> permitirá ejecutar fragmentos de código como root en un entorno jail al conectarnosPermitEmptyPasswords
(no) -> Permite contraseñas vacíasAddressFamily
(Inet) -> Capamos el tipo de tráfico que soportará el servidor, los valores son: Inet, Inet6,AnyAuthorizedKeysFile (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.
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.
Correcto, en el equilibrio está la clave (barridos de bots VS acceso sin privilegios).
Gracias por el aporte.