В таких инструментах, как tcpdump, когда именно собираются сетевые пакеты? - PullRequest
6 голосов
/ 02 сентября 2010

Один из инструментов, которые я использую, использует шифрование / дешифрование для отправки данных по сети. Я модифицирую инструмент и должен быть уверен, что данные на самом деле отправляются в зашифрованном виде.

Являются ли Wireshark и tcpdump подходящими инструментами для этой цели? В какой момент во время передачи они захватывают сетевые пакеты?

Ответы [ 3 ]

12 голосов
/ 01 марта 2014

Краткий ответ: пакеты отправляются в самый конец программного стека (например, в Linux).

Длинный ответ с копанием кода в ядре tcpdump, libpcap и linux 3.12:

И Wireshark, и tcpdump используют libpcap, например,

http://sources.debian.net/src/tcpdump/4.5.1-2/tcpdump.c#L1472

    if (pcap_setfilter(pd, &fcode) < 0)

, которые в свою очередь устанавливают фильтр пакетов через setfilter_op и activ_op. Существует множество реализаций этих операций, и я думаю, что в последних версиях Linux PF_PACKET будет использоваться с pcap_activate_linux libpcap-1.5.3-2 / pcap-linux.c # L1287 :

/*
 * Current Linux kernels use the protocol family PF_PACKET to
 * allow direct access to all packets on the network while
 * older kernels had a special socket type SOCK_PACKET to
 * implement this feature.
 * While this old implementation is kind of obsolete we need
 * to be compatible with older kernels for a while so we are
 * trying both methods with the newer method preferred.
 */
status = activate_new(handle);

    ...
    activate_new(pcap_t *handle)
     ...
    /*
 * Open a socket with protocol family packet. If the
 * "any" device was specified, we open a SOCK_DGRAM
 * socket for the cooked interface, otherwise we first
 * try a SOCK_RAW socket for the raw interface.
 */
sock_fd = is_any_device ?
    socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
    socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

PF_PACKET реализован в ядре, в файле net / packet / af_packet.c . Инициализация PF_SOCKET выполняется в packet_do_bind с функцией register_prot_hook(sk) (если устройство находится в состоянии UP), , которая вызывает dev_add_pack из net / core / dev.c в зарегистрировать крючок:

 370 /**
 371 *      dev_add_pack - add packet handler
 372 *      @pt: packet type declaration
 373 *
 374 *      Add a protocol handler to the networking stack. The passed &packet_type
 375 *      is linked into kernel lists and may not be freed until it has been
 376 *      removed from the kernel lists.
 377 *
 378 *      This call does not sleep therefore it can not
 379 *      guarantee all CPU's that are in middle of receiving packets
 380 *      will see the new packet type (until the next received packet).
 381 */
 382
 383 void dev_add_pack(struct packet_type *pt)
 384 {
 385        struct list_head *head = ptype_head(pt);
 386
 387        spin_lock(&ptype_lock);
 388        list_add_rcu(&pt->list, head);
 389        spin_unlock(&ptype_lock);
 390 }

Я думаю, что обработчик pf_packet - функция tpacket_rcv(...) - будет зарегистрирован в ptype_all.

Хуки, зарегистрированные в ptype_all, вызываются для исходящих пакетов из dev_queue_xmit_nit («Подпрограмма поддержки. Отправляет исходящие кадры в любые сетевые ответвления, используемые в настоящее время.») С помощью list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func, delivery_skb вызывает функцию, которая равна tpacket_rcv для libpcap.

dev_queue_xmit_nit вызывается из dev_hard_start_xmit ( строка 2539 в net / core / dev.c ), что является AFAIK последней стадией (для исходящих пакетов) независимой от устройства обработки пакетов в сетевом стеке Linux.

Та же история для входящих пакетов, ptype_all -регистрационные хуки вызываются из __netif_receive_skb_core с такими же list_for_each_entry_rcu(ptype, &ptype_all, list) {.. deliver_skb..}. __netif_receive_skb_core вызывается с __netif_receive_skb в самом начале обработки входящих пакетов

Linux Foundation имеет хорошее описание сетевого стека (http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow),, вы можете увидеть dev_hard_start_xmit на изображении http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png (предупреждение, оно огромно) слева под легендой. И netif_receive_skb находится внутри самого правого нижнего квадрата ("net / core / dev.c"), который подается из IRQ, затем NAPI poll или netif_rx, и единственный выход отсюда - netif_receive_skb.

На рисунке даже показан один из двух хуков pf_packet - самый левый квадрат под легендой ("net / packet / af_packet.c") - для исходящих пакетов.

Какой у вас инструмент? Как он подключается к сетевому стеку? Если вы сможете найти инструмент в Network_data_flow picture , вы получите ответ. Например, Netfilter подключается (NF_HOOK) только в ip_rcv (входящий) ip_output (локальный исходящий) и ip_forward (исходящий из маршрутизации) - сразу после netif_receive_skb и непосредственно перед dev_queue_xmit.

5 голосов
/ 02 сентября 2010

Оба эти инструмента фиксируют данные точно по мере их поступления по проводам. (Думайте об этом как что-то вроде эквивалента "tee" для вывода, который будет выводиться на экран, а также в файл; здесь также те же данные поступают в сокет, а также в tcpdump или что-либо еще.)

Так что да, если ваш инструмент настроен правильно для шифрования данных перед отправкой, то tcpdump или Wireshark должны отразить это в своих перехватах пакетов.

1 голос
/ 02 сентября 2010

Да, это правильные инструменты.Wireshark определит пакеты TLS и SSL, если вы используете их для шифрования.Вы можете предоставить Wireshark закрытый ключ сервера и при необходимости расшифровать трафик (кроме эфемерных режимов, таких как DHE и ECDHE).

...