Configurar un proxy reverso o inverso en Apache

Si contamos con un servicio web (o más) en una LAN el cual es accedido desde Internet, podemos configurar un proxy reverso o inverso para ocultar los servidores que contienen realmente las aplicaciones web. En este caso, planteamos configurar un proxy reverso HTTP en Apache.

Para poder avanzar en esta solución hay 2 puntos a tener en cuenta:

Ahora sí vamos con los pasos:

1. Activar el módulo proxy

En la ubicación donde instalamos Apache, abrimo con un editor de textos el archivo: conf\httpd.conf y descomentamos las siguientes líneas:

LoadModule proxy_module modules/mod_proxy.so
....
LoadModule proxy_http_module modules/mod_proxy_http.so

2. Configurar un VirtualHost

Debemos crear un VirtualHost con la configuración básica actuar de proxy reverso:

<VirtualHost *:<PUERTO_EXTERNO> >
  ServerName <DOMINIO_EXTERNO>

  ProxyRequests Off
  ProxyPreserveHost Off
  ProxyPass /<PATH_EXT>/ http://<DOMINIO_INTERNO>:<PUERTO_INTERNO>/<PATH_INT>/
  ProxyPassReverse /<PATH_EXT>/ http://<DOMINIO_INTERNO>:<PUERTO_INTERNO>/<PATH_INT>/
</VirtualHost>

Analizamos cada una de las directivas:

<VirtualHost *:<PUERTO_EXTERNO> >

Define un VirtualHost. En lugar de * se podría indicar una dirección IP para que solamente se acceda al sitio a través de la misma y separado por dos puntos se indica el PUERTO_INTERNO donde se recibe la petición desde Internet

ServerName <DOMINIO_EXTERNO>

Indica el dominio donde se recibe la petición desde Internet

ProxyRequests Off

Evita que Apache funcione como un servidor proxy que realice forwarding (forward proxy server)

ProxyPreserveHost Off

No se utiliza el host que se indica en la petición que ingresa. Podría ser necesario en caso de que el servicio web lo requiera para evaluarlo de alguna manera.

ProxyPass /<PATH_EXT>/ http://<DOMINIO_INTERNO>:<PUERTO_INTERNO>/<PATH_INT>/

Realiza el mapeo del dominio externo a una url interna. El primer parámetro es un path dentro del DOMINIO_EXTERNO y el segundo es la correspondiente URL interna a la cual se convertirá.

Tip: si el primer parámetro termina con /, el segundo también debe hacerlo para evitar posibles errores en las construcciones de urls.

Ejemplo:

ProxyPassReverse /<PATH_EXT>/ http://<DOMINIO_INTERNO>:<PUERTO_INTERNO>/<PATH_INT>/

Ajusta la url de manera similar a ProxyPass pero en las redirecciones HTTP, dentro de las cabeceras: Location, Content-Location y URI. Es necesario para que funcione correctamente el proxy reverso, de lo contrario las redirecciones HTTP podrían saltarlo.

Ejemplo:

<VirtualHost *:80>
  ServerName externo.servicio.com

  ProxyRequests Off
  ProxyPreserveHost Off
  ProxyPass / http://interno.servicio.com:666/
  ProxyPassReverse / http://interno.servicio.com:666/
</VirtualHost>

En este caso podemos ver que Apache actuará como un proxy reverso para que cuando se acceda a http//externo.servicio.com:80/ se redirija la petición a http://interno.servicio.com:666/

3. Reiniciar Apache y probar

Una vez reiniciado el servicio de Apache podemos probar acceder a desde Internet al dominio externo (y al puerto externo), a partir de un navegador por ejemplo. Mediante DNS la petición se dirige hacia nuestro router LAN, el cual a través de la redirección de puertos la envía al equipo con Apache actuando de proxy reverso. Éste hace la conversión al dominio y puertos internos. La petición llega al servicio web interno correspondiente, quien finalmente la responde. Entonces esta respuesta sigue el mismo camino (pero ahora al revés) hasta mostrar la respuesta en el navegador. Las acciones de redirección de puertos y DNS no aplican en este sentido, pero la respuesta pasa por los dispositivos sabiendo a dónde debe dirigirse.

Anuncios

Información sobre módulos core de Perl

Es importante conocer si un módulo pertenece o no al core de Perl y a partir de qué versión.

Como primer alternativa tenemos Perldoc, donde debemos:

  1. elegir la versión deseada de Perl, en el combo de la izquierda
  2. seleccionar la primer letra del módulo que buscamos en el apartado Modules

si el módulo aparece en el listado, entonces pertenece al core, en la versión elegida.

Pero si necesitamos más información esta forma es bastante limitada y poco productiva. Teniendo instalado Perl, accedemos al directorio bin desde la línea de comandos y ejecutamos corelist con alguno de sus parámetros.

Este comando utiliza internamente el módulo Module::CoreList para generar la salida. También podríamos invocarlo desde un script que desarrollemos si necesitamos realizar alguna tarea más específica.

Listar versiones de perl de las cuales se tiene información

corelist -v

Module::CoreList has info on the following perl versions:
 5
 5.000
 5.001
 5.002
 5.00307
 5.004
 5.00405
 5.005
 ...
 v.5.17.8

La última será la versión de perl que tenemos instalada.

Listar versiones de perl y su fecha de lanzamiento

corelist -r [<PERL_VERSION>]

Ejemplo:

corelist r

Module::CoreList has release info for the following perl versions:
 5           1994-10-17
 5.000       1994-10-17
 5.001       1995-03-14
 5.002       1996-02-29
 5.00307     1996-10-10
 5.004       1997-05-15
 5.00405     1999-04-29
 5.005       1998-07-22
 .....

Listar módulos core y su versión, para cierta versión de perl

corelist -v <PERL_VERSION>

Ejemplo:

corelist -v 5.14.0

The following modules were in perl 5.14.0 CORE
 AnyDBM_File                                      1.00
 App::Cpan                                        1.5701
 App::Prove                                       3.23
 App::Prove::State                                3.23
 App::Prove::State::Result                        3.23
 App::Prove::State::Result::Test                  3.23
 Archive::Extract                                 0.48
 Archive::Tar                                     1.76
 Archive::Tar::Constant                           1.76
 Archive::Tar::File                               1.76
 ....

Listar las versiones de un módulo

corelist -a <MODULO>

Ejemplo:

corelist -a Archive::Zip

Data for 2013-01-20
Archive::Zip was not in CORE (or so I think)

corelist -a Archive::Tar

Data for 2013-01-20
Archive::Tar was first released with perl v5.9.3
  v5.9.3     1.26_01
  v5.9.4     1.30_01
  v5.9.5     1.32
  v5.10.0    1.38
  v5.10.1    1.52
  v5.11.0    1.54
  v5.11.1    1.54
  v5.11.2    1.54
  v5.11.3    1.54
  .....

Ver las diferencias entre 2 versiones de perl

corelist --diff <PERL_VERSION> <PERL_VERSION>

Ejemplo:

corelist --diff 5.10.1 5.12.5

App::Cpan                             (absent)     1.5701
 Archive::Extract                          0.34       0.38
 Archive::Tar                              1.52       1.54
 Attribute::Handlers                       0.85       0.87
 AutoLoader                                5.68       5.70
 B                                         1.22       1.23
 B::Concise                                0.76    0.78_01
 B::Debug                                  1.11       1.12
 B::Deparse                                0.89     0.9701
 B::Lint                                   1.11    1.11_01
 B::Lint::Debug                         (undef)       0.01
 CGI                                       3.43       3.49
 CGI::Apache                               1.00       1.01
 CGI::Carp                              1.30_01       3.45
 .........

Quitar un módulo de Perl

Si utilizamos PPM para administrar módulos de Perl tenemos todas las herramientas allí mismo, incluso la posibilidad de quitar un módulo. Pero en el caso de que hayamos usado CPAN esa opción no está disponible. Podemos borrar manualmente los archivos pero puede quedarnos algún resto olvidado.

Estuve buscando alternativas hasta que encontré un script que se encarga de ellos, invocándolo con un módulo como argumento. Su funcionamiento se basa en el módulo ExtUtils de Perl. El mismo borra todos los archivos asociados y los directorios vacíos.

Creen un archivo con el nombre remove_module.pl, copien el siguiente código dentro y guárdenlo en un directorio conocido:

# remove_module.pl from PerlTricks.com

use ExtUtils::Installed;
use ExtUtils::Packlist;

# Exit unless a module name was passed
die ("Error: no Module::Name passed as an argument. E.G.\n\t perl $0 Module::Name\n") unless $#ARGV == 0;

my $module = shift @ARGV;

my $installed_modules = ExtUtils::Installed->new;

# iterate through and try to delete every file associated with the module
foreach my $file ($installed_modules->files($module)) {
    print "removing $file\n";
    unlink $file or warn "could not remove $file: $!\n";
}

# delete the module packfile
my $packfile = $installed_modules->packlist($module)->packlist_file;
print "removing $packfile\n";
unlink $packfile or warn "could not remove $packfile: $!\n";

# delete the module directories if they are empty
foreach my $dir (sort($installed_modules->directory_tree($module))) {
    print("removing $dir\n");
    rmdir $dir or warn "could not remove $dir: $!\n";
}

Aclaraciones:

El método directory_tree() trae todos los directorios contenidos en las rutas donde existan archivos del módulo (incluyendo el directorio raíz ej: c:\) y luego intenta borrarlos. No se preocupen porque solamente lo hará si están vacíos.

Si bien existe otro método, directories(), que trae solamente los directorios del módulo, esta limitado a aquellos de mayor nivel de profundidad

 

Entonces si lo que deseamos es quitar el módulo DBass, abrimos una línea de comandos y nos ubicamos en el directorio donde guardamos el script y ejecutamos mediante:

perl remove_module.pl DBass

removing C:/Perl/site/lib/DBass.pm
removing C:/Perl/html/site/lib/DBass.html
removing C:/Perl/site/lib/auto/DBass/.packlist
removing C:/
could not remove C:/: Directory not empty
removing C:/Perl
could not remove C:/Perl: Directory not empty
removing C:/Perl/html
could not remove C:/Perl/html: Directory not empty
removing C:/Perl/html/site
could not remove C:/Perl/html/site: Directory not empty
removing C:/Perl/html/site/lib
could not remove C:/Perl/html/site/lib: Directory not empty
removing C:/Perl/site
could not remove C:/Perl/site: Directory not empty
removing C:/Perl/site/lib
could not remove C:/Perl/site/lib: Directory not empty

Basado en:

http://perltricks.com/article/3/2013/3/27/How-to-cleanly-uninstall-a-Perl-module

Administrar módulos de Perl mediante PPM

Una forma de administrar los módulos de Perl pudiendo consultarlos, agregarlos, actualizarlos y quitarlos de nuestra instalación de Perl es mediante PPM (Perl Package Manager) de ActiveState. Alternativamente podemos administrarlos mediante CPAN.

PPM está disponible en 2 modos:

PPM – Interfaz gráfica

Para iniciar la interfaz gráfica podemos ir a Inicio > Perl Package Manager o bien desde  desde una consola lanzar:

ppm

En la ventana que se abre podremos buscar módulos a partir de su nombre (cambiando “::” por “-“) en las vistas de Todos, Instalables y Actualizables.

Una vez encontrado el módulo deseado, lo marcamos mediante el icono con el signo + o directamente presionando la tecla +. Análogamente, para quitarlo usamos el icono con el signo – o la tecla -.

Cuando terminamos de indicar todos los cambios a realizar, los ejecutamos con el icono de la flecha verde hacia la derecha (Ctrl + Enter)

Tendremos que confirmarlos junto con las dependencias a instalar/actualizar que los módulos seleccionados necesiten.

PPM – Consola

Para iniciar PPM en modo consola, abrimos una y tipeamos:

ppm-shell

Esto nos ubicará en el shell:

ppm>

Podemos realizar varias acciones, hasta salir mediante el comando exit o quit.

Consultar los paquetes instalados

ppm> list [ --matching <PATRON> ]

ppm> query <PATRON>

Ejemplo:

ppm> list --matching DBD

┌────────────┬─────────┬───────┬─────────┬──────┐
│ name       │ version │ files │ size    │ area │
├────────────┼─────────┼───────┼─────────┼──────┤
│ DBD-CSV    │ 0.38    │     3 │   31 KB │ perl │
│ DBD-ODBC   │ 1.31    │     9 │  329 KB │ perl │
│ DBD-Oracle │ 1.58    │    22 │  636 KB │ perl │
│ DBD-Pg     │ 2.19.3  │     8 │ 2035 KB │ perl │
│ DBD-SQLite │ 1.37    │     9 │ 6205 KB │ perl │
│ DBD-mysql  │ 4.022   │    13 │ 2963 KB │ site │
└────────────┴─────────┴───────┴─────────┴──────┘
 (6 packages installed matching 'dbd')

Listar archivos de un paquete instalado

ppm> files <PAQUETE>

Ejemplo:

ppm> files Archive::Tar

C:/Perl/html/bin/ptar.html
C:/Perl/html/bin/ptardiff.html
C:/Perl/html/bin/ptargrep.html
C:/Perl/html/site/lib/Archive/Tar.html
C:/Perl/html/site/lib/Archive/Tar/File.html
.......

Instalar un paquete o módulo

ppm> install <PAQUETE>|<MODULO>

Actualizar un paquete o módulo

ppm upgrade <PAQUETE>|<MODULO>

ppm update <PAQUETE>|<MODULO>

Ejemplo:

ppm> upgrade Archive::Zip

Downloading Archive-Zip-1.37...done
Unpacking Archive-Zip-1.37...done
Generating HTML for Archive-Zip-1.37...done
Updating files in site area...done
19 files installed

Borrar un paquete

ppm> remove <PAQUETE>

ppm> uninstall <PAQUETE>

Buscar paquetes en los repositorios

ppm search <PATRON>

El formato de salida depende de la cantidad de paquetes que se encuentren con el patrón. Si hay uno solo, se muestra la descripción del mismo. Si son pocos, se muestra información resumida de cada uno. Si son muchos, se listan el nombre y versión por cada línea.

Ejemplo:

ppm> search DBD-

1: AnyEvent-DBD-Pg 0.03
2: Bundle-DBD-PO 2.10
3: DBD-ADO 2.99
4: DBD-AnyData 0.110
...
30: DBD-iPod 0.01
31: DBD-mysql 4.022
32: DBD-mysqlPP 0.07

ppm> s *temp

1: Bundle-Latemp
A bundle to install external CPAN modules used by
Version: v0.2.4
Released: 2014-01-26

2: File-MkTemp
Make temporary filename from template
Version: 1.0.6
Released: 2000-02-23

3: File-Temp
return name and handle of a temporary file safely
Version: 0.2304
Released: 2013-10-10

...

ppm> describe 3

3: File-Temp
return name and handle of a temporary file safely
Version: 0.2304
Released: 2013-10-10
Author: David Golden <dagolden@cpan.org>
Provide: File::Temp version 0.2304
Require: Carp
Require: Carp::Heavy
Require: Cwd
Require: Exporter version 5.57 or better
Require: Fcntl version 1.03 or better
Require: File::Path version 2.06 or better
...
Require: strict
Require: vars
Repo: ActiveState Package Repository
Link: http://ppm4.activestate.com/MSWin32-x64/5.16/1603/D/DA/DAGOLDEN/File-Te
mp-0.2304.ppmx
CPAN: http://search.cpan.org/dist/File-Temp-0.2304/
Installed: 0.22 (perl)

Listar dependencias de un paquete

ppm> tree <PAQUETE>

Muestra las dependencias recursivamente del paquete indicado.

Ejemplo:

ppm> tree Scalar::Util

package Scalar-List-Utils-1.39
needs Test::More (v0.98 installed in perl area)
package Test-Simple-1.001003 provide Test::More
needs Scalar::Util 1.13 or better (v1.27 installed in perl area)
needs Test::Harness 2.03 or better (v3.26 installed in perl area)
package Scalar-List-Utils-1.39 provide Scalar::Util
package Test-Harness-3.32 provide Test::Harness
(no dependencies)

 

TIP ADICIONAL

Todos los comandos mencionados se pueden ejecutar directamente desde la consola sin ingresar a PPM, de la siguiente manera:

ppm <COMANDO> <ARGUMENTO>

Ejemplo:

ppm search File::Temp

Administrar módulos de Perl mediante CPAN

Una forma de consultar los módulos disponibles y agregarlos a nuestra instalación de Perl es mediante CPAN (Comprehensive Perl Archive Network). Alternativamente podemos administrarlos mediante PPM.

Accedemos a la línea de comandos y lanzamos CPAN mediante:

  • En Linux (con un superusuario)
    • perl -MCPAN -e shell
  • En Windows
    • perl -MCPAN -e "shell"

Si es la primera vez que lo hacemos nos indicará si deseamos hacer la configuración automática (lo que recomiendo) y nos ubicará en el shell:

cpan>

Podemos realizar varias acciones, hasta salir mediante el comando q.

Consultar la información de un módulo

cpan> i <MODULO>

nos indica si el módulo, existe la versión en CPAN (CPAN_VERSION) y si está instalado, el archivo (INST_FILE) y la versión (INST_VERSION)

Por ejemplo:

cpan> i Archive::Zip
Strange distribution name [Archive::Zip]
Module id = Archive::Zip
CPAN_USERID PHRED (Fred Moyer <fred@redhotpenguin.com>)
CPAN_VERSION 1.37
CPAN_FILE P/PH/PHRED/Archive-Zip-1.37.tar.gz
MANPAGE Archive::Zip - Provide an interface to ZIP archive files.
INST_FILE /usr/share/perl5/Archive/Zip.pm
INST_VERSION 1.18

Instalar o actualizar un módulo

cpan> install <MODULO>

instala el módulo indicado, o lo actualiza si tenemos una versión menor. Considerar que instala o actualiza el paquete completo que contiene al módulo!

Por ejemplo:

cpan> install Archive::Zip