Si has montado un wordpress en un cluster de Kubernetes y lo has publicado, habrás notado que al poco tiempo comienza a dar algunos problemas. No te preocupes no es tu fallo, puedes estar sufriendo un ataque de denegación de servicio. En esta entrada vamos a explicar cómo mitigarlo.
Por si no te suenan las sigas DDoS ( Denial Of Services ) es un tipo de ataque que consigue que un servicio publicado en internet deje de funcionar de forma adecuada. En algunas ocasiones puede ser un ataque completamente dirigido con un objetivo claro y en otras puede ser un daño colateral de cualquier otra actividad. Si se trata del primer caso , la solución puede ser un poco más compleja que la que planteamos hoy aquí , en mi caso se trata de un escaneo masivo desde distintas IP’s a un recurso que está accesible por defecto en WordPress , es “/xmlrpc.php” .
¿Qué hay detrás de XML RPC en WordPress ?
Se trata de un servicio de acceso remoto que permite interactuar con nuestro wordpress. Ideado en 2016 e incluido en la versión 2.6 de WordPress ha sido recientemente “reemplazado” por la API REST. Por tanto es muy probable que no lo necesites más.
¿Por qué es un peligro tenerlo activo?
Desde hace años es posible empleando este servicio que tu WordPress envíe “pings” a otras direcciones web. Un atacante puede usando tu sitio y otros que tengan XML-RPC activo lanzar ataques masivos sobre una Web concreta , por lo que sería partícipe, inconscientemente, del primer caso de DDoS que hemos comentado.
¿Por qué me afecta a mi sitio?
Cuando estos ataques emplean tu web consumen los recursos de tu sistema por lo que puedes experimentar problemas de uso de memoria o lentitud en tu web por falta de CPU. Si prestas atención a tu fichero de logs podrás observar muchas entradas como esta:
1XX.XXX.XXX.XXX - - [01/Jan/2021:00:00:01 +0000] "POST /xmlrpc.php HTTP/1.1" 200 222
¿Cómo puede verificar si está accesible el recurso xmlrpc ?
Una forma muy sencilla es acudir a un servicio de validación, que comprobará tu sitio y te dirá si xmlrpc.php está habilitado.
Cuando indique la url de tu wordpress, si el sitio puede acceder a tu xmlrpc te lo indicará con una pantalla como esta.
En el caso de que esta no sea accesible la pantalla será como la siguiente:
¿Como puedo eliminar el acceso a este recurso?
Cuando se trata de un WordPress alojado en un servicidor VPC , la solución es bastante fácil. Tan solo tenemos que denegar el acceso a este recurso en la configuración de nuestro servidor web. Ya sea mediante configuración o mediante el fichero .htaccess , vamos a indicar como:
En el caso del fichero .htaccess debemos añadir lo siguiente:
# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from none
</Files>
En el caso de un servidor web nginx, la configuración será :
# IMPORTANT: for security purposes, disable access to xmlrpc
location = /xmlrpc.php {
deny all;
return 404;
access_log off;
log_not_found off;
}
¿Qué pasa cuando WordPress se publica en Kubernetes?
Pues en este caso es probable que emplees un balanceador de carga de tu proveedor y un controlador de ingress dentro del cluster Kubernetes para habilitar el acceso a los distintos servicios que publicas.
En este caso debemos modificar el ingress asociado a WordPress para que descarte las peticiones que van dirigidas al recurso xmlrpc mediante un código de error.
Si como en mi caso empleas un controlador de ingress basado en nginx , uno de los más populares y que mejor rendimiento proporcionan tendrás que seguir los siguientes pasos.
Comencemos listando todos los ingress e identificando el que está asociado al dominio.
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
wordpress <none> www.domain.com abcdefXXXXXXX.ab-east-4.elb.amazonaws.com 80, 443 1d20h
Ya hemos identificado como se llama , podemos obtener toda la configuración y enviarla a un fichero con :
kubectl get ingress wordpress -o yaml > wordpress.yaml
Veamos el contenido:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/issuer: wordpress-issuer
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
meta.helm.sh/release-name: wordpress
meta.helm.sh/release-namespace: default
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
labels:
app.kubernetes.io/instance: wordpress
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: wordpress
helm.sh/chart: wordpress-XX.X.X
name: wordpress
namespace: default
spec:
rules:
- host: www.domain.com
http:
paths:
- backend:
serviceName: wordpress-service
servicePort: http
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- www.domain.com
secretName: wordpress-tls
status:
loadBalancer:
ingress:
- hostname: abcdefXXXXXXX.ab-east-4.elb.amazonaws.com
Debemos agregar a esta configuración una nueva anotación que se encargará de denegar el acceso y enviar un error 403 cuando se solicite el recurso “/xmlrcp.php”
Quedando el fichero así:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/issuer: wordpress-issuer
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
meta.helm.sh/release-name: wordpress
meta.helm.sh/release-namespace: default
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/server-snippet: |
location ~* "^/xmlrpc.php" {
deny all;
return 403;
}
labels:
app.kubernetes.io/instance: wordpress
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: wordpress
helm.sh/chart: wordpress-XX.X.X
name: wordpress
namespace: default
spec:
rules:
- host: www.domain.com
http:
paths:
- backend:
serviceName: wordpress-service
servicePort: http
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- www.domain.com
secretName: wordpress-tls
status:
loadBalancer:
ingress:
- hostname: abcdefXXXXXXX.ab-east-4.elb.amazonaws.com
Tan solo debemos aplicar la nueva configuración y de inmediato dejarán de estar accesible el recurso.
Si revisar el log del pod asociado a wordpress observarás de inmediato que desaparecen las peticiones al recurso, y verás como se reduce el uso de recursos de la web.
El original está disponible en el blog de falc0n.es
Top comments (0)