Transparencias de clase sobre DHCP

Tal y como comentaba ayer en esta entrada, voy a ir dejando todas mis transparencias de clases, ponencias, conferencias y cursos en Slideshare.

Hoy toca el turno del servicio DHCP, clase que impartía en la asignatura de Administración e Instalación de Redes de Computadores en las titulaciones de Informática.

De las diferentes versiones (en función de los años) que tengo, he decidido publicar estas:


Protección contra ARP poisoning

Ya he escrito en varias ocasiones acerca de problemas que permiten insertar un equipo entre nosotros y nuestros objetivos (Ataque Man In The Middle): aquí y aquí. En esta entrada, que amplía el “primer aquí”, el objetivo es explicar en qué consiste y cómo podemos abordarlo.

¿Qué es ARP Poisoning?

Consiste en conseguir indicarle a un nodo que la MAC asociada a una IP (por ejemplo la de nuestro router por defecto) es la otra diferente a la que tiene realmente el equipo objetivo. Conseguirlo es bastante fácil y, además, simplemente hay que usar el propio protocolo ARP. Una imagen vale más que mil palabras y, creo, la de la Wikipedia refleja bastante bien en qué consiste el envenamiento de ARP (también llamado, por el efecto, ARP Spoofing):

Leer más


IGMP: tráfico multicast y filtros

Cuando diseñamos una red una de las tecnologías/infraestructuras que planificaremos será la instalación de un cortafuegos*. En estas circunstancias tenemos que tener claro qué paquetes dejamos pasar, cuales desechamos, y todo en función de nuestra política de seguridad y sin perder la funcionalidad para la que estamos diseñando nuestra red.

Si utilizamos OSPF o, en general, si queremos manejar tráfico multicast, debemos habilitar los paquetes IGMP en nuestros filtros (suponiendo que tenemos la estrategia de denegar todo lo que no está explicitamente habilitado) ya que es el protocolo que utilizaran hosts y routers para establecer los miembros de los grupos de multicast. De este protocolo, debemos tener en cuenta, sobre todo, que se encapsula en datagramas IP con el número 2 de protocolo (esto implica que NO utiliza UDP ni TCP ni, por tanto, tiene puertos). Otro detalle que debemos tener en cuenta es que el TTL de los paquetes de IGMP, por defecto, es 1, lo que implica que no “atravesarán” los routers y no saldrán de la subred en la que se genera, aunque puede aumentarse para localizar servidores lejanos utilizando este campo como “barrera” y configurando los routers para que sean transparentes y no decrementen el TTL**.

La ejecución de las siguientes órdenes provocará que nuestro router de filtrado acepte y saque mensajes IGMP:

iptables -A INPUT -p igmp -j ACCEPT
iptables -A OUTPUT -p igmp -j ACCEPT

Para el caso de los grupos multicast relacionados con OSPF que comentábamos en la entrada anterior, podríamos limitar las reglas habilitando solo los grupos relacionados con OSPF:

iptables -A INPUT -p igmp -d 224.0.0.5 -j ACCEPT
iptables -A INPUT -p igmp -d 224.0.0.6 -j ACCEPT
iptables -A OUTPUT -p igmp -d 224.0.0.5 -j ACCEPT

Referencias

  1. Building Internet Firewalls, de Elizabeth D. Zwicky, Simon Cooper y D. Brent Chapman
  2. https://tools.ietf.org/html/rfc3376, RFC para IGMP versión 3
  3. http://tools.ietf.org/html/rfc2236, RFC para IGMP versión 2

* Prefiero usar el concepto de cortafuegos para la infraestructura de protección de red que diseñamos y que puede estar compuesta por varios elementos donde, uno de ellos, el dispositivo de red que filtra paquetes y que -casi- todo el mundo denomina cortafuegos, yo prefiero denominarlo router de filtrado.

** Una orden genérica para este caso es: iptables -A FORWARD -p igmp -j ACCEPT Si queremos, por ejemplo, especificar que el tráfico que queremos es el relacionado con el audio/vídeo: iptables -A FORWARD -p udp -m udp -d 239.0.0.0/16 –dport 5001 -j ACCEPT

 


Timeouts de TCP

En TCP(1) existen 4 tipos de timeouts (tiempos de espera) y cada uno de ellos se aplica en diferentes momentos y con diferente duración. Algunos, incluso, podemos evitarlos si es lo que deseamos…

Conocer estos tiempos es importante tanto para administradores de sistemas como para programadores de aplicaciones distribuidas (¡¡¡pocas no lo son ya!!!)

Leer más


Como cambiar la MAC en GNU/Linux

Existen ciertas circunstancias en las que cambiar la MAC de nuestra tarjeta de red nos facilita el trabajo. Por ejemplo, si tenemos filtros por MAC (como ocurre con muchos routers ADSL) y cambiamos la tarjeta de red de nuestro equipo, quizás sea más fácil cambiar la MAC de la nueva por la que tenía la vieja y que se le apliquen todos “las ventajas” que tengamos implementadas, que ir cambiando los filtros en cada uno de los dispositivos.

Sea por la razón que sea (alguna también puede no ser “benigna”), en Debian se realiza con la ejecución de estos comandos (suponemos que la NIC es eth0):

ip link set dev eth0 down
ip link set dev eth0 address aa:bb:cc:dd:ee:ff
ip link set dev etho up

Si queremos comprobar que todo ha ido bien: ip link show eth0

Para que se quede fijo y al reiniciar dispongamos de la nueva MAC, podemos crear un guión con las 3 órdenes anteriores y lanzarlo en el arranque de la máquina.


El cliente en Python

Y para terminar con el ejemplo de un esqueleto cliente-servidor en Python, el cliente:

#!/usr/bin/python
#encoding:utf-8
try:
 import socket
 import optparse,sys
except:
 print("Error running 'import optparse,socket,sys'. Maybe you have to install some python library :)")
parser = optparse.OptionParser("usage%prog " + "-s <target server> -p <target port>")
parser.add_option('-s', dest = 'server', type = 'string', help = 'Please, specify the target server '-s server'')
parser.add_option('-p', dest = 'port', type = 'string', help = 'Please, specify the target port '-p port'')
(options, args) = parser.parse_args()
if (options.server == None):
 print '[-] You must specify a target server: -s server.'
 exit(0)
if (options.port == None):
 print '[-] You must specify a target port: -p port'
 exit(0)
server = options.server
port = int(options.port)

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port on the server given by the caller
server_address = (server, port)
print('connecting to %s port %s' % server_address)
try:
 sock.connect(server_address)
except socket.error , msg:
 print 'Connect failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
 sys.exit()
try:
 message="Speaking with server "
 print("sending %s" % message)
 sock.sendall(message)
 amount_received = 0
 amount_expected = len(message)
 while amount_received < amount_expected:
 data = sock.recv(16)
 amount_received += len(data)
 print("received %s" % data)
finally:
 sock.close()

Creo que el código se explica solo. Tras realizar una correcta conexión, el cliente intercambiará un mensaje con el servidor. En ese trozo es donde se debería implementar el protocolo de aplicación que necesitemos.

La ejecución del cliente en el servidor implementado en las imágenes

Captura de pantalla de 2014-02-14 18:42:56

Referencias:

  1. Python para todos, de Raúl González Duque
  2. Entrada con la versión sencilla del servidor
  3. Entrada con la versión concurrente del servidor

nmap y python. Un ejemplo

Para realizar pruebas sobre una red o equipo -casi- todos pensamos, en seguida, en nmap. Muchas veces queremos automatizar ciertas tareas y cuando interviene nmap, con el módulo python-nmap, podemos programarlas con este maravilloso lenguaje. Si, por ejemplo, necesitamos saber si un equipo tiene abierto un puerto determinado, si está “vivo”,… podemos fácilmente usar la funcionalidad de nmap e incluirla en nuestro programa sin necesidad de hacer invocaciones de comandos del sistema.

Esta librería nos proporciona varias clases que implementan la funcionalidad, síncrona y asíncrona, de nmap. PortScanner es una de ellas y es la que se utiliza en el sencillo guión que se muestra como ejemplo y que permite comprobar el estado de uno o varios puertos indicados por parámetro. Antes de que se me olvide, en esta página podéis encontrar información.

#!/usr/bin/python
try:
    import optparse, sys, re, socket
except:
    print("Error executing 'import optparse, sys, re, socket' command")
    exit(1)
try:
    import nmap
except:
    print "Error importing nmap module. It is possible you need running 'apt-get install python-nmap'"
    exit(1)
def checkIp(ip):
    if (re.match("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",ip)):
        host = ip
    elif re.match(r'^[a-zA-Z0-9_]{,63}(.[a-zA-Z0-9_]{,63}){3}$',ip): #("^W+(.W)$", ip):
        host = socket.gethostbyname(ip)
    else:
        host=""
        print "Name/IP host wrong. You have to write a FQDN name or a IP direction"
        exit(3)
    return host
def main():
    parser = optparse.OptionParser("usage%prog " + "-H <target host> -p <target port> + -N <target_network>")
    parser.add_option('-H', dest = 'host', type = 'string', help = 'Please, specify the target host')
    parser.add_option('-P', dest = 'protocol', type = 'string', help = 'Please, specify the transport protocol: tcp or udp')
    parser.add_option('-p', dest = 'ports', type = 'string', help = 'Please, specify the target port(s) separated by comma')
    (options, args) = parser.parse_args()
    if (options.host == None): 
        print '[-] You must specify a target host or a target network.'
        exit(0)
    if (options.ports == None): 
        print '[-] You must specify a target port(s).'
        exit(0)
    if ((options.protocol == None) or (options.protocol != "tcp" and options.protocol != "udp")): 
        print '[-] You must specify the transport protocol: tcp or udp.'
        exit(0)
    protocol = options.protocol
    host=checkIp(options.host)    
    ports = options.ports.split(',')
    scanner=nmap.PortScanner() 
    for port in ports:
        try:
            print('Analizing %s, %s/%d' % (host, protocol,(int(port))))
            if (protocol != "tcp"):
                scanner.scan(host, port, '-sU')
            else:
                scanner.scan(host, port)
            print " [+] "+ host + "(" + scanner[host].state() + ") " + protocol +"/" + port + "->" + scanner[host][protocol][int(port)]['state']
        except nmap.PortScannerError:
            print('Nmap ERROR: %s ' % sys.exc_info()[0])
            exit(2)
        except:
            print("Unexpected ERROR: %s" % sys.exc_info()[0])
            exit(3)
        
if __name__ == "__main__":
    main()

Lo que hace el guión es, tras el formateo de los parámetros de entrada:

  1. Se comprueba si con el parámetro -H se ha especificado una dirección IP válida (regexp: “^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$”),  o un nombre de dominio completamente cualificado (regexp: r’^[a-zA-Z0-9_]{,63}(.[a-zA-Z0-9_]{,63}){3}$’,ip): #(“^W+(.W)$”) y, en ese caso, se resuelve por su ip (socket.gethostbyname(options.host)
  2. Declaramos la clase y se lanza la comprobación, en función del protocolo de transporte. Si es UDP, los permisos deben ser de root (no lo comprueba el guión –> mejora)
  3. Se muestra el resultado para todos los puertos indicados (opción -p), del protocolo definido (-P) y del host deseado (-H).

Rogue/Spoofing DHCP

Un problema de seguridad que podemos tener es que “alguien” logre situar, entre nosotros y nuestro destinatario, un elemento intermedio que haga lo que le dé la gana: desde registrar lo que hacemos (y nuestras contraseñas, por supuesto, como la NSA pero más modesto 🙂 ) hasta reenviar nuestras peticiones a otros servicios similares al que necesitamos/queremos, pero no lo “reales”.

Leer más


¿Qué pasa con nuestra conexión de red?

Para comprobar la velocidad efectiva de nuestra conexión de red, tenemos una aplicación como Network Diagnostic Tool (NDT). Se trata de un sofisticado test de diagnóstico y velocidad que no solo mide la velocidad de subida y descarga sino que pretende encontrar la causa de la limitación de la velocidad, diferenciando entre los problemas de infraestructura de red y la configuración del ordenador. Aquí, un servidor cercano. En la misma página que he enlazado en primer lugar tenemos, más abajo, la utilidad NPAD, cuyo objetivo es diagnosticar problemas en el rendimiento de la red.

Por otra parte, si lo que detecto es que determinados protocolos o contenido (como vídeo cuando me conecto a youtube) va “lento”, lo que debo hacer es comprobar, y no fiar me de las palabras, si mi proveedor de red está o no realizando filtros, penalizaciones de tráfico,…, e incumpliendo con la neutralidad de red. Para realizar estas comprobaciones, tenemos paquetes software como Glasnost o el Switzerland de la EFF. Gracias a programas como estos, nos ahorramos tener que analizar nosotros los paquetes que circulan por la red para comprobar si están siendo “retocados”.

Espero que os sean de utilidad.


Las cookies nos permiten ofrecer nuestros servicios. Al utilizar nuestros servicios, aceptas el uso que hacemos de las cookies. Más información.