Archive for the ‘Apache’ Category

PHP4 y PHP5 juntos, pero no revueltos

Friday, July 29th, 2005

Si quieres tener en un mismo ordenador las versiones PHP4 y PHP5 instaladas y funcionando al mismo tiempo, en esta historía te explico uyn par de formas ridiculamente fáciles de hacerlo.

Eso sí, es necesario disponer de un ordenador Linux y tener instalado el “mágico” módulo del kernel llamado “binfmt_misc”, bueno y en realidad tampoco es que sea tan fácil hacerlo…

Instalación de Apache, PHP4, etc.
Lo primero es instalar Apache y PHP4 de la forma habitúal, es decir, como másd te apetezca. Puedes descargarte las fuentes y compilarlas tu mismo, puedes usar Yum, APT o up2date para instarlos, etc.

Instalación de PHP5
Ahora comienza la parte interesante. Debes compilar e instalar PHP5 en lo que personalmente denominio “como CGI”, es decir, que no debes instalarlo como módulo de Apache sino como un binario independiente.

Para compilar PHP5 como un binario independiente y válido para CGI debes lo primero que debes hacer es descargar la última versión estable de PHP5 desde la web de PHP y luego:

$ tar zxvf [archivo].tgz
$ cd [directorio]
$ ./configure --prefix=/usr/local/php5 --enable-force-cgi-redirect --with-xml --enable-bcmath --enable-calendar --enable-exif --enable-mbstring --enable-mbstr-enc-trans --enable-mbregex --with-mysql --with-pear --enable-xslt --enable-sockets --enable-track-vars --enable-versioning
$ make
$ make install

Tras hacer esto, el binario de PHP5 estará ubicado en:

/usr/local/php5/bin/php

En estos momentos, suponiendo que ya tenemos Apache instalado con la configuración más habitual, ya podríamos hacer programación CGI usando PHP5. Esto significa que podríamor crear scripts PHP5 y ejecutarlos a través de Apache, siempre que los nombraras con mombres tipo “hola.cgi” o “phpinfo.cgi” y siempre que incluyesemos la ubicación del binario PHP5 en la primera línea del script:

#!/usr/local/php5/bin/php
< ?php
echo "Hola mundo!";
?>

Configurar Apache
El hecho de poder utilizar la extensión “cgi” para un archivo PHP5 está muy bien, pero no nos permite identificar el tipo de archivo fácilmente, por lo que nos interesa utilizar la extensión “php5″.

Pero no podemos llamar “hola.php5″ al script de arriba y espera que funcione, primero tendremos que hacerle saber a Apache que los archivos con extensión “php5″ son scripts CGI y que los debe tratar como tal.

Para hacer esto, debemos abrir el archivo de configuración principal de Apache, es decir, el “httpd.conf” y localizar una línea similar a la siguiente:

AddHandler cgi-script .cgi .pl

Una vez localizada, añadiremos la extensión “.php5″ a dicha línea a fin de que Apache sepa que los archivos con extensión “php5″ son scripts CGI:

AddHandler cgi-script .cgi .pl .php5

Una vez hecho esto, no debemos olvidarnos de reiniciar Apache.

¿Un poco de mágica?
Pero lo de incluir la ubicación del binario PHP5 en la primera línea de cada uno de nuestros scripts es suficientemente aburrido como para utilizar el modulo del kernel “binfmt_misc” y hacer un poco de mágia.

Tal y como se intutuye de lo que se indica en el sitio web de binfmt_misc, “Binfmt_misc provides the ability to register additional binary formats to the Kernel without compiling an additional module/kernel. Therefore binfmt_misc needs to know magic numbers at the beginning or the filename extension of the binary.”, este módulo nos permite forzar al kernel de Linux para que trate un archivo con extensión “php5″ como una aplicación PHP5 y por lo tanto, ejecute el código usando el binario de PHP5.

Ya se que no me he explicado nada bien, pero lo mejor es que lo pruebes tu mismo, ejecuta los siguientes comandos:

$ modprobe binfmt_misc
$ cd /proc/sys/fs/binfmt_misc
$ echo ':PHP5:E::php5::/usr/local/php5/bin/php:' > register

El primero comando carga el módulo “binfmt_misc” en el kernel y el segundo hace que el kernel identifique cualquier archivo con extensión “php5″ como un archivo PHP5 y como tal, utilize el binario “/usr/local/php5/bin/php” para ejecutarlo.

Ahora pruebalo, crea el siguiente script y llamalo “hola.php5″:

< ?php
echo "Hola mundo!";
?>

Ahora accede a este script a traves de Apache. Funciona, ¿verdad?

Tras verificar que funciona, añade las siguientes líneas al archivo “/etc/rc.local”:

# Hacer que .php5 sea ejecutado por el interprete PHP5
modprobe binfmt_misc
cd /proc/sys/fs/binfmt_misc
echo ':PHP5:E::php5::/usr/local/php5/bin/php:' > register

De esta forma, el módulo “binfmt_misc” se cargará y se configurará para identificar a los archivos PHP5 cada vez que se inicie el sistema y no tendrermos que ejecutar dichos comandos cada vez que…

Pues esto es todo.

Protegiendo directorios. Autentificación básica de Apache

Tuesday, April 19th, 2005

Este artículo describe como funciona la autentificación básica de Apache y como proteger recursos fácilmente usando esta caracterísitica del servidor. Este artículo es la versión revisada y corregida de aquel articulo que escribí hace ya más de uno año y que lo podéis leer aquí.

Antes de empezar indicar que este artículo es la versión revisada y corregida de aquel articulo que escribir hace ya más de uno año y que lo podéis leer aquí.

El servidor Apache permite el uso de los llamados “distributed configuration files”, osea “ficheros de configuración distribuidos”. Estos permiten personalizar el funcionamiento del servidor en un directorio concreto sin necesidad de modificar el fichero de configuración principal de Apache, el “httpd.conf”.

Por defecto, estos “ficheros de configuración distribuidos” deben llamarse “.htaccess”, pero si no te gusta ese nombre lo puedes cambiar facilmente según se explica en este mini artículo.

Cada vez que un cliente le hace una petición al servidor Apache, es decir, cada vez que tú con tu navegador accedes a una página web, Apache busca uno de esos ficheros .htaccess en el mismo directorio de la página que has pedido a Apache. Si encuentra uno de esos .htaccess lo lee y lo interpreta antes de mostrarte la página que le has pedido. De esta forma, si en el .htaccess se indica la necesidad de autentificar a los clientes, Apache lo hará. Y precisamente de esto trata el artículo, de la autentificación de usuarios mediante el módulo mod_auth_basic, el método de autentificación más básico y sencillo de implementar de Apache.

La implementación más básica

A continuación la implementación más básica del método de Autenficación Básica de Apache, donde se limita todo tipo de acceso (GET, POST y HEAD) a un determinado directorio:

AuthType Basic
AuthName "Directorio Protegido"
AuthUserFile /var/www/dir/.htpasswd
require valid-user

La sentencia “AuthType Basic” indica el método de autentificación que deseamos usar. En nuestro caso el método de autentificación básico.

AuthUserFile debe indicar la ubicación completa del fichero que contiene los datos de los usuarios (nombre de usuario y contraseña). No es válido indicar una ubicación relativa.

El fichero que contiene los datos de autentificación de los usuarios, aunque habitualmente se le llame “.htpasswd”, puedes usar cualquier nombre.

En Windows, las contraseñas del fichero “.htpasswd” pueden o no estar encriptadas, en todos los demás sistemas es necesario que estén encriptadas.

En sistemas Unix (Linux, BSD, etc.) este fichero lo debes crear (y actualizar) mediante la herramienta htpasswd de Apache. En sistemas Windows lo puedes hacer manualmente (sin encriptar las contraseñas) o usando htpasswd.

AuthName indica el nombre que deseas darle al recurso. Este nombre aparecerá en la ventanita de autentificación donde el usuario tiene que introducir su nombre de usuario y contraseña, por lo que es recomendable darle un nombre descriptivo.

Suponiendo que aún no dispones del fichero .htpasswd, que deseas crearlo en /var/www/dir y que quieres permitir el acceso al usuario “pepito”, debes ejecutar el siguiente comando en la línea de comandos:

$ htpasswd -c /var/www/dir/.htpasswd pepito

Para añadir un nuevo usuario a un fichero “.htpasswd” ya existente, ejecuta el siguiente comando:

$ htpasswd /var/www/dir/.htpasswd nuevo_usuario

Cada vez que ejecutes cualquiera de los comandos mencionados se te pedirá que introduzcas la contraseña del nuevo usuario.

La sentencia “Require valid-user” indica que se limitará todo acceso ya sea de tipo GET, POST o HEAD y que solo se permitirá el acceso a los usuarios que aparezcan en el fichero “.htpasswd”.

Limitando el acceso dependiendo del método HTTP utilizado

Si solo deseas limitar el acceso POST, de forma que cualquiera pueda ver los contenidos del directorio
/var/www/dir, pero solo los usuarios que aparezcan en “.htpasswd” puedan enviar peticiones de tipo POST usa la siguiente configuración:

AuthType Basic
AuthName “Directorio Protegido"
AuthUserFile /var/www/dir/.htpasswd
&lt;Limit POST&gt;
require valid-user
&lt;/Limit&gt;

Esto podría ser útil, si por ejemplo, el el directorio en cuestión tienes algún formulario para subir ficheros al servidor. Usando la configuración sugerida, solos los usuarios autentificados podrían hacerlo.

Autentificación de grupos

Supongamos que disponemos de algunos documentos ultra secretos que solo el grupo de administradores puede ver. Siempre podrías crear un nuevo directorio donde ubicar estos documentos y duplicar el procedimiento descrito anteriormente. Esto supondría la necesidad de mantener varios ficheros “.htpasswd”, lo cual resultaría bastante incomodo. Por esto existe una forma alternativa y mucho más sencilla.

Suponiendo que nuestro nuevo directorio ultra secreto es /var/www/dir/secreto, creamos un .htaccess con el siguiente contenido y lo ubicamos en el nuevo directorio:

AuthType Basic
AuthName “Directorio secreto"
AuthUserFile /var/www/dir/.htpasswd
AuthGroupFile /var/www/dir/secreto/.htgroup
require group administradores

Como puedes ver, en AuthUserFile se indica el mismo fichero .htpasswd, no es necesario crear uno adicional.

AuthGroupFile indica la ubicación completa del fichero que relaciona los grupos y los usuarios pertenecientes a cada grupo.

El fichero AuthGroupFile se edita manualmente, usando tu editor de texto preferido, y su formato es el siguiente:

nombre_del_grupo: usuario1 usuario2 usuario3

Es decir, que suponiendo un grupo “administradores” y que solos los usuarios “pepito” y “jaimito” pertenecen al mismo, nuestro fichero .htgroup tendría el siguiente aspecto:

administradores: pepito jaimito lola juanmi pedrito

La sentencia “require group administradores” permitiría el acceso únicamente a los usuarios que pertenezcan al grupo “administradores” y que se autentifiquen correctamente según los datos del fichero “.htpasswd”.

¿Un único administrador?

Continuando con lo anterior… y ¿si únicamente el usuario pepito fuera administrador? En vez de crear el fichero .htgroup indicando que pepito pertenece al grupo “administradores” e incluir la directiva AuthGroupFile en nuestro fichero “.htaccess”, crearíamos un .htacces con el siguiente contenido:

AuthType Basic
AuthName “Directorio Protegido"
AuthUserFile /var/www/dir/.htpasswd
require user pepito

De esta forma, solo “pepito” podría acceder a nuestro directorio ultra secreto.

Si en algún momento decidiésemos dar acceso al usuario “lola” a nuestro directorio ultra secreto, solo tendríamos que modificar el fichero .htaccess anterior de la siguiente forma:

AuthType Basic
AuthName “Directorio Protegido"
AuthUserFile /var/www/dir/.htpasswd
require user pepito lola

Y esto es todo por ahora…

¿Donde guardo mis scripts y ficheros de configuración?

Tuesday, April 19th, 2005

Todo sitio web necesita de algún fichero o scripts donde se guardan datos sensibles que el servidor necesita para restringir el acceso a usuarios no autentificados, conectarse a una base de datos, etc.

Existen multitud de situaciones donde uno se pregunta (o al menos debería) cual será el sitio más seguro para guardar ese script o archivo de configuración necesario para que nuestro sitio web o software funcione correctamente.

Estos archivos de configuración suelen contener los datos necesarios para que un programa se pueda conectar a una base de datos, restringir el acceso a un directorio protegido por htaccess, verificar la autenticidad de un usuario que pretenda acceder a sistema de administración de un sitio web, etc. Por lo tanto, los archivos de configuración son necesarios y en alguna parte debemos colocarlos.

La mejor opción es situar esos archivos en un directorio al cual no se pueda tener acceso desde internet, por lo que solo se puede tener acceso a ellos desde un script situado en el mismo servidor. Supongamos que la estructura de directorios de tu sitio web es el siguiente:

/home/tudominio
/home/tudominio/mail
/home/tudominio/stats
/home/tudominio/www

El directorio “/home/tudominio” es tu directorio personal, mientras que “home/tudominio/www” es el directorio público, al cual se puede acceder desde internet. Tus archivos de configuración deberían estar fuera de este directorio público, por lo tanto, podrías crear “/home/tudominio/config” y guardar allí todos tus ficheros de configuración.

Estos archivos de configuración solo serán accesibles desde scripts situado en tu servidor ya que al estar fuera del directorio público, la única forma de incluirlos en un script es usando la estructura de directorios.

&lt;?php
include('/home/tudominio/config/conexion.conf');
?&gt;

Manteniendo, los archivos de configuración fuera del directorio público, nadie puede usarlos en un script situado en un ordenador remoto. Supongamos, que tu archivo de configuración estuviera en el directorio “/home/tudominio/www/conexion.conf”, cualquiera podría acceder a sus datos de la siguiente forma:

&lt;?php
include('http://tudominio.com/conexion.conf');
?&gt;

¿Que pasa con los usuarios locales?

Reubicando estos archivos en el directorio “/home/tudominio/config” evitamos que se pueda acceder a ellos desde Internet, pero el resto de usuarios que posiblemente compartan tu mismo servidor si que pueden acceder a ellos.

Para evitarlo debes asegurarte de configurar correctamente los permisos de estos archivos y del directorio “/home/tudominio/config”. La forma correcta de hacerlo varia de servidor a servidor, pero en general, la siguiente configuración resultará correcta:

$ chmod 751 /home/tudominio/config
$ chmod 644 /home/tudominio/config/*

En realidad, con los permisos sugeridos no impedimos que los usuarios locales accedan a tus archivos, pero se lo ponemos un poco más difícil. Y obviamente existen métodos muchos más seguros y efectivos pero su explicación no es objeto de este artículo.

Lo mismas medidas preventivas son aplicables a los archivos .htpasswd, las imagenes (puedes evitar el Hotlink), etc. Siempre es preferible colocar los archivos sensibles fuera del directorio público.

Introducción a los “Server Side Includes” (SSI)

Tuesday, April 19th, 2005

Los Server Side Includes, o simplemente SSI, nos proporcionan una sencilla forma de automatizar ciertos aspectos de la creación y posterior mantenimiento de nuestro sitio web, y sin necesidad de saber programar en Perl o PHP.

Los SSI (Server Side Includes) son directivas insertadas en páginas HTML que nos permiten inserción de contenido generado dinámicamente en nuestras páginas web. Como PHP pero mucho más fácil.

Para que los SSI funcionen, las páginas HTML que las incluyen deben ser evaluadas por Apache antes de mostrar su contenido al navegador cliente. Por este motivo, servir páginas que hacen uso de SSI consume más recursos del sistema que el servir páginas HTML normales.

El uso de SSI consume más recursos del sistema su utilización supone una carga adicional del servidor. Aunque esto es inevitable y lo mismo ocurre con los scripts en PHP o CGI, es una cuestión de comodidad contra eficiencia. Obviamente, no debemos hacer que Apache evalúe todas las páginas HTML antes de devolverlas al cliente, ya que seguramente en muchas de ellas no habrá directivas SSI y estaremos sobrecargando el sistema inútilmente. Por lo tanto, debemos diferenciar las páginas HTML y las que incluyen instrucciones SSI, para ello nada mejor que la solución estándar, la de usar la extensión "shtml" con las páginas que deben ser evaluadas.

Configurar Apache para que permita SSI

Para permitir el uso de SSI en todo tu servidor o en un directorio concreto debes tener la directiva "Options All" o "Options +Includes" en el fichero de configuración de Apache, httpd.conf, o en un archivo htaccess. Debes tener algo así:

<directory "c:/home">
Options +Includes
Order allow,deny
Allow from all
</directory>

Además, como queremos que Apache únicamente evalúe los archivos que tengan extensión "shtml", esto también tendremos que indicarlo en httpd.conf o en el archivo htaccess que usemos. Para ello, en caso de usar la versión 2.0 de Apache, debes incluir las siguientes líneas:

AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

En cambio, si utilizas la versión 1.3 de Apache, la configuración se hace con esto:

AddType text/html .shtml
AddHandler server-parsed .shtml

Pero que ocurre cuando queremos usar SSI en una página web, pagina.html, que previamente no las usaba y que por lo tanto su extensión no es "shtml"? Tenemos dos opciones:

  • Renombrar pagina.html por pagina.shtml y cambiar todos lo enlaces a pagina.html por pagina.shtml.
  • Usar la directiva XBitHack de Apache. Esta directiva nos proporciona una forma de indicarle a Apache de uno en uno las páginas sin extensión "shtml" que queramos que evalúe. Para activar XBitHack incluye la siguiente línea en la configuración:

    XBitHack on

    Para indicar a Apache que evalúe una página concreta, simplemente tenemos que dar permisos de ejecución a este fichero:

    $ chmod +x pagina.html

Uso de SSI

echo permite imprimir ciertos datos como por ejemplo la fecha local, fecha GMT, fecha de la ultima modificación del fichero, variables definidas previamente, variables de entorno como DOCUMENT_URI, REMOTE_ADDR, SERVER_NAME, SERVER_PORT, etc.

La siguiente directiva imprime la fecha y hora GMT:

< !###echo var="DATE_GMT"##>

La siguiente directiva muestra la fecha y hora local:

< !###echo var="DATE_LOCAL"##>

La siguiente directiva muestra la fecha y hora de la última actualización del fichero:

< !###echo var="LAST_MODIFIED" ##>

La siguiente directiva muestra el valor de la variable NOMBRE, la cual como se puede observar ha sido definida previamente:

< !###set var="NOMBRE" value="Juan García" ##>
< !###echo var="NOMBRE" ##>

La siguiente directiva muestra el número IP del cliente:

< !###echo var="REMOTE_ADDR" ##>

include permite la inserción del contenido de otro fichero en el fichero actual. Resulta muy práctico para incluir una cabecera común en todos nuestros documentos:

< !###include virtual="cabecera.html" ##>

exec permite la ejecución de un programa externo desde el documento actual. Podemos ejecutar un programa ejecutable pasándole comandos de la siguiente forma:
< !###exec cmd="mkdir -m 0755 /home/tudominio/directorio_nuevo" ##>

Aunque también podemos ejecutar un script CGI:
< !###exec cgi="script.cgi" ##>

Debemos comentar que esta última directiva, exec, suele estar deshabilitada en la mayoría de los entornos de hosting virtual, por lo que sino funciona… posiblemente esta sea la causa.

config permite configurar la forma en la que se muestran ciertos tipos de datos.

La siguiente directiva configura el mensaje de error por defecto:

< !###config errmsg="Ha ocurrido un error" ##>

La siguiente directiva configura el formato en el que se muestras las fechas:

< !###config timefmt="%A %B %d, %Y" ##>
Hoy es < !###echo var="DATE_LOCAL" ##>

Controlar el acceso de Robots a tu sitio usando el archivo “robots.txt”

Tuesday, April 19th, 2005

En ciertas ocasiones nos puede interesar impedir que los robots de los buscadores indexen ciertos directorios o documentos de nuestro web, para ello se usan los archivos "robots.txt".

En ciertas ocasiones nos puede interesar impedir que los robots de los buscadores indexen ciertos directorios o documentos de nuestro web, para ello se usan los archivos "robots.txt".

El archivo robots.txt no es más que archivo de texto que contiene una lista de instrucciones escritas en un formato estandarizado y que están dirigidas a todos o a ciertos robots en concreto. La función de estas instrucciones es la de prohibir que ciertos documentos o directorios que no queramos compartir sean indexados por los spiders.

El fichero robots.txt es lo primero que los crawlers buscan cuando acceden a un sitio web, posteriormente pasan a indexar el resto de nuestra web. El fichero robots.txt debe esta situado en el directorio raíz de nuestro sitio web, es decir, deberíamos poder acceder a el desde la dirección tudominio.com/robots.txt.

El motivo por el cual robots.txt debe esta colocado en nuestro directorio raíz es por es simple hecho de que los spiders solo lo buscan allí. Si lo encuentran, lo leerán y supuestamente acataran las instrucciones allí indicadas. Pero si no lo encuentran, darán por hecho que pueden indexar todos los documentos que estimen oportuno.

Puede ocurrir que un spider encuentre nuestro fichero robots.txt y que aunque supuestamente debería de acatar las ordenes que allí se le indican, este haga caso omiso de los mismo y termine indexando los documentos que queríamos prohibirle. Pero esto es algo que no tiene solución clara, al fin y al cabo quien va a obligar a los desarrolladores del spider a que este acate las ordenes de los archivos robots.txt?

La estructura de un archivo robots.txt es realmente simple, todas sus instrucciones son de tipo

&lt;Campo&gt; : &lt;Valor&gt;

donde <Campo> únicamente puede ser "User-agent" o "Disallow", mientras que <Value> solo puede ser el nombre de un robot o el path relativo al directorio o documento cuya indexación queremos prohibir.

Con un ejemplo todo se ve más claro:

User-agent: *
Disallow: /docs_privados/fotos/
Disallow: /docs_privados/textos/
Disallow: /docs_privados/doc_secreto.txt

User-agent: Googlebot/2.1
User-agent: InfoNaviRobot(F107)
User-agent: TV33_Mercator_1-1.0
User-agent: AVSearch-3.0
User-agent: Scooter/2.0
User-agent: Slurp/2.0
User-agent: SearchengineLicenceSheep_v1.0
User-agent: shadow/2.0
User-agent: MultiText/0.1
User-agent: FAST-WebCrawler/2.2.5
User-agent: Atomz/1.0
User-agent: htdig/ (searchit@netmind.com)
User-agent: spider00.logika.net.
Disallow: /documento.html

Como puedes observar el ejemplo esta dividido en dos partes. La primera esta dirigida a todos los robots, así lo indica la primera instrucción User-agent: *, donde el carácter "*" equivale a "cualquier" o "todos" los spiders. La segunda parte, esta dirigida a unos robots concretos definios mediante múltiples instrucciones que asignan un robot concreto a "User-agent".

En ambas partes, tras indicar los robots a los cuales esta dirigido, se especifica mediante "Disallow" los directorios y documentos que no deberían ser indexados por los robots. Hay que tener en cuenta que para prohibir la indexación de todos los documentos de un directorio, el path que se asigna a "Disallow" debe incluir el carácter "/" al final del nombre del directorio. Es decir, debe tener el formato Disallow: /directorio/ en vez de Disallow: /directorio.

El archivo robots.txt solo sirve para intentar prohibir la indexación de ciertos documentos y directorios, no es valido para configurar otros aspectos del funcionamiento de los spiders. Pero para esto existen los meta-tags de tipo "Robot", los cuales incluidos en un documento HTML sirven para comunicar al robot la asiduidad con la que debiera indexar el documento. Pero esto es ya otra historia…