Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket Filter Type Programs capturing outgoing packets as well. #101

Open
Saurabh2402 opened this issue Dec 20, 2024 · 1 comment
Open

Comments

@Saurabh2402
Copy link

Hello,
I tried using the socket filter program and I was successfully able to capture the outgoing packets,
I tried it on kernal versions - 5.4, 6.1, 6.8.
It has worked successfully.

https://github.com/isovalent/ebpf-docs/blob/master/docs/linux/program-type/BPF_PROG_TYPE_SOCKET_FILTER.md#:~:text=(the%20program%20isn%27t%20called%20for%20egress/outgoing%20packets)
Do we have any documentation link of linux which states that it wont work,
Also as mentioned in the above link that tcpdump uses socket filter,
and tcpdump can capture outgoing traffic - https://4sysops.com/archives/capture-outbound-connections-initiated-on-your-host-with-tcpdump-and-windump-on-linux-and-windows/

Can we have some documentation stating that socket filter for outgoing traffic not works or works on some specific kernal versions,
just for the proof.

Thanks.

@dylandreimerink
Copy link
Collaborator

I tried using the socket filter program and I was successfully able to capture the outgoing packets

What does this look like? Perhaps I am missing something somewhere, but looking at the kernel code (more on this below) the eBPF filter program seems to only be called in ingress/receive paths of sockets. Perhaps the confusion stems from the way raw sockets work. Since they can see "outgoing traffic" as in traffic created by a process, but from the perspective of that raw socket both remote -> host and host -> remote packets appear on its ingress path. While egress would only be when a packet is written to the raw socket.

When looking at the kernel code, I can find the following call chains:

sk_filter_trim_cap (this actually calls the eBPF program)
|- __sk_receive_skb
| |- dccp_v4_rcv
|  \-dccp_v6_rcv
|- tcp_filter
|  |- tcp_v4_rcv
|  \- tcp_v6_rcv
|- udp_queue_rcv_one_skb
|- udpv6_queue_rcv_one_skb
|- rose_state3_machine
\- sk_filter
  |- l2cap_sock_recv_cb
  |- l2cap_sock_filter
  |- caif_queue_rcv_skb
  |- sock_queue_rcv_skb_reason
  |- dccp_v6_do_rcv
  |- iucv_process_message
  |- afiucv_hs_callback_rx
  |- netlink_unicast
  |- do_one_broadcast
  |- netlink_dump
  |- sctp_rcv
  \- unix_dgram_sendmsg

As you can see from the names most of these are _rcv (receive) functions. And in the exceptions like unix_dgram_sendmsg or do_one_broadcast, where the filtering does happen in the send path, the receiving socket is known and the eBPF filter from the receiving socket is used.

Please let me know if I missed anything

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants