CloudFront
Sobre el tema de la seguridad hablé un poco sobre esto en el siguiente post. Digamos que sería seguridad a nivel de aplicación, por decirlo de alguna manera. Pero luego queda el problema de como queremos lidiar con los ataques diarios que va a sufrir un WordPress. Algunos como los ataques de fuerza bruta o XMLRPC los traté en el post que comenté en link anterior. Pero aún así me faltaba una herramienta para poder mitigar esos ataques, banear los agresores, etc. Entonces comenté que posiblemente habían opciones rápidas de implementar (a priori) como Sucuri. Sin embargo, el propósito de estos posts y mi intención inicial era profundizar sobre el conocimiento de la infraestructura y servicios de AWS para albergar un WordPress. En este sentido aquí es donde entra CloudFront. Y como este post iba de la infraestructura pues voy a explicar (brevemente) el cambio en la infraestructura para poder implementar la CDN, cambios a realizar y alguna medición de rendimiento para poder ver el efecto tiempo después.
Alternativas a CloudFront como CDN
Las alternativas son varias y francamente están todas muy bien. Me he decantado por CloudFront porque es necesario para mi camino hacia el Solutions Architect Professional.
Una que me pareció muy interesante fue la CDN+WAF de Sucuri. Tiene un precio muy ajustado y está muy integrada con WordPress.
Cómo implementar CloudFront con WordPress?
Os dejo aquí varios artículos a continuación. No repetiré lo que se dice aquí, está muy bien explicado.
Links
- https://aws.amazon.com/es/blogs/startups/how-to-accelerate-your-wordpress-site-with-amazon-cloudfront/
- https://www.danneh.org/2015/04/setting-wordpress-amazon-cloudfront/
La configuración que me ha quedado ha sido básicamente esta
- Distribución
- Multiples CNAMES
- ACM para multiples CNAMES
- Origin
- ElasticBeanstalk
- S3
- Behaviors
- Default(*) apuntando a ElasticBeanstalk
- wp-admin/* apuntando a ElasticBeanstalk
- wp-content/uploads/* apuntando a S3
- wp-includes apuntando a ElasticBeanstalk
- wp-login.php apuntando a ElasticBeanstalk
Rendimiento antes de CloudFront
Vamos a ver algunas métricas antes del cambio de pasar de una Ec2 en eu-west-1 a una distribución CloudFront y su impacto en las métricas.
Antes de hacer el cambio, creé unos healtchecks con la opción de latencia activada para medir el comportamiento del WordPress. Vamos a ver como se comportaba hasta ahora.
Rendimiento después de CloudFront
Aquí es donde se puede apreciar mejor el afecto de la CDN. De una latencia desde us-east-1 de 300-400 ms a 10-20 ms.
Aquí también se aprecia que ha bajado ligeramente la latencia.
En la imagen cuesta de apreciar pero se ha pasado de una latencia de 500 ms a 120-160 ms
Y si miramos Gtmetrix, por alguna razón, hemos pasado de Yslow 90% a Yslow 99% !
También es interesante ver los tiempos.
El famoso TTFB es de unos 120 ms desde Canada hasta el CloudFront Edge más próximo. Se puede comprobar con estas métricas que sin tocar el código y simplemente añadiendo una capa de CloudFront conseguimos mejor rendimiento para usuarios alejados de nuestro servidor además de, mejora en la valoración de parámetros como PageSpeed Score o YSlow que quizá afecten positivamente a nuestro SEO.
¿Qué plugin necesito?
Bueno, la mayoría de tutoriales te van a recomendar el W3 Total Cache. El tema es que le tengo un poco de manía a ese plugin. Es un plugin gigantesco que hace muchas cosas. Pero bueno, lo puedes utilizar perfectamente.
En mi caso, yo empecé el WordPress con el plugin de Delicious Brain. Es un plugin que en su versión gratuita te permite subir imágenes a S3 automáticamente y reescribe la URL de las imágenes que subes. Valoré utilizar la versión de pago pero al final no me hizo falta.
Este plugin permite como digo
- subir imágen a S3 CloudFront
- reescribir la URL con el cNAME de tu bucket o distribución
Web Application Firewall (AWS WAF)
Me lo he pasado muy bien con esta herramienta. Para empezar, han habido cambios en WAF desde 2019 cuando sacaron una nueva versión de la herramienta:
In November 2019, Amazon launched a new version of AWS Web Application Firewall (WAF) that offers a richer and easier to use set of features.
https://aws.amazon.com/blogs/security/migrating-rules-from-aws-waf-classic-to-new-aws-waf/
AWS WAF tiene integración con
- Api Gateway
- CloudFront
- ALB
Para utilizar WAF en tu CloudFront o otro recurso necesitarás definir lo que se conoce como Web ACL. En esta Web ACL es donde configuraremos nuestras reglas.
Una de las mejoras de esta nueva versión de WAF es que AWS da sin coste alguno una serie de reglas, que mantiene actualizadas, que de forma fácil puedes implementar. Son las llamadas “AWS Managed Group rules“. Son un conjunto de reglas que evaluan las peticiones que llegan a tu infraestructura y deciden si hay que bloquearlas o no. Puedes poner estas reglas a prueba en un primer momento, en modo “COUNT” para ver su impacto y si, pueden haber problemas etc. Puedes también excluir algunas reglas dentro del conjunto de las AWS Managed Group rules.
Por ejemplo, dado que en este caso lo que voy a proteger es una aplicación de tipo
- PHP
- WORDPRESS
AWS tiene reglas que me vienen perfectas para mi caso como por ejemplo la de:
Esta ManagedRule contiene dentro dos reglas. Una para inspeccionar la query string dentro de la petición y luego, otra regla para el clásico ataque de XMLRPC. Podemos poner todo este conjunto de reglas a funcionar o individualmente, excluir alguna de las reglas.
Hay muchas reglas dentro de las que AWS ofrece gratis como: Core rule set (CRS), Admin protection, Known bad inputs, SQL database, etc.
Luego también reglas de otros proveedores que sí tienen coste como: F5, Fortinet, Imperva, etc.
Luego, también podemos crear nuestras propias reglas y en la versión 2 de WAF han añadido más lógica con lo que se pueden hacer reglas mucho más complejas.
De momento he comenzado con una sola WEB ACL y habilitado un par de reglas. De momento los ataques que más veo son los de XMLRPC.
El otro cambio grande es que ahora, cada regla consume una unidad de WCU (Web Capacity Unit) y el límite por defecto son 1500. Cada regla que añadas, ya sea tuya o de un proveedor consume unos recursos. El límite son 1500. Desconozco si este límite se puede ampliar. Cuanto más compleja es la regla, más consumo de WCU. Por ejemplo, la AWS Managed rule de WordPress application consume apenas 100 mientras que el conjunto de reglas de Fortinet son ya 1000 WCU.
¿Y el precio? Nos van a cobrar por :
- Web ACL 5$
- Regla 1$
- Petición (0,60$ 1 millón de peticiones)
Esta sería una forma sencilla de aplicar WAF. Hay otras muchas maneras. AWS tiene soluciones que despliegan un cojunto de recursos (que también consumen más) que hacen que esta solución sea aún más proactiva a encontrar posibles atacantes. Pero se salen con mucho del objeto de este tutorial pero por si le quieres dar una ojeada:
- https://aws.amazon.com/es/about-aws/whats-new/2017/07/use-aws-waf-to-mitigate-owasps-top-10-web-application-vulnerabilities/
- https://aws.amazon.com/es/solutions/implementations/aws-waf-security-automations/
En su momento valoré Sucuri como CDN + WAF por su más que óptima integración con WordPress pero, el camino de la certificación es uno.
Otras soluciones que no pasen por utilizar CDN o WAF a nivel de infraestructura serán por ejemplo los plugins como:
y tantos otros. El problema que tiene cualquier plugin de este tipo es que añadirá carga a nuestro WordPress. Nuestro WordPress pasará a consumir más CPU, más RAM. Añadiremos más líneas de código a nuestro repositorio. Y es la parte que no me gusta de esa solución. Aún y así son la mejor opción para tener una capa de seguridad adicional sin mucho coste. Pero es otro plugin a mantener y si tenemos WordPress a nivel empresarial, y yo lo he sufrido en mis carnes, no es agradable tener que trabajar con WordPress y el CI/CD de los plugins (yikes).
Las otras opciones clásicas pasan por implementar un WAF dentro de la propia capa de computación (EC2) pero la curva de aprendizaje es costosísima. Hablo del famoso mod_security. Y si los plugins como el de Sucuri nos van a restar CPU y RAM, tanto o más va hacerlo este mod. Porque vamos a cargar a nuestro servidor de aplicaciones Web con otro trabajo más. Y si por ejemplo negociamos el SSL también en este servidor, vamos sumando tareas a hacer y podemos tener problemas de rendimiento. Aún y así mi principal duda para plantearme mod_security y sus reglas OWASP es básicamente el mantenimiento del mismo.
AWS WAF me parece una solución interesante donde adquirir experiencia a lidiar con ataques comunes o simples ataques de fuerza bruta, que es lo que haré a continuación. El típico AB Benchmark que siempre nos comemos, va siendo hora de ponerle freno!