跟踪数据包通过内核 (linux)

发布于 2024-12-13 16:22:12 字数 467 浏览 0 评论 0原文

我有两台机器设置为使用 Ip-Security,机器 A(我们称它们为 A 和 B)有一个套接字,该套接字绑定到本地机器上的特定 UDP 端口,并且它经常轮询它以查看是否收到任何内容在它上面。

当我禁用 IP 安全性时,两台机器之间的数据可以正常传输,并且我可以正常发送和接收数据包。但是,当启用 Ip-Security 时,数据包不会到达由机器 B 发送的机器 A 上的套接字。

我在两台机器上执行 tcpdump,我可以看到(加密的)数据包正在发送从机器 B 发出并在机器 A 上接收。但此后,数据包进入内核,并且在数据包解密或其他阶段的某个位置,数据包被丢弃。

我希望能够在数据包通过内核时跟踪它并查看它被丢弃的位置。是否有一些 /proc 我可以用于此目的?我能想到的另一种方法是在整个内核中插入调试语句并重新编译它,然后尝试再次发送数据包并进行调试。

感谢并抱歉发了这么长的信息,但这是必要的。

I have two machines which are set up to use Ip-Security and machine A (lets call them A and B) has a socket which is bound to a particular UDP port on the local machine and it polls it frequently to see if anything is received on it.

When I disable Ip-security, the data between the two machines goes through fine and I send and receive the packets fine. But when Ip-Security is enabled, the packet doesn't get to that socket on machine A sent by machine B.

I do a tcpdump on both the machines and I can see the (encrypted) packet being sent out from machine B and being received on machine A. But after that, the packet goes to the kernel and somewhere either in the decryption of the packet or at some other phase, the packet is dropped.

I want to be able to trace the packet as it goes through the kernel and to see where it is dropped. Is there some /proc that I can use for this purpose? The other method I can think of is to insert debug statements all over the kernel and recompile it and then try sending the packet again and going through the debug.

Thanks and sorry for the long message but it was necessary.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩人痒 2024-12-20 16:22:12

是的,正如 Dan 所说,SystemTap 很有用。但我最喜欢的是 ftrace。

供参考:

linux内核中UDP数据包的路径

因此,为了跟踪一般的网络流量,请将以下内容放入 bash shell 中并以 root 身份运行:

mkdir /debug
mount -t debugfs nodev /debug
mount -t debugfs nodev /sys/kernel/debug
echo '*' >/debug/tracing/set_ftrace_filter
echo function_graph >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
sleep 20
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace > /tmp/tracing.out$

等等接收入口路径:

 5)               |              tcp_recvmsg() {
 5)               |                lock_sock_nested() {
 5)   0.042 us    |                  _cond_resched();
 5)               |                  _raw_spin_lock_bh() {
 5)   0.040 us    |                    local_bh_disable();
 5)   0.414 us    |                  }
 5)   0.040 us    |                  _raw_spin_unlock();
 5)   0.040 us    |                  local_bh_enable();
 5)   1.814 us    |                }
 5)               |                skb_copy_datagram_iovec() {
 5)   0.042 us    |                  _cond_resched();
 5)   0.588 us    |                }
 5)   0.042 us    |                tcp_rcv_space_adjust();
 5)               |                __kfree_skb() {
 5)               |                  skb_release_all() {
 5)               |                    skb_release_head_state() {
 5)   0.044 us    |                      sock_rfree();
 5)   0.670 us    |                    }
 5)               |                    skb_release_data() {
 5)               |                      put_page() {
 5)   0.049 us    |                        put_compound_page();
 5)   0.449 us    |                      }

这是:

Netlink 处理:

 6)               |          rtnetlink_rcv() {
 6)               |            mutex_lock() {
 6)   0.090 us    |              _cond_resched();
 6)   1.455 us    |            }
 6)               |            netlink_rcv_skb() {
 6)               |              rtnetlink_rcv_msg() {
 6)   0.150 us    |                mutex_unlock();
 6)               |                __netlink_dump_start() {
 6)               |                  netlink_lookup() {
 6)   0.091 us    |                    _raw_read_lock();
 6)   0.100 us    |                    netlink_compare();
 6)   1.791 us    |                  }
 6)               |                  mutex_lock() {
 6)   0.095 us    |                    _cond_resched();
 6)   0.913 us    |                  }
 6)   0.100 us    |                  try_module_get();
 6)   0.090 us    |                  mutex_unlock();

这就是入口也是:

 3)               |                                                tcp_v4_rcv() {
 3)               |                                                  sk_filter() {
 3)               |                                                    security_sock_rcv_skb() {
 3)   0.076 us    |                                                      cap_socket_sock_rcv_skb();
 3)   0.867 us    |                                                    }
 3)   1.630 us    |                                                  }
 3)   0.076 us    |                                                  _raw_spin_lock();
 3)   0.477 us    |                                                  tcp_prequeue();
 3)               |                                                  tcp_v4_do_rcv() {
 3)   0.088 us    |                                                    tcp_md5_do_lookup();
 3)   0.109 us    |                                                    tcp_parse_md5sig_option();
 3)   0.072 us    |                                                    ipv4_dst_check();
 3)               |                                                    tcp_rcv_established() {
 3)   0.076 us    |                                                      tcp_parse_aligned_timestamp.part.34();
 3)               |                                                      tcp_queue_rcv() {
 3)               |                                                        tcp_try_coalesce.part.41() {
 3)   0.835 us    |                                                          skb_try_coalesce();
 3)   1.722 us    |                                                        }
 3)   2.637 us    |                                                      }

这是出口(从系统调用“sendmsg()”开始):

 5)               |  SyS_sendmsg() {
 5)               |    __sys_sendmsg() {
 5)               |      sockfd_lookup_light() {
 5)   0.080 us    |        fget_light();
 5)   0.502 us    |      }
 5)               |      ___sys_sendmsg() {
 5)   0.117 us    |        copy_msghdr_from_user();
 5)   0.101 us    |        verify_iovec();
 5)               |        sock_sendmsg() {
 5)               |          security_socket_sendmsg() {
 5)               |            apparmor_socket_sendmsg() {
 5)   0.092 us    |              aa_revalidate_sk();
 5)   0.580 us    |            }
 5)   1.044 us    |          }
 5)               |          unix_stream_sendmsg() {
 5)   0.113 us    |            wait_for_unix_gc();
 5)               |            security_socket_getpeersec_dgram() {
 5)   0.044 us    |              apparmor_socket_getpeersec_dgram();
 5)   0.479 us    |            }
 5)               |            sock_alloc_send_pskb() {
 5)               |              __alloc_skb() {
 5)               |                kmem_cache_alloc_node() {
 5)   0.042 us    |                  _cond_resched();
 5)   0.648 us    |                }
 5)               |                __kmalloc_reserve.isra.27() {
 5)               |                  __kmalloc_node_track_caller() {
 5)   0.074 us    |                    kmalloc_slab();
 5)   0.040 us    |                    _cond_resched();
 5)   0.504 us    |                    __slab_alloc();
 5)   1.878 us    |                  }
 5)   2.276 us    |                }
 5)   0.175 us    |                ksize();
 5)   4.217 us    |              }

希望你喜欢......

Yes, as Dan said, SystemTap is useful. But my favorite is ftrace.

For reference:

Path of UDP packet in linux kernel

So for tracing the network traffic in general, put the following in a bash shell and run it as root:

mkdir /debug
mount -t debugfs nodev /debug
mount -t debugfs nodev /sys/kernel/debug
echo '*' >/debug/tracing/set_ftrace_filter
echo function_graph >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
sleep 20
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace > /tmp/tracing.out$

And so on the receiving ingress path:

 5)               |              tcp_recvmsg() {
 5)               |                lock_sock_nested() {
 5)   0.042 us    |                  _cond_resched();
 5)               |                  _raw_spin_lock_bh() {
 5)   0.040 us    |                    local_bh_disable();
 5)   0.414 us    |                  }
 5)   0.040 us    |                  _raw_spin_unlock();
 5)   0.040 us    |                  local_bh_enable();
 5)   1.814 us    |                }
 5)               |                skb_copy_datagram_iovec() {
 5)   0.042 us    |                  _cond_resched();
 5)   0.588 us    |                }
 5)   0.042 us    |                tcp_rcv_space_adjust();
 5)               |                __kfree_skb() {
 5)               |                  skb_release_all() {
 5)               |                    skb_release_head_state() {
 5)   0.044 us    |                      sock_rfree();
 5)   0.670 us    |                    }
 5)               |                    skb_release_data() {
 5)               |                      put_page() {
 5)   0.049 us    |                        put_compound_page();
 5)   0.449 us    |                      }

and this:

Netlink processing:

 6)               |          rtnetlink_rcv() {
 6)               |            mutex_lock() {
 6)   0.090 us    |              _cond_resched();
 6)   1.455 us    |            }
 6)               |            netlink_rcv_skb() {
 6)               |              rtnetlink_rcv_msg() {
 6)   0.150 us    |                mutex_unlock();
 6)               |                __netlink_dump_start() {
 6)               |                  netlink_lookup() {
 6)   0.091 us    |                    _raw_read_lock();
 6)   0.100 us    |                    netlink_compare();
 6)   1.791 us    |                  }
 6)               |                  mutex_lock() {
 6)   0.095 us    |                    _cond_resched();
 6)   0.913 us    |                  }
 6)   0.100 us    |                  try_module_get();
 6)   0.090 us    |                  mutex_unlock();

and this is the ingress also:

 3)               |                                                tcp_v4_rcv() {
 3)               |                                                  sk_filter() {
 3)               |                                                    security_sock_rcv_skb() {
 3)   0.076 us    |                                                      cap_socket_sock_rcv_skb();
 3)   0.867 us    |                                                    }
 3)   1.630 us    |                                                  }
 3)   0.076 us    |                                                  _raw_spin_lock();
 3)   0.477 us    |                                                  tcp_prequeue();
 3)               |                                                  tcp_v4_do_rcv() {
 3)   0.088 us    |                                                    tcp_md5_do_lookup();
 3)   0.109 us    |                                                    tcp_parse_md5sig_option();
 3)   0.072 us    |                                                    ipv4_dst_check();
 3)               |                                                    tcp_rcv_established() {
 3)   0.076 us    |                                                      tcp_parse_aligned_timestamp.part.34();
 3)               |                                                      tcp_queue_rcv() {
 3)               |                                                        tcp_try_coalesce.part.41() {
 3)   0.835 us    |                                                          skb_try_coalesce();
 3)   1.722 us    |                                                        }
 3)   2.637 us    |                                                      }

And this is the egress (starting from the syscall "sendmsg()"):

 5)               |  SyS_sendmsg() {
 5)               |    __sys_sendmsg() {
 5)               |      sockfd_lookup_light() {
 5)   0.080 us    |        fget_light();
 5)   0.502 us    |      }
 5)               |      ___sys_sendmsg() {
 5)   0.117 us    |        copy_msghdr_from_user();
 5)   0.101 us    |        verify_iovec();
 5)               |        sock_sendmsg() {
 5)               |          security_socket_sendmsg() {
 5)               |            apparmor_socket_sendmsg() {
 5)   0.092 us    |              aa_revalidate_sk();
 5)   0.580 us    |            }
 5)   1.044 us    |          }
 5)               |          unix_stream_sendmsg() {
 5)   0.113 us    |            wait_for_unix_gc();
 5)               |            security_socket_getpeersec_dgram() {
 5)   0.044 us    |              apparmor_socket_getpeersec_dgram();
 5)   0.479 us    |            }
 5)               |            sock_alloc_send_pskb() {
 5)               |              __alloc_skb() {
 5)               |                kmem_cache_alloc_node() {
 5)   0.042 us    |                  _cond_resched();
 5)   0.648 us    |                }
 5)               |                __kmalloc_reserve.isra.27() {
 5)               |                  __kmalloc_node_track_caller() {
 5)   0.074 us    |                    kmalloc_slab();
 5)   0.040 us    |                    _cond_resched();
 5)   0.504 us    |                    __slab_alloc();
 5)   1.878 us    |                  }
 5)   2.276 us    |                }
 5)   0.175 us    |                ksize();
 5)   4.217 us    |              }

Hope you enjoy....

万水千山粽是情ミ 2024-12-20 16:22:12

请参阅名为 SystemTap 的项目。它允许您将用户友好的脚本插入任何内核代码,而无需重新编译内核。例如:

probe function("ip_rcv").call {
    printf("%d:   ->ip_rcv()\n", gettimeofday_ms()) 
}

它将为网络层中每个收到的数据包发出内核打印。当然,您需要阅读源代码才能更深入地了解网络堆栈。

SystemTap 非常有能力,并且对可以插入的各种钩子有详细的记录。

Please refer to the project named SystemTap. It allows you to insert user-friendly scripts hooking into any kernel code, without recompiling the kernel. For example:

probe function("ip_rcv").call {
    printf("%d:   ->ip_rcv()\n", gettimeofday_ms()) 
}

It will emit a kernel print for every received packet in the network layer. Of course, you would need to read the sources to follow from there deeper into the network stack.

SystemTap is very capable and quite documented about the various hooks that can be inserted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文