
735 - ¿Quién Visita Tu Servidor? Descubre BOTS y HACKERS que Te Roban Recursos
¿Bots y hackers roban tus recursos? Usa OpenObserve (O2) para analizar los logs de tu servidor Linux. Descubre quién te visita y protege tu infraestructura.
Si tu servidor está expuesto a internet, es importante saber quién lo visita y con qué intenciones. Y te puedo asegurar que lo visita mucha gente, ya sean seres vivos o bots, y no todos con muy buenas intenciones. La cuestión es que en estos últimos días he estado dando una vuelta a revisar todo lo que sucede en mis servidores, y he probado distintas herramientas y opciones que me permiten descubrir quien visita mis servidores, donde van y con qué intenciones… o por lo menos basándose en lo que buscan, puedo intuir las intenciones con lo que lo hacen. Por supuesto, esto no debe quedarse en saber quién visita nuestro servidor y con qué intenciones, lo cierto es que tenemos que tomar cartas en el asunto y actuar, porque las visitas cuestan como te explicaré a lo largo del episodio.

¿Quién Visita Tu Servidor? Descubre BOTS y HACKERS que Te Roban Recursos
¿A que se debe esto?
El mes pasado Feedpress fue hackedeado, y la consecuencia directa de ello, fue que se alteraron los feeds de varios podcasts, entre ellos el de Sospechosos Habituales al que pertenece este podcast. La solución para resolver este problema fue utilizar una herramienta de la que he hablado en alguna ocasión conocida con Podmixer y que tengo alojada en mi servidor.
La cuestión es que mi servidor lo tenía restringido, mediante un plugin de Traefik, lo tenía restringido exclusivamente a España, pero, al tener que servir el feed de Sospechosos Habituales, he tenido que abrir el servidor al resto del mundo. Y en esa apertura me he encontrado visitantes desconocidos haciendo peticiones cuanto al menos curiosas. Esto me llevó a este episodio.
¿Porque es necesario conocer quien visita tu servidor?
En general no nos preocupamos en exceso por nuestra seguridad hasta que nos sucede algo. Algo muy típico es no preocuparse por tus datos, hasta que un día se corrompe el disco duro y pierdes todo lo que tienes en él. O no preocuparse por la seguridad de tu servidor, hasta que un día te das cuenta de que alguien ha entrado en él y ha hecho cosas que no debería haber hecho.
Pero además, tienes que tener en cuenta que cada visita cuesta. Me refiero a que cada visita supone un gasto de CPU y de memoria RAM. Cada visita tiene que ser convenientemente atendida, y esto impacta en los recursos de tu sistema. Cuantas mas visitas, mas consumo de recursos.
La cuestión es que tú quieres tener el mayor número de visitas posibles, pero evidentemente, quieres que se traten de visitas de calidad. No te interesa visitas que *miren
En busca de la solución perfecta
Con el objetivo de descubrir quien visita mi servidor, he estado probando distintas herramientas y opciones. La cuestión es que no existe una solución perfecta, pero si que he encontrado una combinación de herramientas que me permiten tener una visión bastante completa de lo que sucede en mi servidor.
Todo esto se hace inicialmente a través del access.log
de Traefik, que es el que me permite tener un registro de todas las peticiones que se hacen a mi servidor. A partir de ahí, he estado probando distintas herramientas para analizar estos logs y obtener información útil de ellos.
Este log se recoge, se procesa, para obtener IP desde la que se realiza la petición y determinar el país de procedencia y posteriormente se envía a una base de datos para posteriormente poderlo mostrar en un mapa que indique ubicación y número de peticiones.
Esto se puede hacer con distintas herramientas, y he estado probando distintas combinaciones, como por ejemplo,
- Traefik Dashboard
- Vector, Prometheus, Grafana y Loki.
- Vector, Victorialogs, Grafana y Loki.
- Vector y OpenObserve
Algunas de estas combinaciones son mas o menos sencillas de implementar, y no solo se trata de implementarlas, si no que además es necesario crear los dashboards, que también puede ser algo relativamente complejo.
Además de esto, hay que tener en cuenta el consumo de recursos de las distintas soluciones, ya que algunas de ellas pueden ser bastante pesadas y consumir muchos recursos de tu servidor.
Lo que buscaba es una herramienta lo más sencilla posible y que no se llevara por delante todos los recursos de mi servidor. Y al final la combinación con la que me he quedado ha sido Vector y OpenObserve, junto con la Traefik Log Dashboard.
Traefik Log Dashboard
Este es un interesante descubrimiento que nos permite tener información en tiempo real de los logs de Traefik con geolocalización incluida. Se trata de un proyecto de código abierto, donde el backend está implementado en Go y el frontend en React.
Características
- Monitorización en Tiempo Real: Actualizaciones en directo a través de WebSocket.
- Soporte OpenTelemetry OTLP: Receptor de telemetría directo para trazas en tiempo real desde Traefik.
- Fuentes de Datos Híbridas: Soporte tanto para el análisis de archivos de log como para las trazas OTLP.
- Geolocalización IP: Rastrea las solicitudes por país y ciudad con soporte para MaxMind GeoIP2.
- Analíticas Completas: Tasas de solicitud, tiempos de respuesta, códigos de estado y monitorización de errores.
- Interfaz de Usuario Moderna (UI): Construida con componentes Shadcn UI y gráficos en tiempo real.
- Filtrado Avanzado: Oculta servicios desconocidos e IPs privadas, con soporte de paginación.
- Soporte IPv6: Manejo adecuado de direcciones IPv6.
- Múltiples Fuentes de Log: Monitoriza varias instancias de Traefik simultáneamente.
- Contenedorizado: Despliegue sencillo con Docker Compose.
Instalación y configuración
Como te puedes imaginar, lo tengo instalado con Docker y el compose.yml
que utilizo es el siguiente,
logbackend:
image: ghcr.io/hhftechnology/traefik-log-dashboard-backend:latest
container_name: logbackend
restart: unless-stopped
init: true
networks:
- internal
volumes:
- traefik_logs:/logs:ro # Mount the Traefik logs directory
environment:
- NODE_ENV=production
- TRAEFIK_LOG_FILE=/logs/access.log # Path inside the container
- PORT=3001
logfrontend:
image: ghcr.io/hhftechnology/traefik-log-dashboard-frontend:latest
container_name: logfrontend
restart: unless-stopped
environment:
- BACKEND_SERVICE=logbackend
- BACKEND_PORT=3001
depends_on:
- logbackend
networks:
- proxy
- internal
labels:
traefik.enable: true
traefik.http.routers.logfrontend.rule: Host(`logs.tuservidor.es`)
traefik.http.routers.logfrontend.entrypoints: https
traefik.http.services.logfrontend.loadbalancer.server.port: 80
traefik.http.routers.logfrontend.middlewares: oidc-auth@file
volumes:
traefik-logs:
external: true
networks:
internal: {}
proxy:
external: true
Y la pinta que tien es la siguiente.
Vector y OpenObserve
Esta opción es para mi la ganadora al menos de momento, porque me permite de una forma realmente sencilla interactuar con los resultados. Al final, estoy guardando los logs de Traefik en una alternativa a ElasticSearch que es OpenObserve, y la verdad es que me está funcionando realmente bien. Y todo combiando con Vector, que es realmente una gozada de herramienta. Hasta la fecha he trabajado con Logstash y Kafka, pero es que Vector me tiene realmente enamorado.
Vector
Vector es una herramienta que permite recopilar, transformar y enrutar todos tus logs, métricas y trazas a cualquier proveedor que quieras hoy y a cualquier otro proveedor que puedas querer mañana. Vector permite una reducción drástica de costes, un enriquecimiento de datos novedoso y la seguridad de los datos. Es de código abierto y hasta 10 veces más rápido que cualquier alternativa.
El compose.yml
de Vector es el siguiente,
services:
vector:
image: timberio/vector:latest-alpine
container_name: vector
restart: unless-stopped
init: true
ports:
- 8686:8686
configs:
- source: vector
target: /etc/vector/vector.yaml
mode: "0400"
volumes:
- traefik_logs:/traefik_logs:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- geoip:/geoip_db
networks:
- networklog
- monitoring
volumes:
traefik_logs:
external: true
geoip:
external: true
networks:
networklog:
external: true
monitoring:
external: true
configs:
vector:
content: >
api:
enabled: true
address: "0.0.0.0:8686"
enrichment_tables:
geoip_city:
type: "geoip"
path: "/geoip_db/GeoLite2-City.mmdb"
sources:
docker_logs:
type: "docker_logs"
exclude_containers:
- den
- openobserve
- sorteabot
traefik_logs:
type: file
max_line_bytes: 2097152
include:
- /traefik_logs/traefik.log
traefik_access_logs:
type: file
max_line_bytes: 2097152
include:
- /traefik_logs/access.log
transforms:
access_logs:
type: "remap"
inputs:
- traefik_access_logs # Conecta esta transformación a tu source de logs
source: |-
. = parse_json!(string!(.message))
.geoip = get_enrichment_table_record!(table: "geoip_city", condition: { "ip": .ClientHost })
parsed_time = parse_timestamp!(.StartUTC, format: "%Y-%m-%dT%H:%M:%S.%9fZ")
.timestamp_ms = to_unix_timestamp(parsed_time, unit: "microseconds")
._timestamp = .timestamp_ms
.weight = 1
._msg = join!([.RequestAddr, .RequestMethod, .RequestPath])
sinks:
openobserve_docker:
type: "http"
inputs:
- docker_logs
uri: "http://openobserve:5080/api/default/docker_logs/_json"
method: "post"
auth:
strategy: "basic"
user: "${OO_USER}"
password: "${OO_PASS}"
compression: "gzip"
encoding:
codec: "json"
timestamp_format: "rfc3339"
healthcheck:
enabled: false
openobserve_traefik:
type: "http"
inputs: ["traefik_logs"]
uri: "http://openobserve:5080/api/default/traefik_logs/_json"
method: "post"
auth:
strategy: "basic"
user: "${OO_USER}"
password: "${OO_PASS}"
compression: "gzip"
encoding:
codec: "json"
timestamp_format: "rfc3339"
healthcheck:
enabled: false
openobserve_access:
type: "http"
inputs: ["access_logs"]
uri: "http://openobserve:5080/api/default/access_logs/_json"
method: "post"
auth:
strategy: "basic"
user: "${OO_USER}"
password: "${OO_PASS}"
compression: "gzip"
encoding:
codec: "json"
timestamp_format: "rfc3339"
healthcheck:
enabled: false
Un detalle interesante aquí es la configuración de la base de datos GeoIP, que es la que me permite obtener la localización de las IPs que visitan mi servidor.
Openobserve
OpenObserve es una plataforma de observabilidad de código abierto que unifica logs, métricas y trazas en una única interfaz. Está diseñada para ser altamente escalable y fácil de usar, permitiendo a los equipos de desarrollo y operaciones monitorear y analizar sus sistemas de manera eficiente. De esta herramienta te hablado en algún que otro episodio anterior, aunque por el momento no le he dedicado un episodio completo, cosa que tengo pendiente, por que se ha convertido en una herramienta imprescindible para mi en el día a día. Es el lugar donde envío toda la información que quiero recopilar y analizar con posterioridad.
OpenObserve, también conocido como O2, es una plataforma de observabilidad nativa de la nube que unifica logs (registros), métricas y trazas en una única y potente solución. Construida desde cero para los modernos entornos cloud, OpenObserve ofrece observabilidad de grado empresarial por una fracción del coste y la complejidad de las soluciones tradicionales.
Lo cierto es que es increíblemente sencillo de instalar y configurar, y ponerlo en marcha es cuestión de minutos. El compose.yml
que utilizo es el siguiente,
openobserve:
image: public.ecr.aws/zinclabs/openobserve:latest
init: true
container_name: openobserve
env_file:
- .env
volumes:
- data:/data
restart: always
networks:
- proxy
- networklog
- hookbridge
labels:
- traefik.enable=true
- traefik.http.services.dockerobserve.loadbalancer.server.port=5080
- traefik.http.routers.dockerobserve.entrypoints=https
- traefik.http.routers.dockerobserve.rule=Host(`${FQDN}`)
volumes:
data: {}
networks:
networklog:
external: true
proxy:
external: true
hookbridge:
external: true
Más información,