miércoles, 18 de marzo de 2015

Protegiendo los servidores con UFW

Hace unas semanas se armó bastante revuelo cuando se público un documento de unos estudiantes que encontraron miles de servidores de MongoDB accesibles en internet sin ningún tipo de seguridad. Y unos días despues Salvatore Sanfilippo recordó en la lista de Redis que Redis tiene exactamente el mismo problema con la configuración por defecto.

Como buena práctica, en todos los servicios que tienen acceso por un puerto (memcached, postgres, redis, ...) siempre configuro que solo tengan acceso los servidores de la red privada (o localhost según el caso), pero hace unos meses pensé en darle una vuelta más y añadir seguridad extra por firewall, para asegurarme de que no se me pasaba nada.

La primera idea fue usar directamente IPtables, y como siempre que lo miro, me dio una pereza infinita pelearme con esa sintáxis que se me olvida a los cinco minutos de usarla y busqué otras opciones.

Afortunadamente, para mis necesidades, existe otra opción mucho más asequible en ubuntu: UncomplicatedFirewall (UFW). Hay mucha literatura en internet sobre UFW, por ejemplo esta guía de DigitalOcean y además tenemos un módulo en ansible para configurarlo.

Así que solo he tenido que cambiar el bootstrap de los servidores con ansible bloqueando por defecto todos los puertos y abriendo solo el puerto 22

- name: Set firewall default policy
  ufw: state=enabled policy=reject

- name: Allow ssh access
  ufw: rule=allow port=22
Y luego ir añadiendo los puertos que necesite cada servicio, p.e. en el rol de nginx
- name: Allow web access
  ufw: rule=allow proto=tcp port={{item}}
  with_items:
    - 80
    - 443 
O si queremos dar acceso a solo unas IPs determinadas (por ejemplo en el servidor donde esté la web de administración)
- name: Firewall permissions - Add allowed IPs
  ufw: rule=allow port=443 proto=tcp src={{ item }}
  with_items: admin.allowed_ips
Donde admin.allowed_ips es una lista de IPs permitidas definidas en el yaml de configuración

Y así de simple, con 4 líneas de configuración, ya tenemos los servidores un poco más protegidos :)

He actualizado el proyecto de ejemplo que cree en GitHub cuando hice el post de Bootstrap con Ansible añadiendo esta configuración