lunes, 28 de septiembre de 2015

Error TXT DB 2 al generar certificados con easy-rsa

Recientemente estaba generando una lista de certificados digitales para un lote de routers que se van a desplegar, con tan mala suerte que en la lista de seriales de los routers habían 3 duplicados (justo al final y con diferentes nombres). Para la generación de los certificados utilizo como "Common Name (CN)" el serial del aparato, cual es mi sorpresa cuando casi al terminar, generando los últimos 3 me encuentro con el siguiente error:

"failed to update database TXT_DB error number 2"

Primera vez que observo tal error, y para colmo de males, el certificado parecía haberse creado, revisando el directorio donde los almaceno aparecían los mismos, me aventure a pensar que fue un error del sistema al procesarlos y que, con solo borrarlos y recrearlos todo estaría bien. Para mi desgracia al hacer esto ultimo, aparecía el mismo error de nuevo, googleandolo observo que este error solo lo arroja cuando se intenta crear un certificado cuyo CN ya esta registrado y la única forma de solventar esto es o revocando el certificado o esperando que expire (en 12 años en este caso). 

Pues nada hago el procedimiento estándar para revocar un certificado:

./revoke-full CN

Y me arroja un error diciendo que el certificado no se encuentra... Para los que no lo saben (yo no lo sabia) no se puede revocar un certificado digital sin tener el .crt (los cuales yo borre previamente) - Habiéndolo borrado desde la consola de Linux con rm, realmente mis esperanzas de recuperarlos eran pocas, y necesitaba tener esos certificados con el CN = Serial del router, dado que utilizo un script para autoconfigurar todos los routers y ellos descargan sus certificados de forma automática basándose en el serial así que utilizar otro CN no era una opción valida.

Resumiendo la solución, cuando se genera un certificado, se genera también un respaldo del archivo .crt con extensión .pem, solo que el nombre del mismo no concuerda con el CN (el nombre son unos caracteres HEX) y para poder ubicarlo entonces hay que revisar un archivo llamado index.txt (ubicado también en la carpeta keys). Los pasos son:

  • Abrimos el archivo index.txt de izquierda a derecha, hay 4 campos, primero una V o R (Valid o Revoked), siguiendo una serie de números, luego caracteres hex y por ultimo una linea larga que describe todo el certificado
  • Linea a linea buscamos y ubicamos el certificado cuyo CN concuerda con el .crt que borramos (dentro de la linea larga con la descripción del certificado)
  • El tercer campo (los caracteres HEX) nos dice el nombre del archivo .pem que es respaldo del .crt
  • Copiamos el archivo .pem que recién ubicamos en el mismo directorio pero colocando como nombre el CN y la extensión .crt 
  • Ahora si podemos utilizar ./revoke-full CN y funcionara
  • Borramos el .crt (nuevamente)

Ejemplo:

V       29000020045Z           15      unknown /C=MX/ST=SO/L=Hermosillo/O=pagina.com/OU=Conektame/CN=1000010B/name=servidor/emailAddress=correo@correo.com

En negrita están los datos que nos interesa, primero los caracteres HEX que identifican el archivo .pem y luego el CN que identifica el certificado. 

Tendríamos entonces que copias el archivo 15.pem a 1000010B.crt

De todo esto, solo recordar que:
  • Para revocar un certificado es necesario el .crt del mismo
  • los archivos .pem con copias de los archivos .crt generados 
  • Es conveniente hacer respaldos de todos los certificados y tenerlos en sitios diferentes para evitar inconvenientes como este en el futuro 
  • Si les da el error antes mencionado, recuerden, es porque ya generaron un certificado con ese CN

miércoles, 3 de junio de 2015

Cisco Dual-Wan (NAT)

Recientemente me encontré en la necesidad de asesorar a un cliente con un requerimiento que incluía realizar un balanceo de carga entre dos conexiones a Internet. En especifico los requerimientos fueron los siguientes:


  1. Balanceo de carga entre dos conexiones a Internet, pero este balanceo de carga debe de ser asimétrico, es decir, debe pasar mas trafico por una conexión que en la otra, en un ratio 1:2. 
  2. Se debe aplicar NAT a ambas conexiones. 
  3. Se debe realizar un seguimiento de cada conexión para deshabilitarla en caso de una falla indirecta en la misma. 
  4. Se requiere realizar port-forwarding en ambas conexiones a servicios y equipos específicos en la LAN. 

El siguiente diagrama, explica mejor la situación:





Lógicamente, el router que se debe configurar en esta ocasión, es el "NAT-ROUTER", En este caso, asumiremos lo siguiente:

  1. Los puertos conectados a los ISP son, F0/0 para el ISP01 y F0/1 para el ISP02
  2. El puerto conectado a la LAN es F1/0
  3. Del lado de la LAN solo existe una subred, 192.168.0.0/24
  4. Las IPs que nos asignaron los ISP son, ISP01 172.10.10.10 y ISP02 173.16.0.10
  5. Las puertas de enlace son ISP01 172.10.10.1 y ISP02 173.16.0.1

Para poder llevar a buen puerto este proyecto, se debe realizar lo siguiente:

Configurar NAT (PAT en este caso)

El proceso es exactamente el mismo que se realiza habitualmente, esto es, definir que interfaces son inside y que interfaces son outside, definir una lista de acceso con los hosts a los cuales se les realizara el NAT cuando salgan a internet, etc. Pero, adicionalmente, dado que esto es un entorno con dos WAN, es necesario definir reglas de NAT que permitan diferenciar cual se aplicara, según el puerto de salida del paquete.

Según documentación de Cisco, por la forma en que opera IOS con NAT, la simple definición de un ACL que defina los hosts que pueden conectarse a internet, no basta, dado que el sistema realiza una verificación de reglas NAT, luego de consultar la tabla de enrutamiento (y por ende, ya teniendo definida la interfaz de salida del paquete), esto implica que, salvo que definamos una regla NAT que adicionalmente considere la interfaz de salida, podemos terminar con una situación donde un paquete es traducido a una dirección de origen que no concuerda con la dirección de la interfaz de salida.

Ejemplo:

  1. Entra un paquete dirigido a 172.16.0.1 con origen 192.168.0.10, el router consulta su FIB (Tabla de Enrutamiento) y decide enviarlo por F0/0 (ISP01), la IP de esta interfaz es 172.17.0.10
  2. Luego de lo anterior, se consultan las reglas definidas para NAT, el router comprende que el paquete procede de una interfaz definida como inside y va dirigido a una interfaz outside, adicionalmente concuerda con una lista de acceso definida en la regla, realiza una traducción donde cambia la dirección de origen a 172.18.0.20 (la IP asignada a la interfaz F0/1, que conecta con ISP02).
  3. Envía el paquete por la interfaz F0/0
Normalmente un router solo enruta paquetes basado en la IP de destino, pero, que sucedería si el router del ISP02 en el caso anterior utilice algún mecanismo de filtrado o de Policy Based Routing? el paquete recibido por este no concuerda con la subred definida para ese enlace y podría perfectamente descartarlo precisamente por esta razón. 

Para solventar esto, debemos definir no solo listas de acceso de los hosts que queremos puedan tener conexion a internet, sino algo que nos permita definir que regla utilizar, segun la interfaz de salida seleccionada por el router. Para esto utilizaremos algo denominado en Cisco como "route maps". 

Estos mapas de ruta, permiten crear secuencias donde se definen diversos parámetros a evaluar (listas de acceso, interfaces de salida, DSCP, etc.) y solo devuelven como "verdadero" si todos se cumplen. 

Definiendo los route-maps

Definiremos dos route maps, uno por cada interfaz de salida que evaluen si la IP de origen del paquete y la interfaz de salida del mismo:

(en modo conf)
!Definimos primeramente nuestra ACL
ip access-list standard NAT_PERMITIDOS
   permit 192.168.0.0 0.0.0.255
!
!Este route map, verifica que el paquete salga por el ISP01
route-map 1 permit 10
   match ip address NAT_PERMITIDOS
   match interface fastethernet0/0
!
!Este route map, verifica que el paquete salga por el ISP02
route-map 2 permit 10
   match ip address NAT_PERMITIDOS
   match interface fastethernet0/1
!

Definiendo las reglas NAT

(en modo conf)
ip nat inside source route-map 1 interface fastethernet0/0 overload
ip nat inside source route-map 2 interface fastethernet0/1 overload

Como aprecian, no difiere mucho de la definicion de reglas NAT utilizando unicamente ACL.

Configuración de balanceo de carga y chequeo de conexión


Para rutas estáticas, balanceo de carga asimétrico es una función que no esta explicitamente definida en IOS, para lograr esto, jugaremos con la recursividad de las rutas, dado que normalmente los routers Cisco distribuyen el trafico de forma equitativa entre el numero de rutas que posean la misma métrica y la misma distancia administrativa, resulta evidente que, si creamos 3 rutas estaticas con la misma métrica, misma AD pero apuntando a diferentes salidas (2 al ISP01 y 1 al ISP02), obtendremos un balanceo de carga asimétrico con ratio 1:2 (dado que se reparte el 33% del trafico entre cada salida, pero dos de estas son la misma interfaz).

Adicionalmente, tenemos que considerar los problemas de conexión indirectos de cada ruta, normalmente una ruta es eliminada de la FIB cuando se detecta una falla directa de la interfaz de salida de dicha ruta (esto solo en el caso de rutas estáticas, en rutas aprendidas por protocolos de enrutamiento, el comportamiento es algo mas inteligente). ¿Qué sucede entonces cuando por problemas internos del ISP01 (por ejemplo) no se puede acceder a digamos, www.google.com (dado que el router decidió enviar el trafico hacia dicha pagina por este ISP), pero, la conectividad entre el NAT-ROUTER y el router de dicho ISP funciona correctamente? La ruta no se va a deshabilitar, ocasionando que se siga utilizando, lógicamente el trafico jamas alcanzara la pagina web de google y ahí es cuando tendremos al típico usuario llamando para decir "no hay internet".

Tenemos que utilizar algun mecanismo que permita monitorear el funcionamiento de la conexión, mas allá de la disponibilidad del enlace entre ambos routers. Con Cisco, tenemos una herramienta denominada IP SLA, el único problema de este comando, es que solo esta disponible en routers que posean licencia DATA. En cualquier caso, el procedimiento es como sigue:

Creamos los IP SLA

Estas son reglas de chequeo de servicios, en este caso crearemos dos reglas que chequeen la conectividad con www.google.com por medio de ICMP, una regla utiliza como interfaz de salida la del ISP01 y la otra la del ISP02.

(en modo conf)
ip sla 1 
   icmp-echo www.google.com source-ip 172.10.10.10
   frequency 10
!
ip sla 2
   icmp-echo www.google.com source-ip 173.16.0.10
   frequency 10
!
ip sla schedule 1 life forever start-time now
ip sla schedule 2 life forever start-time now
!

Frequency define cada tanto tiempo en segundos se debe realizar la prueba (en este caso 10 segundos) icmp-echo indica el tipo de prueba a realizar (ping) a que destino y con que origen (notese que los orígenes coinciden con las IP asignadas a nosotros por los ISP). IP SLA SCHEDULE, define cuando comienza a funcionar la prueba, en este caso empieza de inmediato y se debe mantener en funcionamiento de forma permanente. Si quieren verificar el funcionamiento basta utilizar el comando show ip sla.

Creamos los objetos TRACK

Estos objetos permiten en conjunto con los IP SLA devolver un estado verdadero o falso, según análisis de los resultados devueltos por IP SLA. En este caso, queremos que se tome cada IP SLA definido y se analice si existe o no conectividad, utilizamos lo siguiente:

(en modo conf)
track 1 ip sla 1 reachability
track 2 ip sla 2 reachability

Nota: En versiones anteriores de IOS los comandos antes expuestos no funcionan, si este es el caso, se debe hacer uso de los siguientes:

(en modo conf)
track 1 rtr 1 reachability

track 2 rtr 2 reachability

Configuramos las rutas estáticas

Finalmente creamos las rutas estáticas correspondientes, sin embargo, estas rutas tienen un añadido como se observa a continuación:

(en modo conf)
ip route add 0.0.0.0 0.0.0.0 172.10.10.1 track 1
ip route add 0.0.0.0 0.0.0.0 173.16.0.1 track 2
ip route add 0.0.0.0 0.0.0.0 fastethernet0/0 track 1

En este caso, observen el añadido de la palabra clave track, seguido de un numero que concuerda con los objetos track que creamos previamente. Esto le indica al router que solo debe instalar la ruta en la FiB cuando el objeto track devuelve como resultado de la prueba "verdadero" esto es, cuando se tiene conectividad con www.google.com, en caso contrario la ruta se elimina, evitando enviar trafico por esta si no se tiene un correcto funcionamiento. Ademas, también deben apreciar que existe una ruta adicional que apunta a la interfaz f0/0 (ISP01) ademas de la ruta que apunta directamente a la IP gateway de este ISP, esto es lo que comentaba de la recursividad y el balanceo de carga, las 3 rutas funcionan correctamente, tienen la misma AD y la misma métrica, dos de estas salen por la misma interfaz, recordemos que los routers Cisco envían de forma equitativa el trafico entre cada ruta, por ende aquí estamos obteniendo un balanceo de carga asimétrico 1:2 (por cada paquete que sale por F0/1, dos salen por F0/0).

Configuración Port-Forwarding

En este caso solo dejare la plantilla para realizar esto, se debe llenar por cada puerto que se requiera abrir. 

ip nat inside source static tcp/udp host_destino p_destino 172.10.10.10 p_origen extendable
ip nat inside source static tcp/udp host_destino p_destino 173.16.0.1 p_origen extendable