[HACK] RewritingProxyTME - Proxy inverso HTTP/HTTPS

Roman Medina-Heigl Hernandez roman at rs-labs.com
Thu Mar 17 17:40:52 CET 2005


J.A. Gutierrez wrote:
> 	Este.... Como me siento un poco gandul para estudiarme a fondo
> 	el tema, quizas no te importaria comentar que diferencias
> 	tiene respecto a las opciones de cache de Apache y a su
> 	directiva "ProxyPass"....

La principal diferencia: el grado de compatibilidad con las
aplicaciones/webs que se encontrarán detrás del proxy inverso.

Si te soy sincero, sólo he usado mod_proxy (el módulo de Apache al que
te estás refiriendo implícitamente) una vez y fue para un caso muy
simple, donde funcionó sin problemas, luego realmente no estoy en
condiciones de ofrecerte una comparativa "real" o más o menos
exhaustiva. Para hacerlo debería haberlo probado en casos difíciles e
incluso críticos (esto sí lo he hecho con mi módulo). No obstante, he
repasado por encima la documentación
(http://httpd.apache.org/docs/mod/mod_proxy.html) y parece que la
mayoría de las "features" de RewritingProxyTME (en adelante RPTME) no
están soportadas, ni siquiera incluso combinando mod_proxy con otros
módulos como mod_rewrite (cuya documentación es simplemente infumable) o
mod_ssl (me parece que es necesario si las aplicaciones detrás del proxy
inverso son HTTPS; mi módulo no lo necesita en este caso).

RPTME (RewritingProxyTME) ha sido elaborado con esta premisa en mente:
debe funcionar con "casi" (nada ni nadie es perfecto) cualquier
aplicación, siempre que ésta hable HTTP/HTTPS, y normalmente sin tener
que configurar reglas especiales para cada aplicación que se desea
integrar con el proxy inverso. Y desde luego, en todo caso sin tener que
modificar la aplicación o web a integrar, en absoluto. Es decir, piensa
que te piden que implementes una especie de proxy inverso "universal",
que debe llevarse bien casi con cualquier web que te vayan pasando,
siendo estas webs desarrollos completamente cerrados, y de diversos
tipos :) Ahora piensa en el funcionamiento de un proxy inverso, y los
problemas que te puedes encontrar... Discutiremos algunos y verás que no
es tan trivial como a priori parece.

- Lo primero que se te vendrá a la cabeza es la "traducción de URLs".
¿Qué ocurre si una página tiene un enlace inmerso del tipo
"http://<ip_de_la_aplicacion>/loquesea" (es lo que yo llamo "enlace
absoluto")? El enlace en principio apuntará a la web (no al proxy), con
lo que cuando el usuario pinche la navegación se interrumpirá.
Conclusión: el proxy debe reescribir parte del contenido de la página,
antes de "pasárselo" al cliente (navegador). Este caso se puede
complicar aún más si los enlaces ni siquiera aparecen en claro, sino que
se generan al vuelo usando código JavaScript o Java. De igual forma hay
que traducir otras cosas, como por ejemplo las redirecciones. Y por
último, datos que un navegador envía en POST/GET, en según qué
escenarios, puede hacer falta "traducirlos".

- La traducción anterior en muchos casos no basta siquiera con aplicar
una expresión regular o cadena de sustitución a las páginas, porque
podrían sustituirse cadenas legítimas que no son realmente enlaces. El
proxy debería poder parsear HTML, entender los tags dentro de los cuales
pueden ir enlaces, y efectuar las sustituciones sólo en esos casos. Es
más, si sustituimos "a saco", también podríamos alterar fichderos .gif,
.exe, .zip que pasen por el proxy (!) ;-)

- Si tu proxy inverso presenta una página de inicio autenticada lo
normal es que utilice una cookie o bien autenticación básica HTTP. El
proxy debería evitar pasar esta cookie de autenticación o bien la
cabecera HTTP de *auth a la aplicación final (de hecho, la aplicación
final puede  ser a su vez autenticada y necesitar de cookies/cabeceras
auth propias, con lo que habría solapamiento, si se pasaran las
cabeceras tal cual).

- Las cookies también deben ser "traducidas". En algunos casos basta con
filtrar la parte donde se indica el dominio/host al que afecta, o en
otros hay que hilar más fino. Por ejemplo, ¿qué ocurre si tienes 2 (o
más) aplicaciones que usan cookies con el mismo nombre y quieres
integrar esas aplicaciones bajo el mismo proxy inverso? Habría
solapamiento de cookies.

¿Cómo soluciona todo esto "mod_proxy"?

En la documentación sólo he podido encontrar que arregla las
redirecciones, de lo demás parece que nada de nada. "Mod_rewrite" creo
que solo vale para reescribir URLs pero no el contenido de las páginas
(y mucho menos partes particulares como un contenido POST que se envía
hacia el servidor; y muchísimo menos ya -rizando el rizo- parseando la
página para averiguar donde puede haber un enlace y donde no). Y aunque
algunas de estas funcionalidades se pudieran hacer jugando con
diferentes módulos y argucias (que creo que no se puede) la
configuración empezaría a complicarse. Sería todo el cotarro complicado
de mantener. RPTME te lo resuelve todo de un plumazo :-)

Por ejemplo, haciendo una búsqueda rápida en Google me he encontrado de
casualidad con:
http://www.issociate.de/board/post/4389/problem_with_cookie_domains_and_mod_proxy,_Apache_1.3.27.html

Que es precisamente uno de los problemas más básicos, y aún asi parece
que mod_proxy no lo supera.

Por último, mi módulo presenta funcionalidades "extra" como:
- la posibilidad de usar un proxy, autenticado o no, para cargar las
páginas de las aplicaciones (creo que en mod_proxy se hace con la
directiva "ProxyRemote" pero no parece que acepte autenticación).
- auto-relleno de formularios y/o autenticación HTTP (muy útil para
centralizar la autenticación en el propio proxy, evitando cualquier auth
en la aplicación final). Esto tampoco lo he visto en mod_proxy.

Y supongo que se me olvidarán cosillas y problemas que son dificiles de
imaginar... hasta que te ocurren, claro. Si echas un vistazo al fuente
verás que esconde algunos trucos. La experiencia es un grado, dicen :-)

Ah, antes de terminar alguna arrojaré alguna piedra sobre mi propio
tejado: una cosa que no tiene RPTME es "caching". Apache lo puede hacer
en combinación con "mod_cache", aunque no tengo claro si funciona en
modo proxy inverso (en modo "forward" sí, lo he leido en la doc). Por
ahora es una funcionalidad que no me preocupa demasiado, ya que RPTME
está orientado a seguridad, no como acelerador (y de todas formas, para
eso yo no pondría un Apache+mod_proxy+mod_cache sino un simple Squid).

Saludos,
-Román



More information about the hacking mailing list