我使用的工具之一使用加密/解密通过网络发送数据。我正在修改工具,我需要确保数据实际上是以加密形式发送的。
3 回答
简短的回答:数据包在软件网络堆栈的最末端被窃听(例如在 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 安装包过滤器。这些操作有很多实现,我认为在最近的 LinuxPF_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
的传出数据包调用 注册的钩子,deliver_skb 调用用于 libpcap 的函数。dev_queue_xmit_nit
list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func
tpacket_rcv
dev_queue_xmit_nit 从dev_hard_start_xmit
(net/core/dev.c 中的第 2539 行)调用,这是 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),你可以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 轮询或 netif_rx,这里唯一的出口是netif_receive_skb
.
图片甚至显示了两个 pf_packet 钩子之一 - 图例下最左边的正方形(“net/packet/af_packet.c”) - 用于传出数据包。
你的工具是什么?它如何连接到网络堆栈?如果您能在Network_data_flow 图片中找到该工具,您就会得到答案。例如,NetfilterNF_HOOK
仅在ip_rcv
(incoming) ip_output
(本地传出) 和ip_forward
(outgoing from routing) 中挂钩 () - 就在 之后netif_receive_skb
和之前dev_queue_xmit
。
这两种工具都可以准确地捕获通过网络传输的数据。(把它想象成相当于“tee”的输出,既要显示又要归档;在这里,相同的数据也进入套接字以及 tcpdump 或其他任何东西。)
所以是的,如果您的工具配置正确以在发送数据之前对其进行加密,那么 tcpdump 或 Wireshark 应该在其数据包捕获中反映这一点。
是的,这些都是正确的工具。Wireshark 将识别 TLS 和 SSL 数据包,如果这是您用于加密的内容。您可以向 Wireshark 提供服务器的私钥并在必要时解密流量(DHE 和 ECDHE 等临时模式除外)。