Soporte para CGI en Apache

CGI (Common Gateway Interface) es un estándar para poder ejecutar scripts en las páginas web. Aunque un CGI puede estar escrito en muchos lenguajes de programación, la mayoría de los CGIs están escritos en Perl (Practical Extraction and Report Language, perl.org, paquete perl) y los restantes son scripts Bash, el shell de Linux.

Con los CGI podemos crear herramientas muy potentes que interactúen con el sistema y que nos permitan configurarlo remotamente vía web. Una aplicación de este tipo muy usada es Webmin. Pero es importante saber que muchas técnicas para atacar servidores web aprovechan CGIs mal programados, por lo que se debe ser cuidadoso.

Configurar Apache

Para que Apache soporte CGIs escritos en Perl debemos tener Perl instalado. Para comprobarlo:

$ perl -v
This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

Después le diremos a Apache que use CGIs. Para ello editaremos el archivo de configuración de Apache /etc/apache/httpd.conf:

  • comprobaremos que existe la directiva:
    Include /etc/apache/modules.conf

    y que en el archivo /etc/apache/modules.conf exista la siguiente línea para que Apache cargue el módulo de CGIs (la añadiremos si no existe):

    LoadModule cgi_module /usr/lib/apache/1.3/mod_cgi.so
  • descomentaremos la siguiente línea para que Apache sepa que los CGIs son programas y no archivos de texto normales:
    AddHandler cgi-script .cgi .sh .pl
  • la directiva ScriptAlias controla qué directorios contienen scripts:
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    Los CGIs no están en el directorio /var/www/cgi-bin sino que esta dirección está redirigida a /usr/lib/cgi-bin, para que en el directorio de la web haya sólo elementos web y no programas ejecutables. De esta manera, si escribimos en el navegador la dirección http://localhost/cgi-bin/prueba.cgi, Apache buscará el archivo prueba.cgi en el directorio /usr/lib/cgi-bin.

    Para los directorios definidos en directivas ScriptAlias tendremos que crear una directiva Directory en la que se definan los permisos, por ejemplo:

    <Directory /usr/lib/cgi-bin/>
            ...
    </Directory>

Guardamos los cambios y reiniciamos Apache:

# /etc/init.d/apache restart

Ejemplo de CGI en Apache

Para probar si funciona, vamos a crear el CGI más sencillo, Hola mundo. Creamos el archivo hello.cgi con el siguiente contenido:

#!/usr/bin/perl
print "Content-type: text/htmlnn";
print "<html><head><title>Hola mundo</title></head>n";
print "<body>Hola, mundo.</body></html>n";
  • la primera línea le dice a Apache dónde está el intérprete Perl que ejecutará el script.
  • la segunda línea es la cabecera donde le indicamos a Apache qué tipo de datos va a recibir, en este caso una página HTML. Entre la cabecera y el código HTML debe haber una línea en blanco o recibiremos un error Internal Server Error (por eso se incluyen dos retornos de carro nn).
  • las otras dos líneas son el código HTML.

Lo guardamos en /usr/lib/cgi-bin/hello.cgi y le damos permisos de ejecución:

# chmod a+x /usr/lib/cgi-bin/hello.cgi

Después, abrimos el navegador y tecleamos http://localhost/cgi-bin/hello.cgi. Tenemos que referirnos al CGI como si estuviera en el directorio /var/www/cgi-bin: Apache sabrá dónde buscar el verdadero archivo gracias al ScriptAlias. Si todo funciona bien veremos:

Hola mundo CGI

Si miramos el código fuente de la página comprobaremos que sólo contiene código HTML.

Hola mundo CGI fuente

Si no funciona habrá que comprobar si podemos ejecutar el script localmente:

$ perl /usr/lib/cgi-bin/hello.cgi
Content-type: text/html
<html><head><title>Hola mundo</title></head>
<body>Hola, mundo.</body></html>

Si funciona localmente, revisaremos los permisos de ejecución, los módulos de Perl, la configuración de Apache, si lo hemos reiniciado y los logs de error.

Otro ejemplo de CGI en Apache

Veamos otro ejemplo de CGI pero esta vez utilizándolo en la forma habitual, llamando al CGI desde una página web, /var/www/cgi.html, cuyo contenido es:

<html>
  <head>
    <title>Probar un script CGI</title>
  </head>
  <body>
    <p>Este formulario es para probar los CGIs.</p>
    <form method="POST" action="/cgi-bin/cgi.cgi">
      <p>Nombre: <input type="text" name="nombre" size=36></p>
      <p><input type="submit" value="Enviar"></p>
      <p><input type="reset" value="Borrar"></p>
    </form>
  </body>
</html>

El CGI /usr/lib/cgi-bin/cgi.cgi será el siguiente:

#!/usr/bin/perl
print "Content-type: text/htmlnn";
# almacenamos el contenido de la variable POST en $buffer
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# separamos el nombre del campo y el valor
# $campo = nombre del campo
# $valor = valor del campo
($campo, $valor) = split(/=/, $buffer);
# si $valor est&aacute; vac&iacute;o, devolver mensaje de error
if ($valor eq "") {
    print "<html><head><title>Mensaje de error</title></head>n";
    print "<body>n";
    print "<h1>Ha ocurrido un error</h1>n";
    print "<p>El campo "", $campo, "" no puede quedar vac&iacute;o.</p>n";
    print "Por favor, vuelva a intentarlo.n";
    print "</body></html>n";
    # hay un error: salir del script
    exit;
}
# $valor no est&aacute; vac&iacute;o, devolver mensaje de bienvenida
print "<html><head><title>Mensaje de bienvenida</title></head>n";
print "<body>n";
print "<h1>Bienvenido</h1>n";
print "Nombre de usuario: "", $valor, ""n";
print "</body></html>n";

La página http://127.0.0.1/cgi.html es la siguiente:

Probar CGIs

Artículos en la categoría "Servidores (software)"

  1. Monitorizar servidores con Nagios
  2. Monitorizar routers SNMP con MRTG
  3. Administración de máquinas Linux con Webmin
  4. Shell remoto con Telnet
  5. Servidor DNS Bind
  6. Servidor de IPs dinámicas DHCP
  7. Servidor de hora NTP
  8. Servidor proxy Squid
  9. Servidor de correo electrónico
  10. Servidor de terminales LTSP
  11. Servidor web Apache
  12. Soporte para PHP en Apache
  13. Soporte para CGI en Apache
  14. Analizador de logs de Apache
  15. Servidor de base de datos MySQL
  16. Servidor web Lighttpd
  17. Whois: Quién es el propietario de un dominio
  18. Servidor de archivos FTP
  19. Compartir archivos en Linux: NFS
  20. Compartir archivos en Windows: Samba
  21. Control de versiones: CVS y Subversion
  22. Servidor de streaming por Internet
  23. Servidor de streaming en red local

6 Comments:

  1. Vientos, gracias por compartir esto con nosotros, me sirvio mucho tu ejemplo, saludos y gracias!!!

  2. Por fin encuentro de manera detallada para que tu localhost acepte modo cgi.
    Pero si lo configuro mi localhost para que ejecute los script cgi, mis script en php tambien pueden ser levantados????
    Te agradeceria si me repondieras tambien en mi correo, estoy aprendiendo perl y solo lo ejecuto en mi maquina pero sin usar cgi solo del editor de comandos. Pero para web en perl requiero de cgi.
    GRACIAS DE ANTEMANO

  3. Renato Salvatore

    muy practico, gracias!

  4. y si en la sección ScriptAlias del httpd.conf se configura el directamente el directorio donde se encuentra el cgi?

  5. Disculpa pero es que no entiendo como dar permiso de ejecucion ahi me decis que haga esto # chmod a+x /usr/lib/cgi-bin/hello.cgi pero como o en donde lo pego o que hago gracias de antemano..

  6. En que archivo esta la linea donde tengo que descomentar??