【发布时间】:2011-04-07 09:34:51
【问题描述】:
我使用的其中一个工具使用加密/解密通过网络发送数据。我正在修改工具,我需要确保数据实际上是以加密形式发送的。
【问题讨论】:
标签: networking encryption tcp wireshark tcpdump
我使用的其中一个工具使用加密/解密通过网络发送数据。我正在修改工具,我需要确保数据实际上是以加密形式发送的。
【问题讨论】:
标签: networking encryption tcp wireshark tcpdump
简答:数据包在软件网络堆栈的最末端被分流(例如在 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 和 activate_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 状态),which calls 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(...) function - 将在 ptype_all 中注册。
在ptype_all 中注册的钩子被调用用于来自dev_queue_xmit_nit 的传出数据包(“支持例程。将传出帧发送到当前正在使用的任何网络分路器。”)list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func,deliver_skb 调用函数@987654345 @ 代表 libpcap。
dev_queue_xmit_nit 从 dev_hard_start_xmit (Line 2539 in 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 基础对网络堆栈有很好的描述(http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow),您可以在图例下方左侧的图像http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png 上看到dev_hard_start_xmit(警告,它很大)。而netif_receive_skb 位于最右下方的方块(“net/core/dev.c”)内,由 IRQ、NAPI 轮询或 netif_rx 提供,这里唯一的出口是netif_receive_skb。
图片甚至显示了两个 pf_packet 钩子之一 - 图例下最左边的正方形 ("net/packet/af_packet.c") - 用于传出数据包。
你的工具是什么?它如何连接到网络堆栈?如果您能在Network_data_flow picture 中找到该工具,您将得到答案。例如,Netfilter 仅在ip_rcv(传入)ip_output(本地传出)和ip_forward(从路由传出)中被钩住(NF_HOOK)——就在netif_receive_skb 之后和dev_queue_xmit 之前。
【讨论】:
PF_PACKET 用于所有 2.x 和 3.x Linux 内核上的所有非古代版本的 libpcap。
这两个工具都可以准确地捕获通过网络传输的数据。 (把它想象成相当于“tee”的输出,既要显示又要归档;在这里,相同的数据也进入套接字以及 tcpdump 或其他任何东西。)
所以是的,如果您的工具配置正确,可以在发送数据之前对其进行加密,那么 tcpdump 或 Wireshark 应该在其数据包捕获中反映这一点。
【讨论】:
是的,这些都是正确的工具。 Wireshark 将识别 TLS 和 SSL 数据包,如果这是您用于加密的内容。您可以向 Wireshark 提供服务器的私钥并在必要时解密流量(DHE 和 ECDHE 等临时模式除外)。
【讨论】: