1 votos

Apache: Servir contenido de archivos restringidos

En mi configuración de Apache, tengo un directorio con mis páginas de error en él (404 403). Sin embargo, no quiero que este directorio sea visible directamente - me gustaría acceder a él para devolver un 404. Así que lo que hice fue lo siguiente:

# Use /hidden/404/ as the 404 page
ErrorDocument 404 /hidden/404/
# Use /hidden/403/ as the 403 page
ErrorDocument 403 /hidden/403/
<Directory /path/to/root/hidden/>
    # All requests return 404
    RedirectMatch 404 .*
</Directory>

el problema es que Apache parece no querer servir los archivos en todos en este caso, incluso cuando se lo indique explícitamente (es decir, para gestionar los errores 404 y 403). De hecho, cuando visito /hidden Recibo el siguiente mensaje:

The requested URL /hidden/404/ was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an 
ErrorDocument to handle the request.

¿Hay alguna forma de decirle a Apache que no permita el acceso al directorio y que, al mismo tiempo, sirva esos archivos cuando sea necesario?

0voto

mpasko256 Puntos 121

OK he descubierto una manera de hacerlo.

Lo que hice fue utilizar mod_rewrite que es un módulo de Apache (incluido por defecto en todas las instalaciones) para reescribir sobre la marcha las URL solicitadas. Aquí está el código:

# Custom error pages
ErrorDocument 404 /hidden/404/index.html
ErrorDocument 403 /hidden/403/index.html

# Pretend that /hidden doesn't exist
# (unless this is an internal redirect,
# such as rendering a 404 or 403)
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^/hidden/.* - [L,R=404]

Así que vamos a recorrer estas líneas. El ErrorDocument no han cambiado - sólo dicen qué página debe ser servida cuando se produce un error dado.

La verdadera carne está en el RewriteCond y RewriteRule directivas. Lo que la RewriteRule es la siguiente: si se solicita una url cuya ruta coincide con la expresión regular ^/hidden/.* (esencialmente, cualquier ruta que sea a cualquier cosa en /hidden/ o su subárbol), deje la url sin cambios (eso es lo que hace el comando - significa), pero no interprete más RewriteRule (eso es lo que hacen las directivas L significa), y devolver un código de error 404 (que es lo que el R=404 significa).

Esto, combinado con la ErrorDocument 404 /hidden/404/index.html puede parecer suficiente. El problema, sin embargo, es que cuando Apache va a servir /hidden/404/index.html vuelve a repasar estas reglas. Esto significa que el RewriteRule que a su vez dice renderizar el 404, y todo el asunto se repite infinitamente.

Así, utilizamos el RewriteCond para asegurarse de que esto no ocurra. RewriteCond son condicionales: la directiva RewriteRule sólo se ejecutará si se cumple la condición. La condición en este caso es "la variable de entorno REDIRECT_STATUS es igual a la cadena vacía". Ahora, REDIRECT_STATUS es una variable de entorno que se establece mediante ErrorDocument y contiene el código de estado que se está redirigiendo (por lo tanto, si el archivo ErrorDocument 404 ... se establecería el valor "404"). Sin embargo, si no se ErrorDocument se había ejecutado, entonces REDIRECT_STATUS no se habría establecido, por lo que preguntar por su valor simplemente devolvería la cadena vacía. Por lo tanto, RewriteCond %{ENV:REDIRECT_STATUS} ="" esencialmente dice, "no te molestes en evaluar el RewriteRule a menos que no estemos sirviendo una página de error".


nota: si ha mirado el RewriteRule se habrá dado cuenta de que R debe realizar una redirección explícita. La razón por la que funciona bien en este caso es que existe una característica no documentada de la directiva R que es que sólo redirige en códigos de clase 300. Por lo tanto, R=404 no hace una redirección explícita, sólo una interna.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X