original in en Atif Ghaffar en to es Marcelo E. Buil
Vivo en Suiza y trabajo como webmaster y administrador de unix. Mis pasiones incluyen Linux, Unix, Perl, Apache y software GPL. Podeis saber más sobre mi en mi página web
Tengo en casa una pequeña red con Linux usando enmascaramiento IP y un cortafuegos (de aca en adelante lo llamaremos firewall). Aunque todas las máquinas en mi red pueden acceder a toda la informacion que está en internet, únicamente la máquina que está haciendo el enmascarado de IP se puede acceder desde internet. En mi último artículo sobre Apache, mostré cómo reciclar direcciones IP. En éste artículo mostraré cómo hacer que un webserver detras de su firewall pueda ser accedido a través de internet, sin cambiar ninguna de las reglas de su firewall ni comprometiendo la seguridad de su red. En este artículo veremos como usar la sentencia ProxyPass de Apache para lograr esto. Al público que apunto con este artículo es a los administradores de sistema o cualquiera que está construyendo una red local pequeña o mediana en su hogar o trabajo.
Por un largo periodo en mi LAN, el router (la máquina que estaba haciendo el trabajo de enmascaramiento y de firewall) estaba también como servidor web, servidor de mail, de ftp, de DNS y todo lo demás que se puedan imaginar. Un día tuve la necesidad que una de las máquinas detras del firewall brindase contenidos web y que puedan ser vistos desde internet. También quería tener en línea algunos documentos desde una máquina SGI IRIX que estaba detrás de la red (un servidor de vídeo que ofrecía imagenes en línea). Esta máquina tenía acceso total a internet, pero los usuarios de internet que querían accederlo no lo podían hacer. Aunque no tenía ninguna intención de conectar a la red la máquina IRIX, era necesario que la gente se conectase a ésta. En el trabajo me enfrentaba con el mismo problema con una red y un firewall similar. Cada vez que alguien quería un servidor web para desarrollo que sea accesible desde internet, para uso únicamente de prueba, había que cambiar las reglas del firewall y había que darle a esa máquina una direccion IP externa y comprometer la seguridad de la red.
Después de considerar varias soluciones, implementé una que incluía al Apache y su sentencia ProxyPass. ProxyPass requiere que el mod_proxy esté compilado o cargado como módulo con su servidor Apache. A continuación tenemos la definición del ProxyPass tal y como viene en el manual de Apache.
ProxyPass
Syntax: ProxyPass <path> <url>
Default: None
Context: server config, virtual host
Override: Not applicable
Status: Base
Module: mod_proxy
Compatibility: ProxyPass está disponible unicamente en
Apache 1.1 y sucesivas versiones.
Esta sentencia permite mapear en el servidor local a servidores remotos; el servidor local no actúa como un proxy en un sentido conveniente, pero aparece como un espejo del servidor remoto. <path> es el nombre de la direccion local virtual; <url> es la direccion URL del servidor remoto.
Supongamos que el servidor local tiene la siguiente direccion: http://wibble.org/; entonces
ProxyPass /mirror/foo/ http://foo.com/daría como resultado un pedido local para <http://wibble.org/mirror/foo/bar > para ser convertido internamenet a un pedido proxy a <http://foo.com/bar>.
Mapeando el servidor de v;ideo interno al servidor web externo.
Red interna: hometranet.home 192.168.1.0/255.255.255.0
(En el teatro de internet, intranet, extranet, llamé a mi red
hogareña hometranet)
Red externa: developer.ch 193.192.254.50
Servidor de vídeo (interno) corriendo en el host
cam.hometranet.home dando servicios de vídeo en línea desde
http://cam.hometranet.home:5555/cams/sony/video y fotos desde la
camara en http://cam.hometranet.home:5555/cams/sony/image
Yo quería ver Ios resultados de estas direcciones cuando visitase
http://mozilla.developer.ch/video
y http://mozilla.developer.ch/image
Esto se puede llevar a cabo sencillamente usando la sentencia
ProxyPass de Apache simplemente agregando las siguientes líneas
en httpd.conf o srm.conf
ProxyPass /image http://cam.hometranet.home:5555/cams/sony/image
ProxyPass /video http://cam.hometranet.home:5555/cams/sony/video
Ahora, después de reiniciar el servidor
web (si mod_proxy está disponible),
http://mozilla.developer.ch/image
responde al servidor web de la camara.
El truco de proxypass puede ser usado para mapear un host virtual
entero a una máquina completamente diferente.
Por ejemplo:
docs.sun.developer.ch mapeado a solsparc.hometranet.home
NameVirtualHost 193.192.254.50 <VirtualHost 193.192.254.50> ServerName sun.docs.developer.ch ProxyPass / http://solsparc.hometranet.home/ TransferLog /net/www/logs/sun.docs.access ErrorLog /net/www/logs/sun.docs.errror </VirtualServer>
también se puede derivar a hosts por su dirección IP
<VirtualHost 193.192.254.50> ServerName sun.docs.developer.ch ProxyPass / http://192.168.1.7/ TransferLog /net/www/logs/sun.docs.access ErrorLog /net/www/logs/sun.docs.errror </VirtualServer>
Dado que su principal servidor web está haciendo pedidos al
servidor web interno a petición de sus usuarios, no se puede hacer ningun
logeo razonable al host al que se apunta, en cambio se tienen que cargar
todos los pedidos al host original.
En el caso anterior yo cargué todas las entradas al host principal
sun.docs.developer.ch en lugar de de hacerlo a solsparc.hometranet.home
Resultados de cargarlo en sun.docs.developer.ch (resultado
incorrecto)
197.0.22.3 - - [05/Nov/1999:22:09:04 +0100] "GET /index.html HTTP/1.0" 304 - 187.0.45.67 - - [05/Nov/1999:22:09:04 +0100] "GET /navi.html HTTP/1.0" 304 - 177.0.5.45 - - [05/Nov/1999:22:09:04 +0100] "GET /entrees.html HTTP/1.0" 304 - 227.0.9.67 - - [05/Nov/1999:22:09:15 +0100] "GET /complets.html HTTP/1.0" 304 - 137.0.7.23 - - [05/Nov/1999:22:09:19 +0100] "GET /menu_poisson.html HTTP/1.0" 200 841 193.192.245.73 - - [05/Nov/1999:22:09:25 +0100] "GET /volailles.html HTTP/1.0" 304 - 192.167.0.1 - - [05/Nov/1999:22:09:44 +0100] "GET /agneau.html HTTP/1.0" 304 -
Resultados de cargarlo en solsparc.hometranet.home
192.168.1.1 - - [05/Nov/1999:22:09:04 +0100] "GET /index.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:04 +0100] "GET /navi.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:04 +0100] "GET /entrees.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:15 +0100] "GET /complets.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:19 +0100] "GET /menu_poisson.html HTTP/1.0" 200 841 192.168.1.1 - - [05/Nov/1999:22:09:25 +0100] "GET /volailles.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:44 +0100] "GET /agneau.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:09:56 +0100] "GET /desserts_ind.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:10:00 +0100] "GET /cocktails.html HTTP/1.0" 304 - 192.168.1.1 - - [05/Nov/1999:22:10:10 +0100] "GET /cgi-bin/commande.cgi HTTP/1.0" 200 2146 =20
Lo mismo se aplica a ACLs( listas de
control de acceso) basadas en nombres o IP.
Si se quieren bloquear algunos host/direcciones de IP o se quiere dar
acceso a ciertas direcciones de IP a áreas especiales, esto se
debe hacer en el servidor principal (el que está disponible para acceso
remoto) en lugar de de al servidor local.
Mas aún, no se puede restringir usuarios basándonos en
Directories.
Igualmente se puede usar las sentencias Location o Files o FilesMatch.
El siguiente ejemplo trata algunas de éstas sentencias.
<VirtualHost 193.192.254.50> ServerName sun.docs.developer.ch #esta regla permite usuarios del dominio good.host.com unicamente <Location /private> order deny,allow deny from all allow from good.host.com </Location> #Esta regla prohibe el ayudante del Browser de Microsoft. BrowserMatch MSIE uncool_browser <Location /coolpages> order allow,deny allow from all deny from env=3Duncool_browser </Location> #Esta regla permite unicamente usuariosque se encuentran en el archivo passwd.httpd <Location /coolpages> AuthName "only for registered users" AuthType Basic AuthUserFile "/etc/httpd/passwd.httpd" <Limit GET> require valid-user </Limit> </Location> ProxyPass / http://192.168.1.7/ TransferLog /net/www/logs/sun.docs.access ErrorLog /net/www/logs/sun.docs.errror </VirtualServer>