【问题标题】:In tools like tcpdump, when exactly are the network packets captured?在像 tcpdump 这样的工具中,网络数据包究竟是什么时候被捕获的?
【发布时间】:2011-04-07 09:34:51
【问题描述】:

我使用的其中一个工具使用加密/解密通过网络发送数据。我正在修改工具,我需要确保数据实际上是以加密形式发送的。

Wiresharktcpdump 是用于此目的的正确工具吗?他们在传输过程中的哪个时间点捕获网络数据包?

【问题讨论】:

    标签: networking encryption tcp wireshark tcpdump


    【解决方案1】:

    简答:数据包在软件网络堆栈的最末端被分流(例如在 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_packnet/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, &amp;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, &amp;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 之前。

    【讨论】:

    【解决方案2】:

    这两个工具都可以准确地捕获通过网络传输的数据。 (把它想象成相当于“tee”的输出,既要显示又要归档;在这里,相同的数据也进入套接字以及 tcpdump 或其他任何东西。)

    所以是的,如果您的工具配置正确,可以在发送数据之前对其进行加密,那么 tcpdump 或 Wireshark 应该在其数据包捕获中反映这一点。

    【讨论】:

    • 虽然这对于特定问题来说是一个非常好的答案,但这些工具实际上是在数据包传送到网络适配器时捕获数据包,而不是在它进入网络时捕获数据包。这意味着网络适配器所做的一切(过去只是 MAC FCS,但现在通常也是 IP/UDP/TCP 校验和)没有被正确捕获。
    • @Will Dean:适配器真的会修改 IP 和更高级别的校验和吗?这让我很惊讶,你有参考吗?
    • @GregS - 一个现代以太网控制器芯片的英特尔数据表会给你所有的血腥,但如果只是不相信我的问题,那么wireshark.org/faq.html#q11.1 应该让你放心.. .
    • @GregS - 给你:download.intel.com/design/network/datashts/82541er.pdf - 这部分也可以做 TCP 分段,所以软件栈底部和线路之间的关系会更加脆弱
    • @Will Dean:感谢这些链接。看起来以太网适配器越来越像网络处理器;很酷。
    【解决方案3】:

    是的,这些都是正确的工具。 Wireshark 将识别 TLS 和 SSL 数据包,如果这是您用于加密的内容。您可以向 Wireshark 提供服务器的私钥并在必要时解密流量(DHE 和 ECDHE 等临时模式除外)。

    【讨论】:

      猜你喜欢
      • 2016-10-11
      • 1970-01-01
      • 2021-08-03
      • 2015-10-12
      • 1970-01-01
      • 2011-08-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      相关资源
      最近更新 更多