Mapa de relaciones: qué es y cómo crearlo desde cero — una guía clara

Mapa de relaciones: qué es y cómo crearlo desde cero — una guía clara

El grafo de relaciones es algo que en algún momento salva casi cualquier análisis: investigación de incidentes, OSINT, búsqueda de cadenas de fraude, análisis de dependencias en la infraestructura e incluso la revisión de procesos empresariales. Mientras tenga diez filas en una tabla, todo es tolerable. Cuando los datos se cuentan por cientos o miles, la mente deja de retener la imagen completa — y aquí el grafo empieza a funcionar realmente como "un segundo monitor" para el pensamiento.

Qué es un grafo de relaciones y en qué se diferencia de "solo un diagrama"

El grafo de relaciones es un modelo de datos en el que hay entidades (nodos) y relaciones entre ellas (aristas). Un punto importante: el grafo no se dibuja por estética. Se construye según reglas que permiten responder de forma inequívoca a preguntas como «quién está conectado con quién», «a través de quién pasa un camino», «qué nodos son los más influyentes», «dónde está el clúster», etc.

"Solo un diagrama" suele ser estático: cuadraditos, flechas, etiquetas explicativas, pero sin reglas estrictas de identificación, sin atributos y sin posibilidad de análisis automático. En cambio, con un grafo se puede:

  • ampliar automáticamente (cargar nuevos datos y relaciones);
  • calcular métricas (centralidad, distancias, componentes conectadas);
  • buscar patrones (por ejemplo, estructuras de interacción idénticas);
  • almacenar y versionar como datos, no como imagen.
Criterio "Diagrama" Grafo de relaciones
Identificadores a menudo condicionales ("Ivan", "servidor 1") ID estrictos, claves estables
Atributos en palabras o en campos parte del modelo (en nodos y relaciones)
Analítica casi siempre manual algoritmos, consultas, métricas
Escalado rápido se convierte en "enredo" se puede filtrar, agregar, clusterizar

De qué consta: objetos, relaciones, atributos

Para que un grafo sea útil conviene acordar de antemano tres cosas: qué objetos hay, qué relaciones existen entre ellos y qué atributos se almacenan. Es como una gramática mínima, sin la cual cualquier grafo se desmorona en caos.

1) Objetos (nodos) — "quién/qué" en su mundo de datos. Ejemplos para ciberseguridad y para investigaciones:

  • cuenta, usuario, rol;
  • dirección IP, dominio, host, contenedor, servicio;
  • archivo, hash, proceso;
  • empresa, persona, teléfono, email (en OSINT).

2) Relaciones (aristas) — "cómo están conectados". Aquí es útil definir los tipos de relación desde el inicio; si no, luego habrá "conectado-conectado" y no se entenderá qué significa:

  • usuario AUTHENTICATED_TO host;
  • host RESOLVES_TO IP;
  • dominio HOSTS servicio;
  • cuenta OWNS email/teléfono.

3) Atributos — propiedades de nodos y relaciones. Importante: los atributos no están solo en los nodos, también en las aristas. Por ejemplo, la relación "inicio de sesión en servidor" puede tener tiempo, método, origen y éxito.

Truco práctico: fijen desde el principio el mínimo obligatorio de atributos:

  • para el nodo: id, type, label (nombre legible), opcionalmente source y confidence;
  • para la relación: type, from, to, opcionalmente timestamp, weight, evidence.

Visualización de un grafo de relaciones en ciberseguridad: nodos (usuarios, direcciones IP, servidores) conectados por líneas dirigidas de interacción. Se muestra la agrupación de datos y el nodo central del ataque.
Ejemplo de visualización de un incidente. En el grafo se ve cómo eventos dispersos se unen en una cadena. En el centro está un nodo comprometido (dirección IP o servidor) que actúa como "hub", conectando amenazas externas con usuarios internos. Diferentes colores indican los tipos de entidad (Usuario, IP, Incidente).


Algoritmo mínimo de construcción (recolección de datos → normalización → visualización)

Si se construye "en serio" se puede caer en metodologías infinitas. Pero la línea básica de trabajo en la práctica es bastante pragmática. Lo más importante no son las herramientas, sino la disciplina en los pasos.

Paso 1. Recolección de datos

Definan de dónde provienen los hechos. Pueden ser logs, exportaciones de CRM, resultados de escaneos, notas OSINT, tickets, informes. En esta fase no intenten embellecer — simplemente recojan observaciones.

  • Registren la fuente primaria (al menos el nombre del archivo o del sistema).
  • Conserven los valores "crudos" tal como están (incluso si hay desorden).
  • Anoten por separado qué se considera hecho (por ejemplo: "email encontrado en un perfil", "la IP fue el origen de la conexión").

Paso 2. Normalización y "unificación" de entidades

El paso más importante: aquí el grafo o se vuelve sólido o se convierte en puré. Normalizar implica aplicar reglas comunes a los datos: formatos, mayúsculas/minúsculas, valores canónicos. La "unificación" (resolución de entidades) es cuando deciden si "Ivan Petrov" y "petrov_i" son el mismo objeto o no.

  • Definan claves: qué hace único al objeto (¿email? ¿UUID? ¿combinación de campos?).
  • Limpien basura: espacios extras, variantes de escritura, delimitadores raros.
  • Separe "valor" y "etiqueta": un ID puede ser uno y el nombre visible otro.
  • Si la certeza no es del 100%, guarden confidence y no unan forzosamente.

Paso 3. Construcción de la estructura del grafo

Ahora convierten hechos en nodos y relaciones. Es útil pensar así: cada afirmación se transforma en una arista. Por ejemplo: "la cuenta inició sesión en el host" → relación AUTHENTICATED_TO. "el dominio se resuelve en IP" → relación RESOLVES_TO.

Paso 4. Visualización

La visualización no sirve solo para "lucir"; es para comprobar el sentido común: detectar nodos excesivamente gordos, comprobar si el grafo se ha partido en islas, si las flechas apuntan correctamente o si hay duplicados.

  • Empiecen con un filtro: un solo caso/periodo/subgrafo.
  • Coloreen por tipos de entidad (al menos lógicamente, aunque la herramienta lo haga automáticamente).
  • Fíjense en los grados de los nodos: quien está conectado con todos suele ser o un "hub" real o un error de normalización.
[Lugar para captura: Grafo "enredo" vs Grafo "clústeres"]

Paso 5. Almacenamiento y reproducibilidad

Si el grafo se construye más de una vez, deja de ser "una imagen" y pasa a ser un proceso. Eso requiere formatos de almacenamiento y reglas de actualización: qué añadimos, qué recalculamos y cómo tratamos hechos conflictivos.

Práctica: construimos un grafo sencillo en Python (NetworkX)

Dibujar esquemas a mano es lento. El verdadero poder de los grafos aparece cuando los generas con scripts. Aquí hay un ejemplo en Python con la librería networkx que conecta un usuario, una dirección IP y un dominio.


import networkx as nx
import matplotlib.pyplot as plt # Para mostrar la imagen

# 1. Creamos un grafo vacío
G = nx.DiGraph() # DiGraph = grafo dirigido (importante para relaciones "quién -> a dónde")

# 2. Añadimos nodos con atributos (¡el tipo de entidad es crucial!)
G.add_node("ivan_admin", type="user", label="Ivan P.")
G.add_node("192.168.1.55", type="ip", is_internal=True)
G.add_node("malicious-site.com", type="domain", threat_level="high")

# 3. Añadimos relaciones (aristas)
# Ivan inició sesión en la IP
G.add_edge("ivan_admin", "192.168.1.55", 
           relation="LOGON", 
           timestamp="2023-10-27T10:00:00")

# Esta IP contactó con el dominio sospechoso
G.add_edge("192.168.1.55", "malicious-site.com", 
           relation="DNS_REQUEST", 
           count=14)

# 4. Análisis sencillo: encontrar el camino más corto
path = nx.shortest_path(G, source="ivan_admin", target="malicious-site.com")
print(f"Cadena de ataque: {path}")
# Salida: Cadena de ataque: ['ivan_admin', '192.168.1.55', 'malicious-site.com']

¿Qué ocurrió aquí? No solo dibujamos una línea. Creamos una estructura consultable: «Muestra todos los usuarios que están a 2 pasos de un dominio malicioso». En Excel eso llevaría horas; con un grafo la respuesta puede salir en milisegundos.

Errores comunes (duplicados de entidades, relaciones "sucias", dirección incorrecta)

Los errores en un grafo son traicioneros: parece convincente aunque sea incorrecto. Y cuanto más atractiva sea la visualización, más difícil es percibir que se está siendo llevado por mal camino.

1) Duplicados de entidades

Un clásico: el mismo objeto aparece fragmentado en cinco nodos ("example.com", "EXAMPLE.COM", "example.com/", " www.example.com" etc.).

  • Solución: canonización (minúsculas, trim, reglas para dominios/teléfonos), clave única.
  • Comprobación: nodos top por "similitud" de etiquetas, informe de duplicados potenciales.

2) Relaciones "sucias"

Aquí entra todo lo que convierte el grafo en ruido: relaciones sin tipo, relaciones "por si acaso", relaciones sin contexto. Es especialmente peligroso cuando una arista significa cosas distintas en distintos lugares.

  • Solución: conjunto fijo de tipos de relación y una descripción clara de lo que significa cada tipo.
  • Truco: guarden la prueba/contexto en el atributo evidence (por ejemplo, "evento de logon 4624", "WHOIS", "ticket #123").

3) Dirección incorrecta

La dirección de la arista no es una flecha decorativa. Es semántica. "Usuario → servidor" y "servidor → usuario" pueden producir resultados distintos en búsquedas de caminos y consultas.

  • Solución: definan de antemano cómo se leen las relaciones (habitualmente "sujeto → objeto de la acción").
  • Comprobación: tomen 10 relaciones al azar y léanlas en voz alta. Si suena extraño, el modelo está mal.

4) Nodos universales y "superhubs"

A veces aparece un nodo conectado con casi todo: "Google", "Unknown", "localhost", "N/A", "Russia", "admin". Parte de esos hubs pueden ser reales, pero con más frecuencia son consecuencia de datos sucios.

  • Solución: separar valores "de servicio" en un tipo aparte o excluirlos de la visualización.
  • Comprobación: ordenar nodos por grado (degree) y auditar manualmente el top-20.

Herramientas y formatos

Las herramientas son cuestión de comodidad y escala. Lo principal: separen almacenamiento y visualización. La herramienta de dibujo no tiene por qué ser su base de datos, y viceversa.

Formatos de datos: cómo almacenar

  • CSV — inicio sencillo. Normalmente se divide en dos archivos: nodes.csv y edges.csv. Ventaja: fácil de editar, compatible con Excel. Inconveniente: atributos anidados y estructuras complejas resultan incómodos.
  • JSON — flexible para atributos y anidamiento. Inconveniente: distintas herramientas esperan "dialectos" distintos de JSON.
  • GraphML — formato pensado para grafos, a menudo se importa bien en visualizadores. Ventaja: estructura y atributos. Inconveniente: verboso, no siempre agradable editar a mano.

Ejemplo de estructura JSON correcta

Muchos principiantes tienden a insertar objetos unos dentro de otros. No lo hagan. La estructura plana "lista de nodos + lista de aristas" (como en el ejemplo siguiente) es el estándar dorado. La entienden casi todas las librerías de visualización (D3.js, Cytoscape, Sigma.js).


{
  "nodes": [
    {
      "id": "user_101",
      "type": "employee",
      "label": "Alexey S.",
      "department": "IT"
    },
    {
      "id": "server_db_01",
      "type": "host",
      "label": "Database Server Primary",
      "ip": "10.0.0.5"
    }
  ],
  "edges": [
    {
      "source": "user_101",
      "target": "server_db_01",
      "relation": "ACCESS_GRANTED",
      "weight": 1,
      "metadata": {
        "method": "SSH",
        "last_seen": "2023-12-01"
      }
    }
  ]
}

Visualización y análisis

  • Gephi — visualizador popular para análisis de redes (clústeres, métricas, filtros).
  • Graphviz — cuando se necesita renderizar rápidamente un diagrama desde una descripción; útil para informes.
  • Cytoscape — visualización potente, especialmente cuando se desea controlar estilos y datos con flexibilidad.

Almacenamiento y consultas

  • Neo4j — una de las opciones más conocidas para almacenamiento y consultas en grafos.
  • TigerGraph — para cuando el grafo es grande y se necesitan cálculos de alto rendimiento.
  • JanusGraph — opción para quienes construyen un almacenamiento de grafos distribuido.

Práctica de almacenamiento "a la humana"

  • Almacenen los datos crudos por separado del grafo normalizado (si no, perderán contexto).
  • Mantengan un diccionario de tipos de entidad y relaciones (mini manual del proyecto).
  • Usen IDs estables (no "Ivan", sino person:sha256(...) o person:12345).
  • Si el grafo está vivo —piensen en versionado (al menos por fecha de snapshot) y reglas de deduplicación.

En resumen: un grafo de relaciones no es una imagen, sino una forma de mantener la realidad controlada cuando hay demasiada información. Empiecen por lo básico: nodos, relaciones, atributos mínimos, IDs limpios. Luego se sorprenderán de lo rápido que "hechos dispersos" se convierten en un mapa comprensible.

Alt text

¿Estás cansado de que Internet sepa todo sobre ti?

¡Únete a nosotros y hazte invisible!