
Cloudflare Access, la parte de control de acceso de Cloudflare One (antes Cloudflare Zero Trust), permite que nadie llegue a wp-login.php ni a /wp-admin sin identificarse antes ante Cloudflare, y su plan gratuito cubre equipos de hasta 50 usuarios. En lugar de limitar intentos fallidos o bloquear direcciones IP después de un ataque, el formulario de acceso de WordPress deja de estar expuesto: Cloudflare intercepta la petición, pide un código por correo o un inicio de sesión con Google o GitHub y solo deja pasar a quien cumple la política.
Las claves de proteger el acceso a WordPress con Cloudflare Zero Trust en 30 segundos
wp-login.php, wp-admin y wp-admin/*.admin-ajax.php necesita una excepción para que no fallen formularios ni tiendas.El planteamiento es distinto al de las medidas habituales. Un plugin de límite de intentos, una regla del firewall o la autenticación en dos pasos actúan cuando la petición ya ha llegado a WordPress. Con Access, el atacante ni siquiera ve el formulario: recibe la pantalla de inicio de sesión de Cloudflare y, si no cumple la política, no pasa de ahí. WordPress sigue pidiendo usuario y contraseña después, así que se trata de una capa añadida, no de un sustituto.
El dominio de la web debe estar activo en Cloudflare, con su DNS gestionado allí (configuración completa) o mediante una configuración parcial por CNAME, y el registro del sitio debe pasar por el proxy, la nube naranja. Si la web todavía no usa Cloudflare, en wpdirecto explicamos cómo configurar gratis el CDN de Cloudflare en WordPress.
También hace falta activar Cloudflare One en la cuenta y elegir un nombre de equipo, que formará la dirección tu-equipo.cloudflareaccess.com. Cloudflare presenta su plan gratuito como pensado para equipos de menos de 50 usuarios, suficiente para la mayoría de webs con unos pocos administradores y redactores. Conviene revisar un detalle de compatibilidad: la documentación de Cloudflare incluye Automatic Platform Optimization (APO), la caché específica para WordPress, entre los productos no compatibles con las aplicaciones autoalojadas de Access, igual que Zaraz.
En el panel de Cloudflare, la ruta actual es Zero Trust > Access controls > Applications. Desde ahí se pulsa Create new application, se elige Self-hosted and private y se añaden los nombres públicos que se quieren proteger con Add public hostname. Para cada uno se selecciona el dominio, el subdominio si lo hay (por ejemplo, www) y la ruta.
Aquí está el primer detalle importante. Según la documentación de rutas de Cloudflare, un comodín como wp-admin/* cubre todo lo que cuelga de esa carpeta, pero no la propia ruta wp-admin. Por eso conviene añadir tres entradas: wp-login.php, wp-admin y wp-admin/*. Las cadenas de consulta, como ?action=logout, no forman parte de la ruta, así que no hace falta contemplarlas. Si el campo de ruta se deja vacío, Access protegerá la web entera.
Después llega la política. Todas las aplicaciones de Access deniegan por defecto, así que hay que crear una política con la acción Allow y, al menos, una regla Include. Lo más directo es el selector Emails con las direcciones de los administradores, o Emails ending in con el dominio de la empresa. Se pueden añadir reglas Require, que funcionan como un «Y» (por ejemplo, exigir además un país o un rango de IP), y reglas Exclude para dejar fuera a alguien concreto.
La propia Cloudflare advierte de dos errores que dejan la puerta abierta: incluir a Everyone en una política Allow, o incluir el método de inicio de sesión One-time PIN como criterio. En el segundo caso, cualquiera con un correo válido podría pedir el código y entrar. El código de un solo uso es el método de identificación; quién puede entrar lo deciden las direcciones de la regla Include.
En la sección de autenticación se eligen los proveedores de identidad. Sin ninguno configurado, el método más sencillo es One-time PIN, que envía un código al correo. Si solo se usa un proveedor, como Google, Cloudflare recomienda activar Apply instant authentication para saltar su pantalla intermedia. El campo Session Duration fija cada cuánto se vuelve a pedir la identificación. Al guardar, basta con abrir una ventana de incógnito, ir a /wp-admin y comprobar que aparece la pantalla de Cloudflare.
Proteger /wp-admin entero tiene una consecuencia que muchas guías pasan por alto: /wp-admin/admin-ajax.php también queda detrás de Access, y ese archivo lo usan desde la parte pública muchos temas y plugins de formularios, tiendas o filtros. Un visitante anónimo recibiría la pantalla de Cloudflare en lugar de una respuesta, y la función dejaría de responder sin un error visible.
La solución es crear una segunda aplicación para la ruta wp-admin/admin-ajax.php con una política Bypass que incluya a Everyone. Cloudflare aplica la regla más específica cuando dos rutas comparten raíz, así que esa excepción prevalece sobre la de wp-admin/*. El mismo criterio sirve para wp-admin/admin-post.php si algún formulario público lo usa. Hay que tener en cuenta que Bypass desactiva todos los controles de Access para esa ruta y que esas peticiones no quedan registradas.
La API REST (/wp-json) y wp-cron.php no cuelgan de /wp-admin, así que no se ven afectadas. xmlrpc.php tampoco, y sigue siendo una vía habitual de ataques de fuerza bruta; si no se usa, lo razonable es bloquear el abuso de XML-RPC con una regla de Cloudflare o añadirlo a la aplicación protegida.
Access protege el tráfico que pasa por Cloudflare. Si alguien conoce la IP real del servidor, puede saltarse el proxy y llegar a wp-login.php directamente. La documentación de Cloudflare lo plantea sin rodeos: si la aplicación es accesible públicamente, hay que proteger la IP de origen por otros medios y validar el token que emite Access.
Hay tres formas de cerrarlo. La primera es publicar la web mediante Cloudflare Tunnel, de modo que el servidor no acepte conexiones entrantes desde internet, y activar en el túnel la opción Protect with Access, que valida el token. La segunda es limitar el cortafuegos del servidor a los rangos de IP de Cloudflare. La tercera es comprobar en el propio servidor la cabecera Cf-Access-Jwt-Assertion, un token firmado que Cloudflare añade a cada petición autorizada. Las claves públicas para validarlo están en https://tu-equipo.cloudflareaccess.com/cdn-cgi/access/certs y rotan cada seis semanas, según la documentación.
La validación del token puede hacerse desde WordPress con DIESIS JWT Auth for Cloudflare Access, de DIESIS Media. El plugin revisa la cabecera en las rutas configuradas (por defecto /wp-login.php*, /wp-admin y /wp-admin/*), comprueba la firma RS256 con las claves del equipo, la caducidad, el emisor y la audiencia de la aplicación, y devuelve un error 403 si algo falla. Se configura con el dominio del equipo y la etiqueta AUD de la aplicación, admite una lista de correos permitidos y rutas excluidas, y viene desactivado hasta completar los ajustes para evitar bloqueos.
No sustituye al inicio de sesión de WordPress ni crea usuarios, y no acepta tokens de servicio. Sus autores avisan de que las rutas de máquina a máquina, como el cron, XML-RPC o la API REST, deben excluirse o quedar públicas tanto en el plugin como en Access. Es un desarrollo reciente: la versión 1.4.3 tiene menos de 10 instalaciones activas, requiere WordPress 6.8 y PHP 8.1 y está probada hasta WordPress 7.1.2. Si el plugin bloquea el acceso, basta con renombrar su carpeta en wp-content/plugins.
La segunda opción va en otra dirección. Cloudflare Zero Trust Login, publicado en GitHub por natbienetre con licencia MPL-2.0, aprovecha la sesión de Access para iniciar sesión en WordPress de forma automática. Según su descripción, puede desactivar el formulario propio de WordPress, añade un campo para asociar el correo de Cloudflare a cada usuario y puede crear la cuenta si no existe. Sus instrucciones piden tener Cloudflare Tunnel instalado en el servidor y su lista de tareas reconoce que aún no cierra la sesión de WordPress cuando caduca la de Cloudflare. Es un proyecto pequeño, con cinco estrellas y cambios recientes centrados en su integración continua, así que conviene probarlo antes en un entorno de pruebas.
Un último apunte: cerrar sesión en WordPress no cierra la sesión de Access, que dura lo que se haya fijado en la aplicación. En equipos compartidos conviene usar duraciones cortas. Y Access no elimina otros riesgos, como el robo de cookies de sesión, aunque sí reduce mucho la superficie expuesta.
Sí, para equipos pequeños. Cloudflare ofrece un plan gratuito de Cloudflare One pensado para menos de 50 usuarios, suficiente para proteger el acceso de los administradores de una web.
wp-login.php, wp-admin y wp-admin/*, porque el comodín no cubre la carpeta raíz. Después hay que dejar fuera wp-admin/admin-ajax.php con una política Bypass.
Sí, si la IP de origen es accesible. Para evitarlo hay que usar Cloudflare Tunnel, limitar el cortafuegos a las IP de Cloudflare o validar el token de Access en el servidor, por ejemplo con el plugin DIESIS JWT Auth.
No por defecto: añade una identificación previa y WordPress sigue pidiendo sus credenciales. Plugins como Cloudflare Zero Trust Login permiten iniciar sesión en WordPress automáticamente con la identidad de Access.
Fuentes:
