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:
Si miramos el código fuente de la página comprobaremos que sólo contiene código HTML.
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á vací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ío.</p>n"; print "Por favor, vuelva a intentarlo.n"; print "</body></html>n"; # hay un error: salir del script exit; } # $valor no está vací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:
Vientos, gracias por compartir esto con nosotros, me sirvio mucho tu ejemplo, saludos y gracias!!!
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
muy practico, gracias!
y si en la sección ScriptAlias del httpd.conf se configura el directamente el directorio donde se encuentra el cgi?
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..
En que archivo esta la linea donde tengo que descomentar??