Tcpdump resuelve problemas encontrados en la producción de operación y mantenimiento

Fuente: Cuenta oficial de DevOpSec
Autor: DevOpSec

Como técnico, tcpdumpesta herramienta sigue siendo necesaria para entender

Cuando se encuentra con problemas de protocolo de red y está perdido, a menudo puede ver tcpdumplo que sucedió en el proceso de comunicación de la red para ayudar a localizar rápidamente el problema.

Este artículo solo presenta los problemas encontrados en el trabajo para su referencia. Su objetivo es proporcionar inspiración para resolver problemas similares en su trabajo. Cómo usar tcpdump específicamente google.

Se introducen los tres casos siguientes:

Caso 1: flumeEscribir kafkaun registro y reportar un error

Caso 2: LB(balanceo de carga) headerDespués de aumentar la solicitud, nginxno se puede obtener el registroheader key client_ip

Caso 3: consulta mysql QPSmuy alta, pero mysqlno lenta, quiero saber topK mysqlla declaración

Finalmente: la escena de la escena de captura del protocolo http

Caso 1: flumeEscribir kafkaun registro y reportar un error

flumeEl registro está escrito kafkade la siguiente manera y no hay otros errores. Mira el error de abajo, a kafka pushlos datosTimeoutException

Pero el puerto 9092 flumede la máquina telnet kafkaestá conectado

¿Cuál es la razón para esto?

No tengo ninguna idea al mirar los registros, tcpdumpasí que echa un vistazo a los paquetes.

13 May 2023 16:01:28,367 ERROR [SinkRunner-PollingRunner-DefaultSinkProcessor] (org.apache.flume.sink.kafka.KafkaSink.process:240)  - Failed to publish events
java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Batch Expired
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.valueOrError(FutureRecordMetadata.java:56)
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:43)
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:25)
        at org.apache.flume.sink.kafka.KafkaSink.process(KafkaSink.java:229)
        at org.apache.flume.sink.DefaultSinkProcessor.process(DefaultSinkProcessor.java:67)
        at org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:145)
        at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.kafka.common.errors.TimeoutException: Batch Expired
13 May 2023 16:01:28,367 ERROR [SinkRunner-PollingRunner-DefaultSinkProcessor] (org.apache.flume.SinkRunner$PollingRunner.run:158)  - Unable to deliver event. Exception follows.
org.apache.flume.EventDeliveryException: Failed to publish events
        at org.apache.flume.sink.kafka.KafkaSink.process(KafkaSink.java:252)
        at org.apache.flume.sink.DefaultSinkProcessor.process(DefaultSinkProcessor.java:67)
        at org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:145)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Batch Expired
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.valueOrError(FutureRecordMetadata.java:56)
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:43)
        at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:25)
        at org.apache.flume.sink.kafka.KafkaSink.process(KafkaSink.java:229)
        ... 3 more

Capturar paquetes en flumela máquina

tcpdump port 9092 -s 0 -A -e -vvv
16:46:31.324786 52:54:00:6f:bf:d2 (oui Unknown) > 98:f2:b3:2b:74:f0 (oui Unknown), ethertype IPv4 (0x0800), length 97: (tos 0x0, ttl 63, id 3722, offset 0,flags [DF], proto TCP (6), length 83)
    flume-001.28230 > 192-168-160-10.kafka.release.svc.cluster.local.XmlIpcRegSvc: Flags [P.], cksum 0xc1b4 (incorrect -> 0x3b21), seq 14182:14225, ack 6634, win 31200, length 43
E..S..@.?.k........
nF#...d.q#..P.y........'.........
producer-1......log_flume_topic

16:46:31.325436 98:f2:b3:2b:74:f0 (oui Unknown) > 52:54:00:6f:bf:d2 (oui Unknown), ethertype IPv4 (0x0800), length 704: (tos 0x0, ttl 64, id 39463, offset 0, flags [DF], proto TCP (6), length 690)
    192-168-160-10.kafka.release.svc.cluster.local.XmlIpcRegSvc > flume-001.28230: Flags [P.], cksum 0x4359 (correct), seq 6634:7284, ack 14225, win 50470, length 650
E....'@.@......
....#.nFq#....e.P..&CY....................kafka-002..#.......kafka-003..#.......kafka-001..#.........log_flume_topic.............................................................
...................................................     ..........................................................................................................................................................................................................................................................................................................................................................................................................................

A partir de la información de captura de paquetes anterior, 192-168-160-10.kafka.release.svc.cluster.local.XmlIpcRegSvcel contenido del paquete de retorno del nodo kafka eskafka-002..#.......kafka-003..#.......kafka-001..#.........log_flume_topic

kafka-002、kafka-003、kafka-001Es kafkael nombre del host. No es muy intuitivo verlo aquí. Guarde el paquete de datos en un archivo y whiresharkanalícelo.

Ejecute , y luego abra tcpdump port 9092 -s 0 -w kafka_traffic.pcapel archivo con [Falló la transferencia de imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leech, se recomienda guardar la imagen y cargarla directamente. Puede ver que el acuerdo tiene ywhireshark

inserte la descripción de la imagen aquí
kafkaKafka Metadata v0 requestKafka Metadata v0 Response

Haga clic en Kafka Metadata v0 requestel acuerdo para ver la información detallada
[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente
inserte la descripción de la imagen aquí

Haga clic en Kafka Metadata v0 Responseel acuerdo para ver la información detallada
[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente

inserte la descripción de la imagen aquí

en flumela maquinaping kafka-002

ping kafka-002                                           
ping: cannot resolve kafka-002: Unknown host

TimeoutExceptionEstá claro que hay un problema aquí , flume clientantes de escribir , la dirección devuelta es el nombre de host más el puerto kafkade la información kafkaobtenida kafka.brokerkafkabroker

flumekafka-002Después de obtener , dnsel análisis falla, lo que resulta en push evetuna falla

Solución:

Después flumede configurar en la máquina , el error desaparece y el problema se solucionakafka-002hosts

flumeHay algunas trampas en el registro aquí TimeoutException, en lugar de kafka-002 name reslove failedhacer que el problema de posicionamiento sea más difícil

Otra solución:

¿Por qué kakfa devuelve kafka-002el nombre de host en lugar de la ip?

Echemos un vistazo al archivo de configuración de kafka y descubramos que advertised.listeners=PLAINTEXT://kafka-002:9092
advertised.listenersla función de los parámetros es Brokerpublicar Listenerla información en Zookeeperel

Entonces , en lugar de obtener el nombre de host flumedesde allí , puede cambiar la configuración para reiniciar y resolver el problemakafkaipkafkaadvertised.listenersipkafka

Caso 2: LB(balanceo de carga) headerDespués de aumentar la solicitud, nginxno se puede obtener el registroheader key client_ip

Déjame hablar sobre la escena primero.

Después de LBhacer el equilibrio de carga de siete capas, remote_addrlo que ve es LB ip, así que agregue el del cliente ipa la solicitud a cargo del equilibrio header client_ip.

nginxSe agregó la impresión de registro y $http_client_ipno se obtuvo headerel valor de esto.

¿Cuál es la razón?

¿ Será porque no ha aumentado el número de socios responsables de la operación y mantenimiento de LB client_ip header?

¿O headerse agrega pero el valor está vacío?

Esto requiere que tcpdump capture paquetes para verificar nuestra suposición.

Ejecute el siguiente comando en nginx:

tcpdump -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'|grep client_ip

结果发现:

client_ip: 1.1.1.1

A partir de la información de captura de paquetes, se puede ver que el cliente ipestá configurado en headerel interior y LBla configuración de la descripción no es un problema, por lo que el problema viene de nginxeste lado.

¿Por qué pasar el valor $http_client_ipno obtenido header?

Encuentre la configuración relevante a través nginxdel sitio web oficial headerhttp://nginx.org/en/docs/http/ngx_http_core_module.html encontrado

Syntax:	underscores_in_headers on | off;
Default:	
underscores_in_headers off;
Context:	http, server

En este punto, se revela la verdad. nginxDe manera predeterminada, se ignorarán headerla evasión subrayada definida por el usuario y los conflictos nginxintegrados .header key

Problema solucionado tras modificar nginxajustes de configuraciónunderscores_in_headers no;

Caso 3: consulta mysql QPSmuy alta, pero mysqlno lenta, quiero saber topK mysqlla declaración

mysqlLa carga se vuelve alta y qpsextremadamente alta, pero no hay una consulta lenta, o puede ser que sql query timela consulta lenta no esté expuesta debido a una configuración irrazonable. Me preocupa que esto afecte el rendimiento de la base de datos durante mucho tiempo. Quiero para saber qué declaración lo causó?

No hay una auditoría habilitada aquí mysql, y la persona que llama no registra registros, por lo que no es fácil de solucionar.

¿Como lidiar con? ¿Hay alguna forma de obtenerlo de forma no intrusiva y sin intervención de I+D topK sql?

Ahí es cuando el nuestro tcpdumpbrilla

El script general para agarrar mysql es el siguiente:

cat /tmp/mdump.sh
tcpdump -i eth0 -s 0 -l -w - port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
    if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL)/i)
    {
        if (defined $q) { print "$q\n"; }
        $q=$_;
    } else {
        $_ =~ s/^[ \t]+//; $q.=" $_";
    }
}'

Ejecutar en la máquina mysql con alto qps

sh /tmp/mdump.sh > /tmp/m.sql
30s后ctrl + c
然后执行如下命令获取top 10 SQL

grep -i ' from ' /tmp/m.sql |grep -i ' where ' |awk -F'where|WHERE' '{print $1}'|sort|uniq -c |sort -rnk1|head -n 10

Si encuentra SQL de alta frecuencia, puede comunicarse con los desarrolladores, si hay nuevas funciones comerciales en línea y optimizar soluciones.

Desde este punto de vista, componentes similares también pueden capturar y localizar problemas de esta forma.

Aquí hay otra herramienta de captura de paquetes de red recomendada MySQLhttps://github.com/40t/go-snifferRedisMongoDBhttp

Finalmente: la escena de la escena de captura del protocolo http

Obtenga solicitudes HTTP GET

tcpdump -i enp0s8 -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

explicar:

tcp\[((tcp\[12:1\] & 0xf0) >> 2):4\]Los 4 bytes que definen la ubicación de la cadena que queremos interceptar (detrás del encabezado http).

0x47455420es G E Tel código ASCII de .

Personaje Valor ASCII
GRAMO 47
mi 45
T 54
Espacio 20

Obtenga solicitudes HTTP POST

tcpdump -i enp0s8 -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354

0x504F5354Representa el código ASCII P O S Tde .

Solicitud HTTP GET con puerto de destino 80

tcpdump -i enp0s8 -s 0 -A 'tcp dst port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

Solicitudes HTTP GET y POST con puerto de destino 80 o 443 (desde 10.10.10.10)

tcpdump -i enp0s8 -s 0 -A 'tcp dst port 80 or tcp dst port 443 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354' and host 10.10.10.10

Obtenga la solicitud y respuesta HTTP GET y POST

tcpdump -i enp0s8 -s 0 -A 'tcp dst port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x3C21444F and host 10.10.10.10'

El puerto de destino del filtro es 80, el host es 10.10.10.10, solicitud y respuesta de http get/post

0x3C21444F'<' 'D' 'O' 'C'Código ASCII, como identificador para archivos html

0x48545450Sí, 'H' 'T' 'T' 'P'código ASCII, utilizado para captar la respuesta HTTP

Supervisar todas las URL de solicitud HTTP (GET/POST)

tcpdump -i enp0s8 -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"

Obtenga la contraseña en la solicitud POST

tcpdump -i enp0s8 -s 0 -A -n -l | egrep -i "POST /|pwd=|passwd=|password=|Host:"

Tome las cookies en Solicitud y respuesta

tcpdump -i enp0s8 -nn -A -s0 -l | egrep -i 'Set-Cookie|Host:|Cookie:'

Filtrar encabezados HTTP

#从header里过滤出user-agent
tcpdump -vvAls0 | grep 'User-Agent:'

Supongo que te gusta

Origin blog.csdn.net/linuxxin/article/details/130662469
Recomendado
Clasificación