Administración de Sistemas Debian GNU/Linux

Eduardo González de la Herrán
egonzalez@nht-norwick.net
Diciembre 2004

Introducción

Consejos generales para la administración de sistemas Unix:

Paciencia, casi todo tiene solución.

Documentarse (RTFM).

Buscar información en internet.

Documentar lo que hacemos/aprendemos.

Tareas del Administrador

Gestión de usuarios y permisos.

Configuración del entorno de shell.

Runlevels y proceso de arranque.

Configuración de la red.

Administración de paquetes.

Configuración de lilo (gestor de arranque).

Configuración del kernel y dispositivos.

Configuración cliente samba.

Configuración de ejecución programada de procesos (cron).

Gestión de usuarios y permisos (I)

GNU/Linux: entorno multiusuario.

Usuarios, grupos y permisos proporcionan el mecanismo de seguridad básico en linux.

Ficheros de configuración:

/etc/passwd	--> usuarios

/etc/group	--> grupos

/etc/shadow	--> contraseñas

Gestión de usuarios y permisos (II)

Grupos: Definidos en /etc/group. Cada usuario debe pertenecer al menos a un grupo

Creación de grupos mediante groupadd.

Sintaxis: groupadd [-g gid] nom_grupo

Ejemplo: groupadd clientes

groups [user]: groups a los que pertenece el usuario (actual).

gpasswd -[a|d] user group : Añade o elimina al usuario del grupo.

Gestión de usuarios y permisos (III)

Usuarios: Definidos en /etc/passwd. Se pueden crear con useradd o con el script adduser.

Creación de usuarios mediante useradd.

useradd -c “Pedro González” -d /home/pedro -g clientes -G users,audio,cdrom -m -s /bin/bash pedro

passwd: modificación de contraseñas. Cada usuario puede modificar su contraseña. El usuario root puede modificar todas las contraseñas.

Gestión de usuarios y permisos (IV)

Usuarios: ¿Quién soy? ¿Hay alguien ahí fuera?

whoami: indica el usuario con el que estamos ejecutando los comandos.

id: credenciales, similar a whoami pero más preciso.

w, who: indican los usuarios conectados en este momento y qué están haciendo.

Gestión de usuarios y permisos (V)

Cambiar propietario y grupo de ficheros:

chown: cambia el propietario y/o grupo del fichero

chown root /var/tmp/fichero

chown root:clientes /var/tmp/fichero

chown -R :nobody /tmp/*

chgrp: cambia el grupo del fichero

chgrp audio /dev/dsp

Gestión de usuarios y permisos (VI)

Permisos: para ver los permisos de un fichero utilizamos ls -l

chmod: cambia el modo de acceso al fichero.

dos sintáxis: octal y con letras:

con letras: [ugoa] [+-=] [rwx]

chmod u=rwx fichero

chmod a+rx fichero

octal:

R W X R W X R W X

1 1 1 1 0 1 1 0 1

7 5 5

chmod 755 fichero (= rwxr-xr-x)

Gestión de usuarios y permisos (VII)

Gestión avanzada:

su: cambiar de usuario.

con “-” se simula que se ha entrado desde ese usuario (se va a la $HOME del usuario, se cargan los scripts de arranque, etc.).

con “-c” se puede ejecutar un comando como ese usuario.

su – usuario

su – root

su usuario -c “ls /home/usuario”

Gestión de usuarios y permisos (VIII)

Permisos avanzados:

SUID: en un ejecutable, funciona parecido a su.

/usr/bin/passwd -> -rwsr-xr-x

GID: en un directorio, mantiene el grupo.

/var/spool/mail -> drwxr-sr-x, grupo=mail

cd /var/spool/mail; touch fichero -> grupo=mail

Sticky: en un directorio, los usuarios no pueden borrar cosas que no son suyas, aunque tengan permiso para ello.

/tmp -> drwxrwxrwt

Configuración del entorno de shell

Con la configuración del entorno de trabajo definimos variables del sistema, prompt, colores, etc. personalizados para cada usuario o para todos los usuarios.

Ficheros implicados:

/etc/profile (se lee siempre en cada login de cualquier usuario)

/etc/bash.bashrc (no se lee en el login, sólo al ejecutar bash)

~/.profile (obtenido de /etc/skel)

~/.bash_profile, ~/.bashrc (obtenidos de /etc/skel)

Si modificamos el fichero /etc/profile haremos cambios para todos los usuarios del sistema cada vez que hagan login.

Runlevels y Proceso de arranque

Cuando la máquina se inicia en un nivel de ejecución N se ejecutan todos los scripts que empiecen por 'S' o 'K' contenidos en /etc/rcN.d/ con las siguientes particularidades.

Si el nombre del script comienza por S se le pasa como parámetro 'start'

Si el nombre del script comienza por K se le pasa como parámetro 'stop'

Normalmente todos estos ficheros de /etc/rcN.d son enlaces a scripts localizados en /etc/init.d/

Configuración de la red (I)

Las interfaces de red se configuran en el fichero '/etc/network/interfaces' (man interfaces).

ender@lusitania:~$ cat /etc/network/interfaces

auto eth0 eth1

iface eth0 inet static

address 172.26.0.2

netmask 255.255.255.0

network 172.26.0.0

broadcast 172.26.0.255

gateway 172.26.0.1

iface eth1 inet dhcp

Configuración de la red (II)

Configuración manual de la red:

ifconfig: configura interfaces de red. Asigna IP, máscara, dirección mac, etc.

$ ifconfig eth0 172.26.0.12 netmask 255.255.255.0 up

route: añade rutas estáticas. Ejemplo típico:

$ route add default gw 172.26.0.1

$ netstat -nrv (muestra tabla de rutas)

/etc/resolv.conf: indica los servidores DNS

$ cat /etc/resolv.conf

nameserver 195.235.113.3

Configuración de la red (III)

Configuración manual de la red:

/etc/hosts: realiza una resolución directa de nombre a IP sin realizar consulta DNS. Normalmente este fichero se mira antes de preguntar al servidor DNS.

Para asegurarnos que el sistema pregunte al dns o al fichero '/etc/hosts' para resolver nombres de host hay que mirar el fichero '/etc/nsswitch.conf'

Configuración de la red (IV)

Configuración de red para DHCP:

Configuración para el arranque: en /etc/network/interfaces definimos la interfaz como “inet dhcp”

Configuración manual: se utiliza un cliente dhcp como dhclient o plumb

# dhclient eth0

# plumb -i eth0

Comandos de Red (I)

ping: manda un mensaje ICMP – echo request.

Se utiliza normalmente para comprobar si un interfaz de red remoto está levantado.

$ ping 212.55.8.132

PING 212.55.8.132 (212.55.8.132) 56(84) bytes of data.

bytes from 212.55.8.132: icmp_seq=1 ttl=242 time=166 ms

(hay conectividad!)

Nota: Si no hay ping puede que el tráfico este filtrado.

Comandos de Red (II)

telnet: protocolo de terminal remoto.

Se utiliza para conectarse a una máquina remota.

$ telnet IP puerto (default 23)

NO es un protocolo seguro (SSH sí)

Se utiliza también para comprobar estado de servicios remotos. Ejemplo:

$ telnet www.euskalnet.net 80

Connected to eui3h.euskaltel.es.

Escape character is '^]'.

Comandos de Red (III)

netcat (nc): “navaja suiza” de red, capaz de funcionar como cliente, como servidor, etc.

Ejemplos:

cat fichero | nc 192.168.1.1 5000

nc -l -p 5000 > fichero

Comandos de Red (IV)

netstat : muestra conexiones de red. Comando potente que permite mostrar casi toda la información de la configuración TCP/IP de la máquina (man netstat).

Ejemplos:

netstat -atup # muestra tambien procesos

netstat -a # muestra todas las conex.

netstat -a | grep LISTEN

netstat -a | grep ESTABLISHED

netstat -nrv # muestra tabla de rutas

Conceptos de red avanzados (I)

Firewall: filtrado de paquetes, políticas de seguridad.

A partir de linux 2.4 se ofrece iptables en el kernel como aplicación para gestionar el filtrado de paquetes. Antiguamente era ipchains. Por debajo de iptables/ipchains está netfilter.

Extensiones de tcp como los tcpwrappers también ayudan a este propósito.

El filtrado de paquetes es uno de los contextos en los que los sistemas GNU/Linux presentan una clara alternativa, válida y reentable, a aplicaciones comerciales como FW1 (CheckPoint), StoneBeat (StoneSoft), etc.

Conceptos de red avanzados (II)

Firewall: filtrado de paquetes, políticas de seguridad.

Se pueden configurar directamente creando reglas de iptables (un script finalmente) o utilizando front-ends que generarán dicho script. Posibles aplicaciones que hacen más fácil la configuración del firewall son:

shorewall: ficheros de configuración de texto estructurados.

fw_builder: interfaz gráfica muy parecida al FW-1 de CheckPoint.

Conceptos de red avanzados (III)

Sniffers, analizadores de red.

Sirven para detectar problemas de congestión, saturación de conexiones.

Se basan en configurar el interfaz de red en modo promiscuo de forma que recogerá la información de todos los paquetes que le lleguen (como si tuviera todas las direcciones MAC).

Es difícil de realizar en redes switcheadas si no se configura una boca del switch para tal propósito.

Infinidad de aplicaciones: tcpdump, ettercap, ethereal, iptraf, airtraf (wifi), airsnort (wifi), kismet (wifi), ...

Conceptos de red avanzados (IV)

QoS: calidad de servicio, control de tráfico.

El kernel de linux ofrece toda la infraestructura para hacer control de tráfico. Genera una serie de colas de paquetes con diferentes prioridades y anchos de banda.

A nivel de kernel, los encargados de realizar QoS en linux son tc e iproute2. Para crear un kernel con soporte QoS hay que seleccionar las opciones “Traffic Shapping” en la configuración del kernel.

Conceptos de red avanzados (V)

QoS: calidad de servicio, control de tráfico.

La aplicación wondershaper (apt-cache show wondershaper) genera un script de QoS configurable bastante potente.

Es un campo donde productos hardware + firmware comerciales lo superan (packeteer)

Administración de paquetes (I)

DPKG, Sistema de gestión de paquetes de Debian:

Permite la instalación, borrado y mantenimiento de .debs

dpkg -i paquete.deb : instala un paquete.

dpkg -r [--purge] paquete : elimina un paquete.

dpkg -L paquete : muestra el contenido completo de un paquete.

dpkg -S file : busca paquetes que contengan el fichero.

dpkg -l paquete.deb : muestra la lista completa de paquetes instalados en el sistema.

dpkg -s paquete : muestra información del estado de un paquete.

Administración de paquetes (II)

APT, front-end avanzado para dpkg (hay otros como dselect, tasksel, aptitude, ...)

APT resuelve dependencias. Al instalar un paquete puede que éste dependa de otro u otros para su funcionamiento. APT detecta esta dependencia e instala los paquetes necesarios.

Funcionamiento:

Se crea una base de datos local con la información de los paquetes instalables. Para crear esta base de datos hace falta un fichero con las fuentes de donde bajarse la información.

Esta base de datos local hay que actualizarla periódicamente.

Administración de paquetes (III)

Funcionamiento (continuación):

Cuando se solicita la instalación de un paquete, APT comprueba primero en el sistema que el paquete no esté ya instalado y posteriormente comprueba en la base de datos local si el paquete está disponible.

Si el paquete está disponible entonces se conecta a la fuente en cuestión para bajarse el paquete (archivo .deb). Estos paquetes bajados se guardan en /var/cache/apt/archives

Posteriormente a la bajada se procede a la instalación y configuración automática del paquete. Si el paquete necesita datos de configuración nos los pedirá el APT.

Administración de paquetes (IV)

Definición de fuentes para APT:

Se definen en el fichero /etc/apt/sources.list

Se pueden configurar con un asistente ejecutando apt-setup.

Para leer CDs con fuentes podemos utilizar también apt-cdrom.

Ejemplo de sources.list básico:

# Standard...

deb http://ftp.de.debian.org/debian sid main contrib non-free

deb http://ftp.de.debian.org/debian-non-US sid/non-US main contrib non-free

deb http://security.debian.org/ stable/updates main contrib non-free

Administración de paquetes (V)

apt-cache: realiza búsquedas sobre la base de datos local de paquetes. Útil para la obtención de información sobre software disponible.

apt-cache search patron : busca paquetes que cumplan un patrón.

apt-cache show paquete : muestra la información de un paquete

apt-cache depends paquete : muestra las dependencias del paquete.

apt-cache redepends paquete : muestra las dependencias inversas del paquete.

Administración de paquetes (VI)

apt-get: interfaz para instalar y desinstalar paquetes así como para la generación y actualización de la base de datos local de paquetes.

apt-get update : Actualiza la base de datos local de paquetes.

apt-get upgrade : Actualiza todos los paquetes instalados que pueda.

apt-get dist-upgrade : Actualiza todos los paquetes que pueda incluso cuando la actualización implique la instalación de paquetes nuevos.

apt-get install paquete1 paquete2 ... : Instala paquetes.

apt-get remove [--purge] paquete1 paquete2 ... : Desinstala paquetes.

apt-get clean : elimina archivos descargados

Configuración de LILO (I)

LILO (Linux Loader) es un gestor de arranque capaz de arrancar diferentes sistemas operativos en diferentes particiones y discos duros. Normalmente se instala en el MBR (master boot record) del disco duro principal.

El archivo de configuración en Debian GNU/Linux es:

/etc/lilo.conf

Siempre que se realice un cambio en la configuración hay que ejecutar 'lilo' para que se escriba el sector de arranque de nuevo.

Configuración de LILO (II)

Datos de interes del archivo lilo.conf:

boot=/dev/hda	# Donde se instala el lilo

install=menu	# Tipo de instalación (interfaz)

delay=20	# Tiempo de espera

default=Linux-2.6.8	# Label de arranque por defecto

image=/boot/bzImage-2.6.8.1	# Imagen del kernel

label=Linux-2.6.8	# Etiqueta

read-only

#vga=0x317 # para driver FB vesa (1024x768)

append="video=i810fb:xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55,vsync1:50,vsync2:85"

Configuración de LILO (III)

Datos de interes del archivo lilo.conf:

other=/dev/hda2	# Otros sistemas operativos

label=Windows

LILO con menú gráfico:

install=/boot/boot-bmp.b

bitmap=/boot/debian-bootscreen-woody.bmp # debe existir

bmp-colors=1,,0,2,,0

bmp-table=120p,173p,1,15,17

bmp-timer=254p,432p,1,0,0

Recuperación de desastres

En caso de que algo haya machacado nuestro MBR...

El objetivo es ejecutar /sbin/lilo de nuestro sistema para volver a escribir el MBR de la máquina y que lilo vuelva a funcionar.

Para ello podemos arrancar de diferentes formas:

Diskette de arranque preparado de antemano + /sbin/lilo (FIN)

CD 1 de Debian GNU/Linux con opcion rescue, rescbf24 o similar:

linux: rescbf24 root=/dev/hda2

# de esta forma se arranca el kernel del CD montando en / la particion que digamos.

# posteriormente se ejecuta /sbin/lilo y FIN.

Live CD (Knoppix o similar) + montar disco + chroot + /sbin/lilo (más complicada)

Configuración del kernel y dispositivos (I)

El kernel linux es el encargado de gestionar todos nuestros dispositivos.

Para que un dispositivo sea reconocido y usable por el sistema debe haber un driver en el kernel que lo reconozca y se apropie de él. Este driver puede estar integrado en el kernel o como módulo.

El kernel linux se puede personalizar para contener única y exclusivamente lo necesario (mayor seguridad y eficiencia pero menor adaptabilidad).

Configuración del kernel y dispositivos (II)

Loadable Kernel Modules (LKM):

Linux: Kernel monolítico con soporte para carga y descarga de módulos.

Los módulos se encuentran en /lib/modules/$version-kernel

Para la carga y descarga de módulos se utilizan los siguientes comandos:

insmod, rmmod, modprobe

Herramienta modconf para la carga y descarga de módulos:

Detecta dependencias entre módulos e instala lo necesario. MUY ÚTIL.

# apt-get install modconf

Configuración del kernel y dispositivos (III)

Construcción de un kernel nuevo. Pasos:

Obtener el código fuente del kernel.

Preparar el árbol de archivos del código fuente.

Configurar el kernel a crear.

Compilar el kernel y los módulos.

Instalar los módulos.

Reubicar el kernel.

Configurar y ejecutar LILO o GRUB.

Reiniciar el sistema.

Configuración del kernel y dispositivos (IV)

Software necesario para la construcción del kernel.

Se necesitan los siguientes paquetes:

gcc : compilador de C.

make: utilidad para compilar programas de forma avanzada.

libc6-dev

linux-kernel-headers : archivos de cabecera comunes.

libncurses5, libncurses5-dev : para la configuración tipo “menuconfig”.

module-init-tools : para construir e instalar módulos.

Configuración del kernel y dispositivos (V)

Configuración del kernel

La configuración del kernel consiste en decidir qué partes queremos meter en el kernel y qué modulos queremos crear.

Se puede configurar el kernel mediante 4 métodos: edición manual del fichero de configuración, configuración basada en texto, configuración basada en diálogos “ncurses” y configuración basada en entorno gráfico.

Configuración del kernel y dispositivos (VI)

Configuración del kernel

Para proceder a la configuración del kernel nos situamos en el directorio base del código fuente bajado y ejecutamos:

# make config	# texto (no usar)

# make menuconfig	# diálogos ncurses

# make xconfig	# modo gráfico

Se procede a la configuracion de TODAS las opciones...

El archivo de configuración del kernel que se genera se llama “.config”

Configuración del kernel y dispositivos (VII)

Compilación del kernel e instalación de módulos:

Version 2.4

make dep

[make clean]

make bzImage

make modules

make modules_install

Version 2.6

make

make modules_install

Configuración del kernel y dispositivos (VIII)

Reubicación del kernel (CUIDADO CON SOBRESCRIBIR ARCHIVOS ANTERIORES)

Copiamos el kernel generado a /boot

cp arch/i386/boot/bzImage /boot/miKernel

Copiamos System.map a /boot

cp System.map /boot/System.map.miKernel

Configuración del kernel y dispositivos (IX)

Reconfiguramos y ejecutamos LILO

Añadimos las líneas necesarias en /etc/lilo.conf

image=/boot/nuevoKernel

label=NuevoKernel

read-only

Ejecutamos LILO

pc-edu:~# lilo

Added Linux *

Added NuevoKernel

Reiniciamos el sistema (reboot)

Configuración cliente samba (I)

Problema 1: Queremos acceder a 'carpetas compartidas de Windows' desde Debian GNU/Linux.

Problema 2: Queremos acceder a 'directorios compartidos de máquinas GNU/Linux' desde Debian GNU/Linux.

Solución: Usar suite SAMBA.

NOTA: Para compartir directorios entre 2 máquinas GNU/Linux lo más común es NFS

Nos centraremos en el Problema 1.

Configuración cliente samba (II)

Paquetes de Debian GNU/Linux que necesitamos:

samba-common

smbclient

smbfs (y soporte en el kernel para smbfs)

Utilización de cliente samba para acceder a recursos compartidos de Windows:

smbclient

smbmount

Configuración cliente samba (III)

Ejemplos:

Para ver las 'carpetas compartidas':

~$ smbclient -L 192.168.1.10 -U nht-norwick -W NHT-LAN

Password:

Para conectarse a una 'carpeta compartida':

~$ smbclient \\\\<ip>\\<carpeta_compartida> -U <usuario> -W <grupo_de_trabajo>

Utilización de Konqueror con integración de cliente samba:

smb://ip_servidor/recurso_compartido

smb4k: Cliente KDE para navegar por los recursos compartidos.

smbc: Cliente basado en ncurses para navegar por los recursos compartidos.

Configuración de cron (I)

El demonio cron permite la ejecución programada de procesos, scripts o simples comandos.

Cron mira cada minuto si tiene que lanzar algún proceso y en caso afirmativo lo lanza. No se puede planificar una ejecución de forma más precisa.

Cada usuario tiene su tabla de planificación (crontab) aunque tambien existen una tabla de planificación global del sistema (/etc/crontab) y una serie de directorios especiales.

Configuración de cron (II)

Ficheros de información de cron. Los ficheros de cron tienen una sintaxis especial y son los siguientes:

/etc/crontab	:	Fichero de cron del sistema. Sintaxis típica de cron con información del usuario.

/etc/cron.d/	:	Directorio para que paquetes puedan meter ficheros de cron. Misma sintaxis que /etc/crontab

fichero de cron de cada usuario	:	No se ven (/var/spool/...). Tienen la sintaxis típica de cron sin información del usuario, ya que pertenecen a un usuario concreto. Se edita con crontab -e y se muestra con crontab -l.

Configuración de cron (III)

La sintaxis típica de los ficheros de cron consiste en 6 campos:

* * * * * [user] comando parametros

minuto: 0-59. Número, rango, intervalo o lista (separada por comas).

hora: 0-23.

día del mes: 1-31.

mes: 1-12 o nombres.

día de la semana: 0-7 o nombres.

usuario: sólo en ficheros comentados anteriormente.

comando: el resto de la línea es el comando a ejecutar.

Nota: También puede haber líneas al principio con declaración de variables.

Configuración de cron (IV)

Ejemplo de cron de un usuario (root):

PATH=$PATH:/usr/bin:/usr/local/bin

# los viernes cada 2 horas...

* */2 * * 5 cd /root/scripts; ./generaEstadisticas.sh

# cada día por la noche

20 3	* * * cd /root/scripts; ./backupDiario.sh

# rotación de backups cada mes

0 1 1 * * cd /root/scripts; ./rotaBackups.sh

Configuración de cron (V)

Creación o edición del fichero de cron del usuario actual:

$ EDITOR=vi

$ export EDITOR

$ crontab -e

(se edita...)

:wq (se guarda y se sale)

Mostrar el contenido del cron de un usuario:

$ crontab [-u user] -l

Configuración de cron (VI)

Directorios especiales:

/etc/cron.daily/

/etc/cron.hourly/

/etc/cron.monthly/

/etc/cron.weekly/

Los ficheros ejecutables que metamos en esos directorios se ejecutarán en su momento por el usuario root. NO DEBEN SER FICHEROS DE CRON, sino scripts o programas.

Instalación de aplicaciones desde fuentes (I)

En algunos casos tendremos que instalar las aplicaciones desde las fuentes, bien porque no existe un paquete debian creado, o bien porque el paquete existente no se ajusta a nuestras especificaciones.

Lo primero que tenemos que hacer para instalar software desde las fuentes es leer las instrucciones de instalación de la aplicación concreta, aunque casi todas suelen ser parecidas.

Instalación de aplicaciones desde fuentes (II)

Proceso de instalación:

1) Obtención y descompresión/desempaquetado del código fuente en un directorio.

2) Edición del fichero Makefile: a veces tenemos que editar este fichero para indicarle al compilador algunos parámetros específicos del sistema. Es el fichero que make va a leer en la compilación.

Para saber si debemos editar el fichero deberemos leer las instrucciones de instalación de la aplicación.

Este paso 2 no es muy típico.

Instalación de aplicaciones desde fuentes (III)

Proceso de instalación:

3) Configuración del código fuente: normalmente este paso se realiza ejecutando un script llamado configure y pasándole una serie de parámetros por si no queremos la configuración por defecto:

./configure [parametros]

Este script suele avisarnos si la configuración ha sido correcta o si no cumplimos todos los requisitos necesarios para soportar el software (por ejemplo nos falta alguna aplicación, librería, etc).

Como parámetros de configure se suele pasar el directorio de instalación, si queremos alguna funcionalidad especial de la aplicación, etc.

Instalación de aplicaciones desde fuentes (IV)

Proceso de instalación:

3) Configuración (continuación):

Algunas aplicaciones traen scripts que ayudan a configurar el código fuente de manera más interactiva que configure. Estos scripts suelen estar basados en diálogos ncurses o en un entorno gráfico. Por ejemplo el kernel de linux o ettercap ofrecen diferentes métodos de configuración.

Instalación de aplicaciones desde fuentes (V)

Proceso de instalación:

4) Compilación del código fuente: Esto genera toda la aplicación pero dentro del directorio donde teníamos el código fuente.

La compilación se realiza generalmente con el comando make desde el directorio raiz del código fuente:

make [parametro]

Se suele mandar un parámetro cuando solo queremos construir alguna parte de la aplicación. Tambien se suele usar la sintaxis make all.

Instalación de aplicaciones desde fuentes (VI)

Proceso de instalación:

5) Instalación (reubicación) de la aplicación: este proceso básicamente copia los binarios, librerías y ficheros de configuración generados en la compilación a los directorios donde residirá la aplicación finalmente.

La instalación se realiza normalmente con el comando make install

make install

Nota: Este paso a veces se hace de forma manual (cuando lo generado son 1 o 2 archivos por ejemplo).

Licencia

Este material es libre de ser reproducido de forma literal en cualquier medio tal y como se especifica la Licencia Libre de Documentación (FDL) y siempre que esta nota sea preservada.

Para la elaboración del documento se ha contado con la ayuda de Alvaro Uría y se ha utilizado documentación libre creada por Alvaro Marín y Pablo Garaizar.

Autor:

Eduardo González de la Herrán

2003-09-27T13:26:22