G DATA XDR
Reducción del tráfico mediante el almacenamiento en caché de actualizaciones con HAProxy
Introducción
Este artículo describe cómo reducir el tráfico de red entre los G DATA Agent y el servicio backend de G DATA. Para ello, un HAProxy ejecutado localmente almacena temporalmente en caché los archivos de actualización descargados a través del puerto 80. La comparación previa de la lista de archivos y los hashes no se ve afectada: se realiza de forma independiente a través del puerto 443 y no se almacena en caché.
Un proxy con caché tiene la ventaja de reducir el volumen de descargas en la red del cliente. Las actualizaciones se descargan una sola vez de Internet y después se distribuyen localmente a todos los Agent de la red.
|
Este artículo se dirige principalmente a quienes administran sistemas y tienen conocimientos de Linux y redes. Los términos técnicos también se explican brevemente. Así, las personas sin conocimientos profundos de informática también pueden seguir el procedimiento. |
Conceptos básicos: ¿Qué es HAProxy y qué hace un proxy con caché?
Cuando muchos G DATA Agent se ejecutan en la misma red, normalmente cada Agent descarga por separado las actualizaciones de firmas y del programa directamente de Internet desde el servidor de actualizaciones de G DATA. Con cien endpoints, esto supone cien descargas idénticas a través de su conexión a Internet.
Un proxy es un intermediario entre los G DATA Agent y el servicio backend de G DATA. Una caché es un almacenamiento temporal. La primera solicitud de un archivo de actualización se envía a Internet de la forma habitual. Además, la respuesta se guarda localmente. Cada solicitud posterior del mismo archivo se atiende directamente desde este almacenamiento local. De este modo, no se vuelve a utilizar la conexión a Internet para descargarlo.
HAProxy es un software de código abierto ampliamente utilizado. Desempeña esta tarea de forma fiable como proxy TCP/HTTP con función de caché.
Requisitos previos
-
Un servidor Linux (p. ej., Debian/Ubuntu) en la red. Todos los G DATA Agent deben poder acceder a este servidor.
-
Privilegios de root o sudo en este servidor.
-
Un certificado TLS válido, incluida la cadena de certificados. Debe ser válido para el nombre de host con el que los Agent acceden al proxy por HTTPS (solicitudes de índices y metadatos).
-
Conexiones de red permitidas:
-
El servidor proxy debe poder acceder al servidor de actualizaciones de G DATA agent-update-server.gdatasecurity.de. Para ello se necesitan dos puertos: el puerto 443 de HTTPS y el puerto 80 de HTTP.
-
Los G DATA Agent también deben poder acceder al servidor proxy a través del puerto 443 de HTTPS y del puerto 80 de HTTP.
-
-
Es útil tener conocimientos básicos sobre los archivos de configuración de HAProxy, aunque esta documentación proporciona una plantilla lista para usar.
Acceso a la nube de G DATA
Para garantizar la notificación fiable y oportuna de eventos e incidentes, la nube de G DATA debe ser accesible y no debe estar bloqueada por un firewall. Para ello son necesarias las siguientes configuraciones. Debe garantizarse que *.gdatasecurity.de y *.gdatasoftware.com puedan resolverse y sean accesibles.
-
Aperturas de puertos
-
Los Agent de G DATA en los endpoints deben poder alcanzar las IP de nuestros servidores backend a través del puerto TCP/443, rango de IP 194.156.84.0/22 (194.156.84.0 - 194.156.87.255).
-
-
Protocolos
-
Los sistemas deben poder comunicarse mediante los protocolos HTTPS:// y también WSS://.
-
-
TLS
-
Los servidores proxy utilizados deben ser compatibles como mínimo con TLS 1.2.
-
No debe haber SSL Inspection ni Deep Packet Inspection.
-
Debe poder establecerse una conexión cifrada mediante TLS con chess.gdatasecurity.de. Para ello, debe existir un certificado raíz correspondiente.
-
Configuración de HAProxy
Paso 1: Instalar HAProxy
Instale HAProxy mediante el gestor de paquetes de su distribución de Linux; por ejemplo, en Debian/Ubuntu:
sudo apt update
sudo apt install haproxy
Paso 2: Preparar el certificado
La conexión TLS de los Agent termina en HAProxy. Para ello, HAProxy necesita un certificado con su clave privada correspondiente.
|
HAProxy requiere que el certificado, la cadena de certificados y la clave privada estén en un único archivo PEM, combinados en este orden. Los componentes son los siguientes: |
| Orden | Componente |
|---|---|
1 |
El certificado propiamente dicho (certificado del servidor). |
2 |
Los certificados intermedios, también denominados Bundle o Chain. |
3 |
El certificado de la autoridad de certificación raíz, si está disponible por separado. |
4 |
La clave privada. |
Combine los archivos en un archivo PEM exactamente en este orden. Ejemplo:
cat server.crt intermediate.crt root-ca.crt server.key > /etc/haproxy/certs/haproxy-cache.pem
chmod 640 /etc/haproxy/certs/haproxy-cache.pem
chown root:haproxy /etc/haproxy/certs/haproxy-cache.pem
Paso 3: Crear la configuración de HAProxy
Cree el archivo de configuración haproxy.cfg en /etc/haproxy/. Utilice para ello la plantilla que figura más abajo (véase Ejemplo de configuración completa). Sustituya el archivo existente por esta plantilla.
Adapte los siguientes marcadores de posición:
| Marcador de posición | Significado |
|---|---|
{{ haproxy_caching_bind }} |
La dirección IP en la que escucha HAProxy. Es la IP a través de la cual los Agent acceden al proxy. |
{{ haproxy_caching_server_cert }} |
La ruta completa al archivo de certificado PEM del paso 2, p. ej., /etc/haproxy/certs/haproxy-cache.pem. |
{{ haproxy_caching_server }} |
El nombre de host interno con el que los Agent acceden al servidor de caché. Este nombre es el que se espera en la cabecera Host. |
Paso 4: Iniciar o reiniciar HAProxy
Reinicie el servicio después de crear o modificar la configuración:
sudo systemctl restart haproxy
sudo systemctl enable haproxy
Paso 5 (opcional): Comprobar la configuración
Compruebe la sintaxis del archivo de configuración antes de reiniciar HAProxy. Así podrá detectar errores tipográficos con antelación:
haproxy -c -f /etc/haproxy/haproxy.cfg
Si la comprobación no detecta errores, se muestra Configuration file is valid.
Ejemplo de configuración completa
El siguiente archivo haproxy.cfg sirve como plantilla. Sustituya los tres marcadores de posición. Su significado se explica en Configuración de HAProxy.
global
log /dev/log sample 1:10 local0
log /dev/log sample 1:10 local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
maxconn 256000
hard-stop-after 15m
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-keep-alive
option forwardfor
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 20s
timeout server 20s
timeout http-keep-alive 10s
timeout check 10s
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend stats
bind {{ haproxy_caching_bind }}:8404 ssl crt {{ haproxy_caching_server_cert }} alpn h2,http/1.1
stats enable
stats uri /
stats refresh 10s
http-request set-log-level silent
http-request use-service prometheus-exporter if { path /metrics }
# ---------------------------------------------------------------------------
# Puerto 80 (HTTP): descarga de archivos propiamente dicha; AQUÍ se usa la caché.
# ---------------------------------------------------------------------------
frontend http_update_server
bind {{ haproxy_caching_bind }}:80
acl is_update_download path_beg /api/v2/update/download/
acl is_caching_host req.hdr(host) -i {{ haproxy_caching_server }}
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request set-header Host %[req.hdr(Host)]
# Solo las solicitudes de descarga al nombre de host conocido se atienden desde la caché.
use_backend http_update_server_backend if is_update_download is_caching_host
# Por seguridad, redirigir a HTTPS todas las demás solicitudes del puerto 80.
http-request redirect scheme https code 301 unless is_update_download
default_backend nomatch
# ---------------------------------------------------------------------------
# Puerto 443 (HTTPS): comparación de índices y hashes; reenvío SIN caché.
# Estas respuestas son pequeñas, cambian con frecuencia y G DATA
# las excluye deliberadamente del almacenamiento en caché.
# ---------------------------------------------------------------------------
frontend https_update_server
bind {{ haproxy_caching_bind }}:443 ssl crt {{ haproxy_caching_server_cert }} alpn h2,http/1.1
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request set-header Host %[req.hdr(Host)]
use_backend https_update_server_backend if { req.hdr(host) -i {{ haproxy_caching_server }} }
default_backend nomatch
cache objectcache_update_server
total-max-size 3000
max-object-size 200000000
max-age 86400
backend http_update_server_backend
balance roundrobin
http-request set-header Connection keep-alive
http-request set-header Host agent-update-server.gdatasecurity.de
http-request set-header X-Forwarded-Proto http
http-request cache-use objectcache_update_server if { path_beg /api/v2/update/download/ }
http-response cache-store objectcache_update_server
option httpchk GET /api/status
http-check send hdr Host agent-update-server.gdatasecurity.de
http-check expect status 200
server agent-update-server.gdatasecurity.de agent-update-server.gdatasecurity.de:80 check inter 10s
backend https_update_server_backend
balance roundrobin
http-request set-header Connection keep-alive
http-request set-header Host agent-update-server.gdatasecurity.de
http-request set-header X-Forwarded-Proto https
option httpchk GET /api/status
http-check send hdr Host agent-update-server.gdatasecurity.de
http-check expect status 200
server agent-update-server.gdatasecurity.de agent-update-server.gdatasecurity.de:443 check inter 10s check-sni agent-update-server.gdatasecurity.de sni str(agent-update-server.gdatasecurity.de) ssl verify required ca-file /etc/ssl/certs/ca-certificates.crt
backend nomatch
errorfile 503 /etc/haproxy/errors/503.http
Explicación de la configuración
A continuación se explica cada una de las secciones más importantes. Así, también las personas con menos experiencia en HAProxy pueden comprender la configuración.
| Sección | Explicación |
|---|---|
global / defaults |
Ajustes básicos de procesos y conexiones. Ejemplos: registro de eventos, número máximo de conexiones simultáneas (maxconn), tiempos de espera predeterminados. Por lo general, no es necesario ajustar estos valores. |
frontend stats |
Proporciona una página de estado en el puerto 8404. A través de esta página puede supervisar el estado de HAProxy, también en formato Prometheus (/metrics). |
frontend http_update_server |
El punto de entrada para las descargas de archivos propiamente dichas en el puerto 80. Solo las solicitudes bajo /api/v2/update/download/ dirigidas al nombre de host conocido se envían al backend que utiliza la caché. Todas las demás solicitudes del puerto 80 se redirigen a HTTPS por seguridad. |
frontend https_update_server |
El punto de entrada para las comparaciones de índices y hashes en el puerto 443 (TLS). Aquí HAProxy comprueba si el nombre de host solicitado ({{ haproxy_caching_server }}) corresponde al backend de actualizaciones. Solo entonces reenvía la solicitud. De lo contrario, la solicitud se envía al backend nomatch y recibe el error 503. Aquí no se utiliza la caché. |
cache objectcache_update_server |
Define el almacenamiento temporal. Hay tres valores importantes: el tamaño máximo total de la caché (total-max-size, en MB), el tamaño máximo de un archivo individual (max-object-size, en bytes) y el tiempo máximo de permanencia de un objeto en la caché (max-age, en segundos). La plantilla utiliza unos 3 GB de tamaño total, hasta 200 MB por archivo y 24 horas de validez. Solo el backend HTTP utiliza esta caché. |
backend http_update_server_backend |
Reenvía las solicitudes de descarga sin cifrar (puerto 80) a agent-update-server.gdatasecurity.de. La línea http-request cache-use … if { path_beg /api/v2/update/download/ } garantiza que solo se almacene en caché esta ruta. La comprobación http-check verifica continuamente si el servidor de G DATA está accesible. |
backend https_update_server_backend |
Reenvía las solicitudes de índices y hashes cifradas (puerto 443, con verificación del certificado) al mismo servidor de G DATA. Este backend no contiene ni cache-use ni cache-store. Las respuestas se reenvían, pero no se almacenan. |
backend nomatch |
Recoge todas las solicitudes que no corresponden a ningún host conocido. Estas solicitudes reciben el error 503. Así, la configuración impide el uso indebido como proxy abierto. |
|
HAProxy solo almacena en caché las solicitudes bajo la ruta /api/v2/update/download/ a través de HTTP. Las solicitudes de índices y hashes por HTTPS siguen su curso sin cambios. Otras comunicaciones de los Agent, como la telemetría o las notificaciones al servicio backend de XDR, no se ven afectadas por el almacenamiento en caché. |
Reconfigurar los Agent para utilizar el servidor de caché
Si ya ha instalado los G DATA Agent en los endpoints, póngase en contacto con el soporte técnico en el teléfono +49 234 9762-901. El equipo de soporte reconfigurará sus G DATA Agent para utilizar el servidor de caché.
Si todavía no ha desplegado ningún G DATA Agent, cree una configuración de instalación indicando la dirección del proxy. Todos los endpoints que se instalen con el SetupID correspondiente recibirán sus actualizaciones a través de su proxy.
|
Compruebe que la configuración funciona y que los endpoints reciben actualizaciones. Los endpoints que no reciben actualizaciones representan un riesgo de seguridad. Mantenga habilitado el servidor de respaldo en la configuración (solo debe deshabilitarse en casos excepcionales justificados). Con el servidor de respaldo habilitado, sus endpoints también recibirán actualizaciones cuando salgan de la red (por ejemplo, los portátiles) o si falla su servidor proxy inverso. |
Resolución de problemas
| Síntoma | Procedimiento |
|---|---|
HAProxy no se inicia |
Compruebe la configuración con haproxy -c -f /etc/haproxy/haproxy.cfg. Compruebe también el estado del servicio con systemctl status haproxy y journalctl -u haproxy. |
Los Agent reciben errores de certificado |
Compruebe dos cosas: ¿contiene el archivo PEM el certificado, los certificados intermedios y la clave privada en el orden correcto? ¿Coincide el nombre de host del certificado con {{ haproxy_caching_server }}? |
No se aprecia una reducción del tráfico de Internet |
Compruebe en la página de estado (frontend stats, puerto 8404) si las solicitudes de descarga pasan por el backend http_update_server_backend y si se atienden solicitudes desde la caché. El backend https_update_server_backend no utiliza la caché de forma deliberada. |
Las solicitudes se envían al backend nomatch |
La cabecera Host de la solicitud entrante no coincide con {{ haproxy_caching_server }}. Compruebe la configuración de los Agent y la resolución DNS. |