Bastionando un servidor: algunas indicaciones

Una de las tareas comunes que deben aplicarse a un servidor que va a pasar a producción es fortalecer la seguridad que lleva por defecto el sistema. A esto se le llama bastionar o securizar. Como son muchos aspectos los que hay que tener en cuenta para llevar a cabo esta labor, he querido hacer un recopilatorio de las principales tareas de bastionado en Linux.

Los siguientes puntos se van a centrar únicamente en la seguridad de la máquina, sin extenderse en los elementos externos que se pueden utilizar para securizar el equipo, como NIDS, IPS, firewalls, auditorías periódicas o cañones de fotones.

  • Software siempre actualizado. Imprescindible mantener el sistema siempre a la última en parches de seguridad. No hacerlo es el método más sencillo para que te vulneren o tumben el equipo. La mayoría de malware actual se basa en vulnerabilidades conocidas de un servicio o aplicación para infectar la máquina.
  • Configuración deficiente de las aplicaciones. De nada serviría un servidor altamente bastionado si uno de los servicios disponibles tiene una configuración que permita a un atacante vulnerar su seguridad. Como es imposible abarcar todo lo que esta implicación supondría, enumeraré algunas indicaciones generales, aplicables a la mayoría de aplicaciones:
    1. Ocultar en la medida de lo posible información “jugosa”. Ponerle difícil la recopilación de información a un posible atacante. Por poner unos pocos ejemplos, banners del servidor web, trazas de errores de un Tomcat, metadatos en documentos, transferencia de zona en los servidores DNS, demasiada información visible en los nodos de un servidor LDAP, etc.
    2. Cifrados débiles. Evitar que se puedan utilizar algoritmos de cifrado crackeables a la hora de almacenar contraseñas o en el intercambio de información.
    3. Permisos de usuario y administrador. Ojo con qué se puede ver o hacer con usuarios limitados o invitados.
    4. Política de contraseñas.
      1. Aplicar una política restrictiva cuando se vaya a almacenar una contraseña, como el tamaño mínimo, el uso de mayúsculas, números, caracteres especiales.
      2. Controlar el acceso a la aplicación, con un máximo de intentos, o un delay entre intentos.
      3. Evitar que se pueda utilizar una palabra de diccionario. Se puede usar un agente que lo detecte: http://www.debian-administration.org/articles/59
      4. Y sobre todo, nunca nunca usar la misma contraseña para cada cuenta o servicio o máquina. Vulneran una contraseña, y pueden tomar el control del resto de servicios o máquinas. Como acordarse de todas ellas es imposible para un mortal medio, es recomendable usar herramientas como KeePass o Password Gorilla.
      5. Usar herramientas específicas de hardening, como WAFs o PHPIDS
  • Permisos de ficheros. Comprobar qué permisos tienen ciertos ficheros o directorios críticos, para evitar que usuarios no autorizados puedan leer o escribir en él. Por ejemplo, no se debería tener permisos de escritura a los ficheros inetd.conf, innittab, passwd, crontabs, o la estructura de directorios del servidor web. Éste último es más delicado y tiene sus excepciones y sus restricciones propias cuya explicación se sale del propósito de este post.
  • Monitorizar o restringir el acceso a cuentas privilegiadas. En un servidor crítico, no suele ser habitual que alguien se loguee como root. Puede ser una buena idea que nos llegue una notificación cuando esto ocurra para controlar posibles accesos ilegítimos. También se pueden tomar medidas como denegar el acceso root desde SSH, o permitir solamente a un rango de ips concreto el acceso administrador de una aplicación web.
  • Eliminar servicios innecesarios. Comprobar con netstat -putan qué servicios están a la escucha, y para los que no sean imprescindibles. Podrían ser un potencial vector de ataque. Un ejemplo de servicios que suelen estar a la escucha en una instalación por defecto son RPC, Zeroconf, samba. Si no estás seguro si necesitas ese servicio, la recomendación que escuché en su día fue: detén el servicio, y atento a ver qué explota ;)
  • Eliminar aplicaciones instaladas innecesarias. Una vez se haya pasado el servidor a producción, no es necesario, por ejemplo, mantener ningún compilador. Se puede instalar un sistema base mínimo y a partir de ahí instalar lo imprescindible.
  • Aislar la máquina del resto de equipos. Si el resto de máquinas pertenecientes a una DMZ no necesitan ningún servicio de ti, impídeles el acceso. En caso de que una máquina sea vulnerada, no podrá saltar a otro equipo y la intrusión quedará contenida.
  • Usar un HIDS. Monitoriza el acceso o modificación de ficheros clave, como /sbin, /etc, /var/www para prevenir cambios ilegítimos.
  • Uso de syslog remoto. Podemos enviar los logs a un servidor de syslog remoto. Con esto conseguimos monitorizar los servicios y poder correlar eventos. La herramienta OSSEC es muy recomendada para esto último. También se gana trazabilidad, haciendo más difícil para un intruso borrar su rastro.
  • Usar parches del kernel como SELinux, AppArmor, o PaX. Estas características implementan políticas de acceso a recursos, o protección de espacios de memoria.
  • Protección en el arranque. Establecer una contraseña a la bios y a grub para evitar la modificación del arranque. Sin estas protecciones, un acceso físico ilegítimo al cpd haría que se pudiera arrancar desde una LiveCD o conseguir una shell de root, arrancando el sistema en modo monousuario.
  • Particionar para aplicar distintas directivas de seguridad. Al dividir el sistema en varias particiones se pueden establecer diferentes restricciones a la hora de crear el punto de montaje. Por ejemplo, poner el parámetro noexec a la carpeta /tmp, o ro, nosuid, nodev a /usr, etc.
  • Uso de sudo. Permite granular los permisos privilegiados de una cuenta. Se puede establecer qué ficheros concretos se pueden ejecutar como root. Se consigue con esto fijar unos permisos concretos a operadores o DBAs con únicamente las herramientas que necesiten, y evitar así compartir la clave de root.
  • Otros:

    1. Monitorización de recursos, como RAM, CPU, espacio en disco, o servicios levantados. Imprescindible para un sysadmin conocer en todo momento el estado de un servidor. La herramienta más popular para esta tarea es Nagios.
    2. Backups y plan de contingencias: de nada habría servido todo este bastionado si un fallo de disco duro hace que se pierda toda la información y el servicio quede inaccesible. Para eso es imprescindible un sistema de copias de respaldo y si el servicio que ofrece es crítico, pensar en implantar un sistema de alta disponibilidad que redunde el servicio inmediatamente en caso de que éste caiga.

Obviamente, estas son unas indicaciones generales de securización de un servidor. Cada responsable deberá valorar qué medidas serán adecuadas y cuales serán excesivas de implantar por no ser necesario o por no merecer la pena la implantación por el coste en recursos que ello supondría. Por supuesto, tampoco están todas. Os animo a que comentéis que medidas usáis para bastionar vuestros equipos que no estén contempladas anteriormente.

Comments

  1. Añadiría la sincronización de tiempo con NTP, necesaria para los syslog remotos. Si no, se mezclarán los registros y bailarán en el tiempo. Por supuesto, debería utilizarse con un servidor interno.

    Otra acción que echo en falta sería establecer un plan de auditorías periódicas de seguridad. Ayuda a revisar que está todo OK pasado un tiempo.

    Buen artículo.

    Un saludo.

  2. Bastante completo para dar una idea general de los distintos aspecto a tener en consideración cuando administras un servidor.
    Añadiría el uso de alguna herramienta tipo fail2ban para protegernos de ataques reiterativos.

    Muy buen artículo.

    Saludos

  3. Buenos días¡

    Quería agradecer el tratamiento directo y accesible a los temas de seguridad a nivel informático y web que ofrecéis.

    Un saludo