Net Emulation permite crear situaciones que nos permiten emular ciertos comportamientos indeseados, tales como retardos, paquetes erróneos, duplicidades, etc... Es decir que nos permite crear situaciones indeseadas de forma controlada con el fin analizar posibles reacciones por ciertos equipos ante dichas situaciones. Tanto la herramienta Traffic Control como el módulo netem vienen por defecto incluidos en Linux, pues ambos vienen incluidos por defecto con la paquetería de iproute2 con lo que afortunadamente no requieren instalación alguna.
El uso de este módulo en sí es bastante sencillo, si bien es importante conocer la estructura general que es necesaria conocer:
tc qdisc acción dev nombre_interfaz usuario netem acción_netem
Aquí podemos ver cuatro partes en cursiva, que serían las que variarían dependiendo de nuestras necesidades, cada parte tendría el siguiente significado:
- Acción: Cuando escribimos el comando siempre hay que especificar si se va a añadir un comportamiento personalizado, si se va a modificar o eliminar. Es decir que en esta parte podemos optar por hacer: add, change o del. Es importante tener en cuenta que una vez añadido una emulación a la interfaz de red, no podremos hacer otro add, sino que tendremos que hacer un change para modificarla o un del para eliminarla.
- Nombre_interfaz: Simplemente le decimos sobre qué interfaz de red queremos aplicar la emulación de red.
- Usuario: El usuario que realizará el cambio de comportamiento. Por lo general siempre será root.
- Comportamiento: Finalmente diríamos que comportamiento queremos emular; es decir qué emulación de red queremos hacer. Esta parte al ser algo extensa la explicaré con más detalle más adelante.
Teniendo clara esta estructura base, podemos empezar a realizar las primeras emulaciones de red.
Comenzaremos con una emulación muy sencilla pero muy útil, que es la de la implantación de retardos. Esto hace que cualquier interacción realizada con esta interfaz tardará un tiempo extra en ser realizada. Esto se logra gracias al comportamiento delay, cuyo comando completo sería:
tc qdisc acción dev nombre_interfaz usuario netem delay retardo_en_milisegundos
He aquí un comando a modo de ejemplo en el que vamos a añadirle un retardo de 200 ms a la interfaz de red eth0, con el usuario root:
tc qdisc add dev eth0 root netem delay 200ms
Una forma muy fácil de comprobar el efecto de este cambio es haciéndole un simple ping a la IP de dicha interfaz de red, tal y como podéis ver en la siguiente imagen:
Además de poner un retardo de Xms, podemos también hacer que dicho valor no siempre sea fijo, sino que oscile entre ese valor y Xms arriba o abajo de forma aleatoria. Por ejemplo si pusiésemos el mismo comando de antes con una oscilación de 10ms, la latencia del ping podría ser hasta 10ms mayor o menor. He aquí el comando que haría referencia a exactamente dicho ejemplo:
tc qdisc add dev eth0 root netem delay 200ms 10ms
En la imagen de a continuación podemos apreciar esa oscilación:
Obviamente podemos hacer más cosas aparte de crear retardos; otra funcionalidad muy útil de este módulo sería la de la posibilidad de que los paquetes recibidos se consideren como "perdidos", es decir que hayan paquetes que no hayan llegado a su destino. Para ello, en vez de recurrir al comportamiento delay recurriremos a loss, comportamiento en el que especificaremos qué % de paquetes queremos que se "pierdan". Por ejemplo podemos hacer que la mitad de los paquetes no lleguen a su destino, para lo cual el comando sería el siguiente:
tc qdisc add dev eth0 root netem loss 50%
Al igual que antes, con un simple ping también podemos verificar que ahora alrededor de la mitad de los paquetes enviados se perderán; he aquí una pequeña muestra a modo de ejemplo:
Casi tan grave como la perdida de paquetes es la duplicidad de éstos, cosa que afortunadamente también es emulable en Linux. Dicha emulación es posible gracias al comportamiento duplicate y usa la misma sintaxis que el anterior comando, sustituyendo, obviamente, loss por duplicate.
tc qdisc add dev eth0 root netem duplicate 50%
En este caso algunos de los pings que mandemos al equipo recibirán como respuesta que hay una duplicidad; es decir que respondería como si hubiesen dos equipos con la misma IP en la misma VLAN. Dichos pings con respuesta de duplicidad en la red tendrían la etiqueta DUP!, tal y como se puede ver en la siguiente captura:
Otro problema que puede surgir en una red es que los paquetes de red se encuentren corruptos, cosa que también podemos emular gracias corrupt que tiene la misma sintaxis que el anterior comando, sustituyendo duplicate por corrupt.
tc qdisc add dev eth0 root netem corrupt 50%
En este caso, la respuesta que recibiremos al hacerle ping será que se esperaba un valor determinado pero que han recibido uno diferente al que se debía, mostrándonos algo como lo de la captura mostrada aquí abajo:
Estas serían las diferentes emulaciones que se pueden hacer gracias a esta herramienta; emulaciones que, en mi opinión, no son pocas y pueden ser de gran ayuda a la hora de intentar reproducir problemas reales para después encontrarles solución. La potencia de el módulo Net Emulation queda patente ya que es increíblemente flexible y versátil. Obviamente las funciones pueden combinarse; es decir que se puede hacer que haya un delay determinado, con un % determinado de paquetes erróneos otro % determinado de paquetes duplicados, etc... Por ejemplo, podemos querer editar una de las reglas que hemos creado atrás para que tenga toda esta combinación de comportamientos; con lo que en vez de usar add, usaremos change para obtener el siguiente comando:
tc qdisc change dev eth0 root netem delay 100ms 20ms \
loss 1% duplicate 05%
Como podéis observar, el comando no es más que una combinación de los atrás vistos, con el cual se puede combinar una latencia alta con un pequeño porcentaje de paquetes perdidos y uno aun menor de duplicados. Un detalle importante a la hora de hacer uso de la función change; si nos fijamos en el valor anterior, se hace un change a los valores delay, loss y duplicate. Si anteriormente hubiese sido especificado un valor para corrupt, la acción change no modificaría su valor ni lo eliminaría a menos que se especificase específicamente. Es decir que si por ejemplo hubiésemos hecho un corrupt del 50% y luego hubiésemos introducido este comando, el valor de corrupt sería siendo el mismo.
Finalmente, para eliminar estos comportamientos especiales por completo, podemos recurrir a la acción del, para lo cual simplemente habría que escribir:
tc qdisc del dev eth0 root netem
Tal y como se puede ver en este artículo, la emulación de diferentes situaciones "conflictivas" es más sencillo de lo que parece, y afortunadamente, todo ello se puede hacer desde cualquier equipo con Linux instalado y sin herramienta especial alguna, estando dicha emulación al alcance de todo el mundo.
Espero que os haya resultado útil.
Saludos.