Estoy restringiendo el acceso a un directorio a ciertas direcciones IP usando un archivo .htaccess como este:

AuthType Basic
AuthName "Protected"

<RequireAny>
    Require ip 1.2.3.4
</RequireAny>

Eso funciona bien en una configuración de servidor normal, sin embargo, cuando se usa Cloudflare como un proxy WAF, deja de funcionar ya que el servidor recibe todas las solicitudes enviadas a través de la IP de Cloudflare.

Como solución alternativa, es posible utilizar el encabezado "X-Fordered-For" para identificar la dirección IP "real" del cliente, ya que Cloudflare pasa esto con todas sus solicitudes:

AuthType Basic
AuthName "Protected"

SetEnvIf X-Forwarded-For 1.2.3.4$ allowed

<RequireAny>
    Require env allowed
</RequireAny>

¿Es este un enfoque seguro o hay una forma mejor / más segura de limitar el acceso por IP del cliente en Apache cuando se utiliza Cloudflare?

2
WackGet 10 oct. 2019 a las 04:34

1 respuesta

La mejor respuesta

Según IETF RFC 2616, Sección 4.2, un encabezado puede contener una lista separada por comas de valores, y este es el caso de X-Forwarded-For como Cloudflare lo usa.

Si un encabezado X-Fordered-For ya estaba presente en la solicitud a Cloudflare, Cloudflare agrega la dirección IP del proxy HTTP al encabezado:

Example: X-Forwarded-For: 203.0.113.1,198.51.100.101,198.51.100.102 

En los ejemplos anteriores, 203.0.113.1 es la dirección IP del visitante original y 198.51.100.101 y 198.51.100.102 son direcciones IP de servidor proxy proporcionadas a Cloudflare a través del encabezado X-Fordered-For.

Es habitual tomar la IP más a la izquierda como la real, pero no siempre es así.

Si va de esta manera, debe buscar una expresión regular que coincida con su IP como

SetEnvIf X-Forwarded-For ^1\.2\.3\.4 allowed

(IP más a la izquierda, escapando de los puntos)

Una mejor manera (en mi humilde opinión)

Cloudflare también envía el encabezado cf-connecting-ip (que está destinado a ser la última IP en llegar a cloudflare antes de ser enviado a su máquina) y prefiero usar ese.

¿Es este un enfoque seguro o hay una forma mejor / más segura de limitar el acceso por IP de cliente en Apache cuando se utiliza Cloudflare?

Hay una trampa. En este escenario, le está diciendo a Apache:

"tenemos cloudflare en el medio, así que en lugar de su forma nativa de decirle la IP del visitante, veamos este encabezado personalizado".

Ese encabezado personalizado se puede falsificar . Absolutamente. Por lo tanto, también debes decir:

"este encabezado personalizado debe considerarse confiable si y solo la solicitud proviene de una IP de Cloudflare".

Cloudflare enumera explícitamente sus rangos de IP

Por último, debe utilizar mod_remoteip en lugar de crear manualmente una regla SetEnvIf.

Básicamente:

# /etc/apache2/conf-enabled/remoteip.conf
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
...
RemoteIPTrustedProxy 2606:4700::/32
RemoteIPTrustedProxy 2803:f800::/32

Alternativamente, coloque la lista de IP en un archivo separado:

# /etc/apache2/conf-enabled/remoteip.conf
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxyList conf/trusted-proxies.lst

Y

# conf/trusted-proxies.lst
173.245.48.0/20
103.21.244.0/22
...
...
2803:f800::/32
2606:4700::/32

Si dicho encabezado no aparece en la solicitud, Apache recurre a REMOTE_ADDR. Lo mismo ocurre con las solicitudes que provienen de direcciones IP que no son de confianza. Si el encabezado está presente y proviene de Cloudflare, simplemente puede hacer:

Require ip 1.2.3.4

Este enfoque reemplaza la IP donde sea que necesite usarla (registros, autenticación, etc.) y regresa con gracia al REMOTE_ADDR original en casos extremos.

5
ffflabs 10 oct. 2019 a las 05:18