\documentclass[12pt,a4paper]{article}
\usepackage[spanish]{babel}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{subcaption}

\title{Tema XII Ejercicio I: DHCPD}
\author{Nicolás A. Ortega Froysa}

\begin{document}
\maketitle
\pagebreak
\tableofcontents
\pagebreak

\section{Introducción}

Cuando estamos creando y configurando redes, un elemento fundamental para la
comunicación entre equipos es la asignación de direcciones IP, ya que es por
medio de esto que se pueden identificar los distintos dispositivos conectados a
la red. Cuando se trata de unos pocos dispositivos, la asignación de direcciones
IP no es una tarea demasiado difícil, mas cuando tratamos de cientos, o incluso
miles de dispositivos, esto se puede convertir en una tarea muy ardua y
compleja. Tiene aún menos sentido tener que pasar tanto tiempo configurando
estas direcciones cuando la mayoría son de dispositivos clientes, y por lo tanto
serán siempre los que inicialicen la conexión, y nunca la recibirán. Es por esto
que se inventó el sistema DHCP.

En este sistema, existe un servidor, corriendo un software DHCPD ({\em DHCP
Daemon}) con una dirección IP fija, que recibe peticiones (generalmente dentro
de su red local) para adquirir direcciones IP. Este servidor devuelve una
dirección IP que se asegura que no la está usando ningún otro dispositivo.

El objetivo de esta práctica es instalar y configurar un servidor DHCP usando el
software {\tt dhcpd} para nuestra red local.

\section{¿Cómo Funciona DHCP?}

\begin{figure}[!htb]
	\centering
	\includegraphics[width=0.25\linewidth]{imgs/dhcp-diagram.png}
	\caption{Diagrama del protocolo DHCP.}
	\label{fig:dhcp-diagram}
\end{figure}

El protocolo DHCP consta de cuatro peticiones distintas entre el servidor y el
cliente.

\begin{enumerate}
	\item El cliente manda a la red (y llega al servidor) una
		petición {\tt DHCPDISCOVER}. Esto sirve para que el cliente se haga
		conocido del servidor, y el servidor registre el nuevo dispositivo.
		También es posible que el cliente, si se ha conectado antes a esta red,
		pida la misma dirección IP que tenía anteriormente, y el servidor DHCP
		se lo puede permitir o no.
	\item El servidor responde a la petición del cliente con una petición {\tt
		DHCPOFFER}, en el que el servidor ofrece una dirección IP al cliente.
		Como el cliente aún no tiene dirección IP (por eso lo va a solicitar)
		especifica la dirección de MAC para identificar al cliente.
	\item Cuando el cliente haya recibido la oferta del servidor, enviará una
		petición al servidor para confirmar la dirección IP, denominada petición
		{\tt DHCPREQUEST}. También, el cliente enviará una petición ARP por la
		red para averiguar si hay algún otro dispositivo en la red que tiene la
		misma dirección IP.
	\item Al final del proceso, el servidor envía al cliente un paquete {\tt
		DHCPACK} que reconoce la reserva de ese cliente en esa dirección IP.
		También debería incluir el cuanto de tiempo que tendrá reservada la
		dirección. A partir del momento en el que el cliente recibe este
		paquete, ya se supone que el propio cliente ha de manejar sus propias
		interfaces. Al recibir la dirección, si el cliente ve que otro ordenador
		de la red ya está usando esa dirección, deberá enviar otra petición
		{\tt DHCPDECLINE} a la red para notificar al servidor.
\end{enumerate}

\section{Configuración de Red}

\begin{figure}[!htb]
	\centering
	\includegraphics[width=0.75\textwidth]{imgs/diagrama-red.png}
	\caption{Diagrama de nuestra red.}
	\label{fig:diagrama-red}
\end{figure}

Nuestra red de prueba constará de los elementos que aparecen en la figura
\ref{fig:diagrama-red}. Aunque es poco usual, el servidor DHCP será el
intermediario entre el enrutador y nuestra red local (192.168.37.0/24). Luego,
el servidor a su vez estará conectado también a un {\em switch}, al cual estarán
conectados todos los terminales. De estos terminales, queremos que uno tenga una
dirección IP fija de 192.168.37.201, y las demás que tengan una IP dinámica
asignada por el servidor DHCP dentro del rango 192.168.37.100-150. Luego para
conectarse a la internet, los terminales se tendrán que conectar, en primer lugar, al
servidor y luego pasar al enrutador para ir a internet. También queremos
designar como servidor DNS los servidores de Google, que tienen las direcciones
IP de 8.8.8.8 y (como alternativa) 8.8.4.4.

\section{Instalación y Configuración de DHCPD}

\subsection{Instalación}

Como nuestro servidor está corriendo Debian, hemos de usar el manejador de
paquetes {\tt apt} para instalar el programa. Para esto, corremos el comando
siguiente:

\begin{verbatim}
# apt install isc-dhcp-server
\end{verbatim}

Para verificar que se ha instalado correctamente, podemos ver si se ha instalado
el binario {\tt dhcpd} en nuestro {\tt PATH} usando el comando {\tt which
dhcpd}. También instalará el servicio de {\em Systemd} con el mismo nombre que
el paquete ({\tt isc-dhcp-server}) que podemos administrar usando el comando
{\tt systemctl}. Como por ahora estamos probando nada más, y no queremos que se
inicialice por sí mismo, vamos a deshabilitar el servicio y pararlo. Luego,
cuando ya tengamos el servicio completamente configurado y funcione
correctamente.

\begin{verbatim}
# systemctl stop isc-dhcp-server
# systemctl disable isc-dhcp-server
\end{verbatim}

\subsection{Configuración}

Para la configuración del servicio DHCP, hemos de editar el archivo de
configuración {\tt /etc/dhcp/dhcpd.conf}. Mas, en nuestro caso vamos a empezar
desde cero, ya que este archivo viene con muchas opciones ya declaradas por
defecto. Para esto, simplemente hacemos una copia de seguridad del archivo
(e.g.\ renombrándolo a {\tt dhcpd.conf.bak}).

Creamos ahora un archivo de configuración nuevo (en blanco) y ponemos la
configuración siguiente:

\begin{verbatim}
option domain-name-servers 8.8.8.8, 8.8.4.4;
option routers 172.21.0.100;
option subnet-mask 255.255.255.0;

subnet 192.168.37.0 netmask 255.255.255.0 {
  range 192.168.37.100 192.168.37.150;
}

host DESKTOP-U4F9M9L {
  hardware ethernet 7C:10:C9:25:95:E1;
  fixed-address 192.168.37.201;
}
\end{verbatim}

En la primera línea, especificamos la opción {\tt domain-name-servers}, que son
los servidores de resolución de nombre de dominio (DNS) que queremos asignar a
los ordenadores de nuestra red. En este caso, 8.8.8.8 y 8.8.4.4 son los
servidores DNS públicos de Google. Así cuando uno de los ordenadores de nuestra
red quiere resolver un nombre, se lo pedirá a uno de estos servidores. Esta
opción es especialmente útil si tenemos un servidor DNS interno a nuestra red
que queremos usar.

La segunda opción se trata de asignar la dirección IP del enrutador (i.e.\ {\em
router} o {\em gateway}) usando la opción {\tt routers}. Si el dispositivo
quiere acceder a alguna dirección que no está dentro de su red asignada,
intentará acceder a ella por medio de esta dirección IP.

La tercera opción, {\tt subnet-mask} trata de asignar la máscara de subred
general, que nosotros que sea el 255.255.255.0 (equivalente a /24). Así los
dispositivos podrán saber qué direcciones IP están dentro de su red.

\begin{verbatim}
subnet 192.168.37.0 netmask 255.255.255.0 {
  range 192.168.37.100 192.168.37.150;
}
\end{verbatim}

En estas tres líneas, tratamos de definir la red, la máscara, y el rango de
direcciones IP para los dispositivos que tengan IP dinámica. Primero, empezamos
definiendo la red en sí. Esto se hace definiendo primero la dirección de red,
que en nuestro caso es 192.168.37.0, y luego la máscara de red, que es de
255.255.255.0. Después, usando la opción {\tt range}, designamos el rango de
direcciones IP que usará nuestro servicio DHCP para asignar nuevas direcciones a
los dispositivos que lo piden. De este modo, todas los dispositivos tendrán una
dirección IP dentro de este rango.

\begin{verbatim}
host DESKTOP-U4F9M9L {
  hardware ethernet 7C:10:C9:25:95:E1;
  fixed-address 192.168.37.201;
}
\end{verbatim}

Estas cuatro líneas nos ayudan a definir una dirección IP estática a un
dispositivo concreto. Esto puede ser útil cuando tenemos un servidor dentro de
la red, que queremos que siempre tenga una misma dirección IP (e.g.\ un servidor
DNS) pero para poder configurarlo todo desde el mismo sitio, en vez de
configurarlo en el servidor en sí, lo configuramos desde el sistema DHCP. Por
ejemplo, si tenemos un servidor DNS en nuestra red con dirección 192.168.37.5 y
lo queremos cambiar a 192.168.37.202, normalmente habría que entrar en el
servidor para cambiarle la dirección, y luego entrar en el otro servidor DHCP
para cambiarle la dirección asignada anteriormente. Pero de este modo,
conseguimos que en el mismo servidor (y el mismo archivo) configuramos ambas
cosas.

Lo primero que hacemos es definir el {\em hostname} con el comando {\tt host}
seguido del nombre del dispositivo en la red (en nuestro caso se llama
DESKTOP-U4F9M9L). Todas las opciones que definimos en este bloque se aplicarán a
este dispositivo. Pero como también puede darse que dos dispositivos se hayan
puesto el mismo nombre (aunque lo suyo sería evitar esto) también identificamos
al dispositivo usando su dirección MAC, que es de hardware, y es único. Esto se
puede encontrar en la salida del comando {\tt ip address} en los sistemas UNIX
dentro de la configuración de la interfaz correspondiente (figura
\ref{fig:mac-address}), o dentro de la configuración de red en Windows. {\bf
Aviso:} aunque en algunos sistemas (como Windows) la dirección MAC aparece
usando guiones (i.e.\ <<->>) para separar los dígitos, siempre se ha de usar los
dos puntos (i.e.\ <<:>>). Lo definimos con la opción {\tt hardware ethernet}.

\begin{figure}[!htb]
	\centering
	\includegraphics[width=1.0\textwidth]{imgs/mac-address.png}
	\caption{Dirección MAC en salida de comando {\tt ip address}.}
	\label{fig:mac-address}
\end{figure}

Finalmente, definimos la dirección IP que queremos asignar, que en nuestro caso
es el 192.168.37.201. Esto lo hacemos con la opción {\tt fixed-address}.

\subsection{Pruebas}

Ya con nuestro servicio DHCP configurada, podemos empezar con las pruebas. Para
esto, primero hemos de empezar nuestro servicio. Como tan sólo estamos haciendo
pruebas todavía, vamos a usar directamente el comando {\tt dhcpd}. Esto lo
haremos usando la opción {\tt -cf} para especificar nuestro archivo de
configuración, y la bandera {\tt -d} para que veamos la salida por pantalla de
lo que vaya pasando:

\begin{verbatim}
# dhcpd -cd /etc/dhcp/dhcpd.conf -d
\end{verbatim}

Cuando ya esté encendido, podemos comprobar su correcto funcionamiento
conectando nuestros dispositivos a la red para que pidan una dirección IP por
medio de DHCP. Para nuestro dispositivo de IP fija, debería de aparecer algo
parecido a lo siguiente:

\begin{verbatim}
DHCPREQUEST for 192.168.37.201 from 7c:10:c9:25:95:e1 via enp3s0
DHCPACK on 192.168.37.201 to 7c:10:c9:25:95:e1 via enp3s0
\end{verbatim}

Esto indica que a este dispositivo se le ha dado la dirección IP 192.168.37.201,
como habíamos designado antes.

Luego, para los dispositivos de IP dinámica, la salida se parecerá algo más como
lo siguiente:

\begin{verbatim}
DHCPDISCOVER from 7c:10:c9:28:29:b5 via enp3s0
DHCPOFFER on 192.168.37.101 to 7c:10:c9:28:29:b5 (LAPTOP-NIMQD9EE)
via enp3s0
DHCPREQUEST for 192.168.37.101 (192.168.37.2) from 7c:10:c9:28:29:b5
(LAPTOP-NIMQD9EE) via enp3s0
DHCPACK on 192.168.37.101 to 7c:10:c9:28:29:b5 (LAPTOP-NIMQD9EE)
via enp3s0
\end{verbatim}

Verificamos que, efectivamente, se han asignado correctamente las direcciones IP
en nuestros dispositivos. Si es así, entonces ya hemos terminado de configurar
correctamente nuestro servicio DHCP (figura \ref{fig:static-ip}).

\begin{figure}[!htb]
	\centering
	\begin{subfigure}[tb]{0.45\textwidth}
		\centering
		\includegraphics[width=0.95\textwidth]{imgs/static-ip.png}
		\caption{Prueba de IP estática 192.168.37.201.}
		\label{fig:static-ip}
	\end{subfigure}
	\hfill
	\begin{subfigure}[tb]{0.45\textwidth}
		\centering
		\includegraphics[width=0.95\linewidth]{imgs/dynamic-ip.png}
		\caption{Prueba de IP dinámica.}
		\label{fig:dynamic-ip}
	\end{subfigure}
	\caption{}
\end{figure}

\subsection{Habilitación e Inicio del Servicio}

Cuando ya hayamos visto que todo funciona correctamente, ya podemos volver a
usar {\em Systemd} para administrar nuestro servicio, habilitándolo e
iniciándolo. De esta forma, cada vez que se reinicia la máquina inicializará
este servicio. Como antes, lo hacemos con el comando {\tt systemctl}:

\begin{verbatim}
# systemctl enable isc-dhcp-server
# systemctl start isc-dhcp-server
\end{verbatim}

Finalmente modificamos el archivo {\tt /etc/default/isc-dhcp-server}, cambiando
la línea de {\tt INTERFACESv4} a lo siguiente (asumiendo que la interfaz a
nuestra red es {\tt enp3s0}).

\begin{verbatim}
INTERFACESv4="enp3s0"
\end{verbatim}

\section{Conclusión}

El sistema DHCP es una herramienta muy útil, y es importante que todo
administrador de red sepa cómo configurar un servicio de este tipo, no por nada,
sino más todavía para facilitarle a él su propio trabajo. Tampoco es una
configuración muy difícil, si no se quiere hacer nada demasiado complejo, y
permite centralizar la asignación de direcciones IP.

\pagebreak

\section{Derechos de Autor y Licencia}

\noindent
Copyright \copyright\ \the\year\ Nicolás A. Ortega Froysa
<nicolas@ortegas.org> \\
\\
Este documento se distribuye bajo los términos y condiciones de la licencia
Creative Commons Attribution No Derivatives 4.0 International.

\end{document}
