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

add conn entries for all tunnels and differentiate from non-tunnel conns #3916

Open
ekoyle opened this issue Sep 4, 2024 · 4 comments
Open

Comments

@ekoyle
Copy link

ekoyle commented Sep 4, 2024

Currently, many tunnel types do not create conn entries. I believe the root of this issue is #3915 and if that behavior is resolved, this issue would be mostly resolved. Currently, VXLAN and GENEVE tunnels get entries in the conn log (since they are UDP-based), but GRE and IP-in-IP do not. This can be especially confusing since the tunnel_parents for connections in these non-UDP tunnels have a uid, but no associated conn entry. I also am not seeing a simple way to differentiate conn entries that belong to tunnels from connections that have not been identified as tunnels (it may be useful to exclude tunnels from some calculations to avoid double-counting the traffic, for example).

I am proposing that we add a field to the conn log to allow filtering out sessions that contain other connections (maybe a boolean named is_tunnel or something similar?). I am also proposing that we track these sessions as a 3-tuple in #3915. I think this issue is a superset of #3378.

There are also some special cases that we might want to consider for tunnels:

For UDP based tunnels like VXLAN or GENEVE, I think it would be best to ignore the src/dst ports for session matching, as it is not actually part of the tunnel session but rather used like a flow-specific key to allow ECMP on flows within the tunnel. So, a GENEVE session could actually consist of host-a:*->host-b:6081 and host-b:*->host-a:6801, however I'm unsure of the best way to handle this in zeek. It won't make a difference in cases where these tunnels are used for mirroring purposes, but if bidirectional traffic exists there will be a separate tunnel for each direction (this may or may not be an issue, though - edit: could there be more bugs like #1991?).

GRE has a concept of a tunnel key to differentiate different sessions between two endpoints, however since zeek isn't really exposing the key I think it would be reasonable to ignore that special case for now (there would be no loss of functionality), although I suppose the 4-byte key could also be encoded into orig_p/resp_p somehow.

@J-Gras
Copy link
Contributor

J-Gras commented Sep 5, 2024

For UDP based tunnels like VXLAN or GENEVE, I think it would be best to ignore the src/dst ports for session matching, as it is not actually part of the tunnel session but rather used like a flow-specific key

For this we would need to keep load-balancing in mind: While the inner connections will be local to a single worker, the encapsulating tunnel might be seen and thus logged on multiple workers.

@awelzel
Copy link
Contributor

awelzel commented Sep 5, 2024

For UDP based tunnels like VXLAN or GENEVE, I think it would be best to ignore the src/dst ports for session matching,
but if bidirectional traffic exists there will be a separate tunnel for each direction

You implied this, but there's a difference between Zeek monitoring/observing a Geneve/VXLAN tunnel being used between two hosts (in which case you might not want to collapse src ports - it might not be a mirroring use-case) or Zeek receiving all monitored packets over VXLAN/Geneve and src ports being flow keys.

@rsmmr mentioned a config option for the latter a few times, maybe if we determine the destination IPs of the "Zeek system", observe tunneled traffic towards it and some option is enabled, only then collapse tunnel connections.

This is somewhat off-topic, but for mirroring only setups, I'm wondering if a packet source that just listens directly on a UDP port (recvmmsg() and SO_REUSEPORT for loadbalancing 🤞) could be an interesting experiment.

@ekoyle
Copy link
Author

ekoyle commented Sep 16, 2024

This is somewhat off-topic, but for mirroring only setups, I'm wondering if a packet source that just listens directly on a UDP port (recvmmsg() and SO_REUSEPORT for loadbalancing 🤞) could be an interesting experiment.

I like the idea. A UDP socket could even allow zeek to start without special privileges. Are you thinking that plus SO_ATTACH_REUSEPORT_EBPF or something to handle load balancing different half-flows to the same worker?

What about mirroring protocols that don't use UDP (erspan uses GRE, for example)?

@ekoyle
Copy link
Author

ekoyle commented Oct 9, 2024

@ckreibich mentioned that it would be useful to have pcaps for testing, a good place to start is the existing tunnel pcaps under zeek/testing/btest/Traces/tunnels/ . I'll try to make a few more with multiple tunnel headers as well.

A quick categorization for reference (I may have missed some):

  • ERSPAN (based on GRE)
    • gre-erspan3-dot1q.pcap
    • erspanII.pcap
    • erspanIII.pcap
  • GENEVE
    • geneve-47101.pcap
    • geneve-many-options.pcap
    • geneve.pcap
    • geneve-truncated.pcap
    • geneve-vxlan-dns-truncated.pcap
  • GRE
    • gre-aruba-amsdu.pcap
    • gre-aruba-ccmp.pcap
    • gre-aruba.pcap
    • gre-pptp.pcap
    • gre-over-udp-4754.pcap
    • gre-sample.pcap
    • gre-within-gre.pcap
  • GTP
    • gtp/gtp4_udp_2152_inside.pcap
    • gtp/gtp6_gtp_0x32.pcap
    • gtp/gtp7_ipv6.pcap
    • gtp/gtp8_teredo.pcap
  • IPIP
    • 4in6.pcap
    • 4in6.pcap
    • 6in4.pcap
    • 6in6in6.pcap
    • 6in6.pcap
    • 6in6-tunnel-change.pcap
  • VXLAN
    • vxlan-encapsulated-http.pcap
    • vxlan-encapsulated-igmp-v2.pcap
    • vxlan.pcap
  • other
    • mpls-6in6-6in6-4in6-invalid-version-4.pcap
    • mpls-6in6-6in6-invalid-version-6.pcap
    • ping6-in-ipv4.pcap
    • socks.pcap
    • teredo_bubble_with_payload.pcap
    • Teredo.pcap
    • teredo-udp-in-udp.pcap

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

3 participants