Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found in GNU Free Documentation License.
Un saludo a tod@s los que de nuevo teneis en vuestro poder este ezine.En este número (y en alguno más, el artículo durará por lo menos 2) vamos a ver que es eso de DHCP, para los que no lo conoceis. Y para los que lo conoceis ya, trataremos de entender como funciona para entender que sucede cuando obtenemos la información de configuración de nuestra máquina de esta forma. Si el tiempo deja intentaremos desmenuzar el dhclient para ver como funciona (repito si el tiempo deja ).
Bueno antes de empezar comentar lo de siempre, si hay algo que este m al,algo que no entiendas, o cualquier cosa, escribeme un mail si quieres.
Como hemos dicho antes, este documento tiene por objetivo, tanto a aquellos que no concocen DHCP, como aquellos que ya saben lo que es. Por eso para empezar voy a explicar qué es, en qué consiste y esas cosas de carácter general que nos serán utiles para saber de que hablamos.
DHCP o Dinamic Host Configuration Protocol (Protocolo de Configuración Dinámica de Host), son las siglas que definen un protocolo que tiene como fin la configuración automática de las máquinas de una red, para de esta forma evitar el pesado trabajo de configurar cada una de las máquinas que existen en la red. Con este protocolo también vamos a ver que la escalabilidad de la red resulta más sencilla, sólo tenemos que "enchufar" una nueva máquina a la red para que esta quede configurada sin apenas intervención nuestra, podiendo dedicarnos a otros menesteres.
El funcionamiento de DHCP es sencillo, esta basado en un modelo cliente- servidor. Es decir uno o varios servidores que están a la espera de peticiones DHCP y los clientes, que son los que hacen esas peticiones. Vamos a tener 3 formas básicas de utilizar los servicios que DHCP ofrece, asignaciónes manuales, asignaciones estáticas y asignaciones dinámicas. La primera de ellas, asignaciones manuales, requieren que el administrador realize la configuración de cada máquina que se añada a la red, y DHCP se utiliza únicamente para comprobar que no haya errores en esas asignaciones (poco util creo yo). La segunda, asignaciones estáticas, es aquella en la que los parámetros de red son dados por el servidor de DHCP, sólo que este las asigna de forma permanente, o hasta que el cliente decida que la quiere cambiar (tampoco es lo que más aprovecha las características del protocolo). Por fin la última forma (que es la más interesante), asignaciones dinámicas, nos permite obtener la configuración del servidor DHCP, pero este nos asigna una fecha en la que la asignación expira, y debemos entonces de negociar otra. Vemos que este módelo es muy interesante si necesitamos introducir temporalmente máquinas en la red, o si vamos quitando equipos viejos de ella.
Hay que decir que los mensages de intercambio entre servidor-cliente empleados por DHCP están basados en el protocolo BOOTP (luego hablaremos de que es , que no cunda el pánico).
Bueno las metas que se propone lograr el protocolo DHCP son más o menos las siguientes (esto está sacado del RFC):
Lograr que la configuración sea automática, sin requerir la atención del administrador de la red.
Conseguir que la configuración obtenida sea correcta claro, es decir que no se asignen configuraciones que puedan generar conflicto (como la misma dirección de red a 2 máquinas).
Intentar que los clientes puedan obtener las mismas configuraciones para diferentes peticiones. Y que el servidor sea capaz de entregar esas mismas configuraciones incluso después de rebootar.
También tenemos que poder mantener en una misma red configuraciones estáticas (configurando a mano cada équipo) y configuraciones dinámicas (DHCP).
Por supuesto debe de ser posible la ampliación de la red, es decir añadir nuevas máquinas a nuestra red.
Lograr que no sea necesario el uso de varios servidores en distintas subredes, permitiendo que un servidor pueda ofrecer configuraciones a máquinas en subredes distintas (ya veremos más adelante el por que de esta supuesta limitación, y como es solventada).
Vale, ya sabemos para que sirve el protocolo, y que es lo que pretende lograr. Ahora vamos a ver que nos ofrece para lograr esas metas que se propone.
Como dijimos anteriormente, la comunicación entre el cliente y el servidor se realizará por medio de paquetes que contienen unos determinados mensages. Estos mensages son los que contendrán las peticiones del cliente (con las opciones que pide, etc...), las respuestas del servidor, y las demás acciones que permite el protocolo. También hemos comentado que estos mensages están basados en los que se envían en el protocolo BOOTP, ¿recordais?. Pues bien, vamos a explicar ahora que es BOOTP.
BOOTP es un protocolo que se diseño con la intención de que máquinas sin disco (memoria no volatil) pudieran arrancar en una red. Estas máquinas al no poseer unidades de almacenamiento no son capaces de guardar la configuración de la red, por lo que no tienen medio por si solas de configurarse para funcionar en una red.
¿Cómo se logra que puedan hacerlo?, pues lo realizan por medio de memorias ROM que están incluidas en su hardware de red, por medio de esas memorias y claro del protocolo BOOTP logicamente.
Este protocolo define 2 fases, una primera en la que por medio de esas ROM y gracias a BOOTP, la máquina será capaz de encontrar un servidor que le ofrecca un fichero de configuración, y una segunda (no definida explicitamente en el protocolo), que consiste en la transeferencia de ese fichero a la máquina por medio de algún protocolo que permita la transferencia, como puede ser TFTP, SFTP o FTP.
La primera fase se realiza por medio de intercambio de estos mensages, para ello BOOTP se basa en IP/UDP. Es decir la comunicación se realizará por medio de paquetes UDP (no orientados a conexión). Para establecer la conexión se utilizan los puertos 67 (el servidor), y el 68 (el cliente). El que se usen puertos concretos, en vez de aleatorios tiene su lógica. Pensad que la mayoría de los mensages enivados tendrán como finalidad la de obtener la configuración de la red para la máquina cliente, esto quiere decir que en ese momento la máquina cliente no tiene IP válida.
¿Cómo enviar mensages sin una IP válida?, pues bien, para eso estan las direcciones de broadcast (a toda la red). La máquina cliente envía el mensage por medio de broadcast al puerto definido, y los servidores que escuchan sabrán interpretar esos mensages y responder a ellos según la necesidad. Por lo tanto necesitamos máquinas, los servidores, que escuchen ese puerto para poder entender los mensages de petición, con un puerto aleatorio se podrían haber confundido otras máquinas que tuvieran en ese puerto algún servicio a la escucha. Esto es importante entenderlo, ya que DHCP utiliza el mismo método para intercambiar los mensages entre cliente-servidor.
Bueno ya hemos visto el funcionamiento a muy grandes rasgos de BOOTP, vamos a ver ahora la estructura de los mensages BOOTP, recordemos que se envían a través de IP/UDP, con lo que se encapsula en un datagrama UDP:
El mensage queda asi:
Bits--> 0 - - - - - - - 8 - - - - - - - 16 - - - - - - - 24 - - - - - - - -32 |**** op[1] ****||** htype[1] **||*** hlen[1] ***||***** hops[1] ***| |******************************** xid[4] ***************************| |************* secs[2] *********||*********** flags ************| |****************************** ciaddr[4] **************************| |****************************** yiaddr[4] **************************| |****************************** siaddr[4] **************************| |****************************** giaddr[4] **************************| |****************************** chaddr[16] *************************|x2 |******************************* sname[64] *************************|x16 |******************************* file[128] *************************|x32 |******************************* vend[64] **************************|x16
Bueno vamos a explicar el contenido de cada uno de esos campos:
op: este es el campo que codifica el tipo de mensage que es, es decir su finalidad. Puede valer:
1 = BOOTREQUEST (petición que envía el cliente)
2 = BOOTREPLY (respuesta enviada por el servidor)
htype: Tipo de la dirección hardware que se enviará con el mensage.
hlen: Longitud de la dirección física (la de hardware)
hops: Este campo indica los saltos que da el paquete por distintas subredes. El cliente lo pone a 0 y los routers por los que pase lo iran incrementando. Los agentes relé deberían desechar paquetes con un hop de 16 o superior.
Luego hablaremos de la opción gateway del mensage.
xid: El identificativo de la transación que se está realizando. Es un número aleatorio que se utilizará para hacer corresponder los mensages de respuesta con las peticiones.
secs: Este campo lo rellena el cliente e indica los segundos que han pasado desde que el cliente intento el arranque (cuando empezó con la transacción). Esto puede ser algunas veces de utilidad, ya que algunos servidores se muestran más "afectosos" con clientes que llevan ya un rato intentando arrancar. Si por alguna razón el cliente no puede llevar la cuenta de los segundos que han transcurrido, el RFC recomienda ponerlo a 100. Este campo no debería usar valores constantes.
flags: Este campo, definido como no usado en la primera especificación, fue designado después como un campo para opciones. De momento sólo esta definido el primer bit, que identifica el paquete como Broadcast, esto lo hace el cliente para hacer saber al servidor que la respuesta ha de ser también por medio de broadcast. El resto del campo hay que ponerlo a 0.
ciaddr: La dirección IP del cliente. Como dijimos antes en caso de la conocca la pone aquí, si no deja este campo a 0 entero. Este campo lo lee el servidor para saber como responder al cliente (lo que comenté arriba, de las posibles opciones de creacción de los mensages de respuesta). Recordad el bit más representativo del campo de flags, es mandatorio, es decir si está activo el servidor debería responder por medio de broadcast. No obstante es recomendable poner este campo a 0 en ese caso.
yiaddr: Campo que contendrá la dirección IP que te dá el servidor, la que tiene mapeada en sus ficheros de configuración para tu dirección MAC, si el cliente no conoce la IP, es decir si pone a 0 el campo ciaddr de arriba.
siaddr: Dirección IP del servidor, generalmente la llena el servidor.
giaddr: Dirección IP del gateway. Como hemos comentado antes, el cliente puede comunicarse por medio de mensages broadcast. Pero el inconveniente que tiene esto es que no pueden salir de la subred en la que esté. Una solución sería la de poner un servidor BOOTP en cada subred, pero también podemos usar agentes relé (no se si está bien traducido) o relay agents. De lo que se encargarán estas máquinas es de redirigir los mensages del cliente al servidor (que recordemos no estaba en la misma subred). Este campo por lo tanto es de utilidad para los servidores y los routers que se encargen de la tarea de tratar las peticiones entre distintas subredes.
chaddr: Dirección física del cliente. El servidor enfrenta contra está dirección en su fichero de configuración para asignar una IP al cliente si este no la conoce (campo ciadddr está a 0).
sname: Cadena que contiene el nombre del servidor, no es necesaria. La cadena debe terminar con NULL. Se usa si se queire especificar en nombre de algún servidor concreto desde el que arrancar.
file: Cadena, también terminada en NULL, que contiene el fichero de configuración que se desea transferir. Este campo puede contener un nombre genérico que ponemos, ser NULL, o tener la ruta completa del fichero (esto en el mensage de respuesta generado por el servidor, para que el cliente pueda después descargarlo).
En el caso de estar vacio, el servidor nos dará el que por defecto este configurado para nuestra máquina. Lo de poner un nombre genérico se utiliza para enfrentarlo contra la base de datos de configuración del servidor.
vend: Campo con especificaciones opcionales, que pueden ser usadas por el fabricante del hardware, por el software o por quien sea. No es requerido.
Generalmente se rellenan los 4 primeros bytes con lo que se llama "magic cookie". Es recomendable que se rellenen estos 4 bytes, aunque el cliente no requiera información adicional del servidor, más adelante veremos como se organiza este campo y que opciones se pueden pasar entre servidor y cliente.
Vamos a ver el mecanismo de intercambio de mensages entre cliente-servidor a través de agentes relé. Como dije antes estos agentes se usan cuando no tenemos un servidor en la misma subred que el cliente. Si esto ocurre no podremos mandar los mensages de broadcast al servidor, ya que no los recibiría. Estableciendo una máquina como agente relé, esta es la que interceptará los mensages del cliente (por lo tanto ha de escuchar por el puerto 67). Las máquinas que actúen como agentes relés pueden estar situadas bien en un host de la subred que es accesible por el cliente o implementados en el router (esto es lo más recomendable) que une las subredes distintas.
Una vez que el agente relé ha recibido nuestro mensage, generará el uno mensage de petición nuevo que enviará al servidor BOOTP. Para ello primero compruebará el contenido del campo 'giaddr', si este esta a 0, el agente relé rellenará este campo con la dirección ip del interface por el cual recibió la petición. Si por el contrario el campo contiene algo, el agente relé lo dejará como esta. Después de esto, aumentará en 1 el numero de saltos del campo 'hops'. Entonces el paquete de petición está listo para ser mandado de nuevo al servidor (al que no podía acceder el cliente directamente). Hay que fijarse que el agente relé no ha modificado ningún campo del paquete de petición original compuesto por el cliente (a excepción del campo 'giaddr' en el caso de ser necesarío y del campo 'hops'). El destino al que lo manda el agente relé puede ir de diferentes maneras, por vía de broadcast, al servidor directamente, etc.... Además puede realizar algún algoritmo para decidir a que servidor (en el caso de que conocca varios) enviarlo, si ocurre esto mandará todos los mensages de petición del mismo cliente al mismo servidor.
En este punto el servidor recibe el paquete de petición enviado por el agente relé. Ahora el servidor deberá generar el paquete de respuesta, para ello lo primero que hará será identificar los campos 'ciaddr' y 'giaddr' y 'secs' (este último para ver la preferencia de resolución de esa petición).
El primero lo comprueba para saber si el cliente especificó su propia dirección IP. El comportamiento del servidor aquí no esta muy definido, podrá o bien creer la dirección que paso el cliente y utilizar ese campo para enviar el mensage de respuesta o bien ignorarlo y actuar como si estuviera a 0. Es importante que aunque el servidor decida ignorar este campo no lo borre, ya que algunos clientes lo usan para asegurarse de que las respuestas son realmente para ellos.
El segundo campo lo comprueba para saber si el mensage llegó a traves de un agente relé, en el caso de que esto sucediera este campo no estará vacio. Si no está vacio el mensage de respuesta se enviará al agente relé (cuya dirección está señalada en 'giaddr'), y se enviará al puerto 67 (el agente relé sólo escucha este puerto, por lo tanto le llegarán por el tanto las peticiones de los clientes como las respuestas de los servidores). El control queda ahora en el agente relé, que será el que se encarge de enviar la respuesta al cliente que la solicitó, a través del puerto 68.
En el caso de que el campo 'giaddr' este a 0, quiere decir que el cliente reside en la misma subred que el servidor, por lo que lo enviará o bien a la IP contenida en 'ciaddr' (recordemos que los servidores pueden ignorar este campo), bien a la IP contenida en 'yiaddr' (esta IP es la que le asigna el servidor al recibir la petición), o bien por medio de broadcast en el caso del que el bit de broadcast del campo 'flags' del mensage de petición del cliente estuviera a 1.
Generalmente los servidores no deberían nunca de modificar el campo de broadcast del mensage de petición que reciban. Aunque hay en casos en los que saben de antemano que un cliente no puede recibir mensages a su nueva dirección IP y modifican el bit de broadcast, activándolo para que los agentes relé que después envíen el mensage al cliente lo hagan por medio de broadcast.
Ahora el mensage de respuesta está en el agente relé, esto quiere decir que será el quien lo mande definitivamente al cliente que originó la petición. Para ello comprobará en el campo de 'flags' el bit de broadcast, si esta activo, enviará el mensage por broadcast. Si no está activo por medio de los campos 'chiaddr', 'yiaddr', 'hlen' y 'htype' podrá enviar el paquete al cliente sin ningún problema. En el caso de tener varias interfaces por las que mandar el paquete al cliente, el campo 'giaddr' le indicará por cual de ellas hacerlo.
Vamos a ver como se forma el campo 'vend' para identificar las opciones que se le pasan al servidor.
El campo comienza con lo que se llama "magic cookie" que es un identificativo que usará el servidor para tratar el campo. El valor de este campo para las opciones definidas en los RFC's es: 99.130.83.99, que ocupa exactamente 32 bytes.
Después del "magic cookie" se incluyen las opciones, las cuales se identifican por medio de un tag que ocupa 1 byte. Estas opciones pueden ser de 2 tipos:
Longitud fija.
Longitud variable.
Solo existen 2 opciones de longitud fija, estas son la 0 y la 255. Las op- ciones que son de longitud fija sólo contienen el byte identificativo, las opciones que son variables contendrán además otro byte con la longitud en bytes del contenido (sin incluir el byte del identificativo, ni el byte de longitud). Después del byte de longitud irán tantos bytes de información como especificara el byte de longitud. Quedaría algo asi:
1 byte 1 byte 1 byte 1 byte 1 byte 1 byte 1 byte 1 byte |--------|--------|--------|-------|--------|--------|--------|--------|--..... |**********MAGIC COOKIE************|***ID***|**LONG**| ******* DATA ******
Este formato será el usado también por DHCP, por lo que es importante entenderlo. Las opciones que se definen para BOOTP son también válidas para DHCP por lo que las enumeraré cuando tratemos DHCP (ya especificaré cuales son válidas para los 2 protocolos y cuales son específicas de DHCP).
Aquí sólo comentaremos la existencia del protocolo RARP (Reverse Address Resolution Protocol). Este protocolo es el inicial que se utilizaba para obtener la dirección lógica del host en la red. El formato de tramas es similar al utilizado por ARP (Address Resolution Protocol). RARP es un protocolo directamente dependiente del medio físico de la red, esto añade grandes inconvenientes (como la imposibilidad de pasar mensages a subredes distintas, la poca abstracción del protocolo con la capa física o la imposibilidad de tener un protocolo lógico con el que controlar las conexiones para el caso de tramas perdidas). Para solventar todos los problemas que causaba RARP se especificó BOOTP. No voy a comentar nada más acerca de este procolo, para más información ver los RFC's.
Aquí van algunos recursos útiles para que sigais con el tema:
Lista de RFCs interesantes:
RFC 951 > BOOTP Protocol Specification. RFC de BOOTP.
RFC 1542 > Clarifications and Extensions for the Bootstrap Protocol. (Deja obsoleto al 1532).
RFC 2132 > DHCP Options and BOOTP Vendor Extensions. Opciones para DHCP y BOOTP
RFC 903 > A Reverse Address Resolution Protocol. RFC de RARP.
En esta primera parte del artículo hemos conocido BOOTP, el protocolo sobre el que se basa DHCP. Hay que fijarse en el formato de los mensages de BOOTP y en la forma de comunicación entre cliente y servidor, así como el uso de agentes relé.
Ya que DHCP es muy muy parecido a esto, tanto que los mensages son compatibles (o deberían si están bien implementados cliente y servidor).
En el próximo capítulo del artículo nos meteremos ya de lleno con el protocolo DHCP, y conoceremos las opciones que posee, así como la interoperatividad con BOOTP y el servicio DNS.
Hasta entonces salud y revolución!!