Como dar acceso público a multiples servicios de nuestra red interna utilizando un proxy reverso y hosts virtuales.

Es común tener en nuestra red interna (ya sea de casa o en la empresa) varios servicios corriendo y querer exponer dos o más de ellos públicamente a través de internet. Existen muchas maneras de realizar esto, pero personalmente me gusta una técnica conocida como Proxy Reverso combinada con el uso de hosts virtuales, que describo a continuación:

Algunos términos antes de comenzar

IP Pública: Es la IP que nuestro proveedor de servicio nos da y es única en internet. Generalmente es dínamica, lo que quiere decir que el proveedor no garantiza que sea siempre la misma, aunque no cambia tampoco con tanta frecuencia. El mismo proveedor puede vendernos IPs públicas fijas, pero tienen un costo elevado. La IP Pública nos permite llegar hasta nuestro router desde internet. Podemos saber la IP accediendo desde nuestra red a WhatIsMyIP.com

IP Privada: Es la IP que nuestros dispositivos reciben dentro de la red interna. Generalmente de la forma 192.168.x.x. Esta IP no puede ser accedida desde internet, pues es privada a cada red.

Router: Es el dispositivo que conecta nuestra red interna y el internet. Para mayor detalles del concepto, pueden ver wikipedia. Para el tema de este artículo nos interesa es saber que es el encargado de hacer lo que llamamos Reenvio de puertos.

Reenvio de puertos: Es la capacidad del router de encaminar un paquete de datos proveniente de internet hacia cualquier servidor/dispositivo conectado a nuestra red interna. Dependiendo de la marca/modelo, el reenvio de puertos se configura de manera distinta, pero el resultado es el mismo: un conjunto de reglas que le dicen al router que hacer cuando llega un paquete de datos a nuestra IP Pública en un puerto específico. Por ejemplo, si hay una petición http (cuyo puerto estándar es el 80), podemos especificar que servidor (IP Privada) atenderá la petición.

Dominio: Es el nombre unico que identifica a un sitio web o servicio. Los dominios internamente son traducidos a direcciones IP.

Proxy Reverso: Es un servidor que recibe y despacha las peticiones de entrada y salida. En el caso de este artículo, las peticiones web (a los puertos 80 y 443).

Host Virtual: Es un concepto que permite a un servidor web atender peticiones para varios dominios, como si se tuvieran distintos servidores web.

Instalando el proxy reverso

Necesitamos instalar un servidor que hará la función de proxy reverso. Puede ser físico o virtual (recomendado), y pueden usar cualquier distribución de Linux y ajustar los pasos, yo para este artículo usaré Ubuntu 12.04 Server. Luego de instalarlo (que hay miles de guías en internet de como hacerlo) accedemos a él con el usuario administrador y seguimos estos pasos:

$ apt-get update && apt-get install apache2 ssl-cert
    #NameVirtualHost *:80
    #Listen 80
    
    <IfModule mod_ssl.c>
        # If you add NameVirtualHost *:443 here, you will also have to change
        # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
        # to <VirtualHost *:443>
        # Server Name Indication for SSL named virtual hosts is currently not
        # supported by MSIE on Windows XP.
        Listen 443
        NameVirtualHost *:443
    </IfModule>
    $ sudo a2enmod ssl proxy proxy_http
    $ sudo service apache2 restart
    $ sudo a2dissite default
#/etc/apache2/sites-available/miblog.no-ip.org
#VHost configuration for miblog

<VirtualHost *:443>
        ServerName miblog.no-ip.org
        ProxyPass               /       http://192.168.1.x/
        ProxyPassReverse        /       http://192.168.1.x/
        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
        SSLEngine on
        SSLProxyEngine on
</VirtualHost>

Noten que a pesar de que para acceder al proxy uso https, internamente puedo usar http. El certificado SSL del proxy esta cubriendo todas los servicios internos y por tanto no es necesario instalar un certificado en cada uno de ellos. Por supuesto los datos viajan desde el proxy al servicio sin encriptación, por tanto si desean una seguridad en la red interna, simplemente expongan cada servicio por https y configuran el proxy de manera acorde.

Si no deseamos usar SSL (no recomendado) simplemente usamos una plantilla como la que sigue (y en este caso no comentar la linea Listen 80 en la configuración de puertos de apache):

#/etc/apache2/sites-available/miblog.no-ip.org
#VHost configuration for miblog

<VirtualHost *:80>
        ServerName miblog.no-ip.org
        ProxyPass               /       http://192.168.1.x/
        ProxyPassReverse        /       http://192.168.1.x/
</VirtualHost>

$ sudo a2ensite miblog.no-ip.org
$ sudo service apache2 reload

Cada vez que queremos añadir un sitio nuevo, repetimos los 2 pasos anteriores.

Y listo. Esto es lo que va a pasar la proxima vez que hagamos una petición al dominio:

  1. Nos dirigimos al dominio en el navegador (ejemplo miblog.no-ip.org) y el mismo nos lleva a nuestra IP Pública (puesto que lo hemos configurado asi en nuestro manejador del dominio)
  2. El router redirige la petición al proxy.
  3. El proxy atiende la petición, y basado en el dominio, elige a que servidor debe redirigir la misma.
  4. El servicio responde al proxy, quien a su vez le responde al navegador.

Asi podemos tener varios servicios corriendo y acceder a ellos asignandoles un dominio distinto. Saludos!

comments powered by Disqus