|
1 | 1 | # Retis |
2 | 2 |
|
3 | | -Tracing packets in the [Linux](https://kernel.org) networking stack, using |
4 | | -[eBPF](https://ebpf.io) and interfacing with control and data paths such as |
5 | | -[OvS](https://www.openvswitch.org) or [Netfilter](https://netfilter.org). |
| 3 | +Tracing (filtered) packets in the [Linux](https://kernel.org) networking stack, |
| 4 | +using [eBPF](https://ebpf.io) probes and interfacing with control and data paths |
| 5 | +such as [OvS](https://www.openvswitch.org) or [Netfilter](https://netfilter.org). |
6 | 6 |
|
7 | 7 | Visit the [online documentation](https://retis.readthedocs.io) for more |
8 | | -details. |
9 | | - |
| 8 | +details, or run `retis --help` and `retis <command> --help`. |
10 | 9 |
|
11 | 10 |  |
12 | 11 |
|
13 | | -## Quick start |
14 | | -An overview and some examples can be found in the |
15 | | -[Documentation](https://retis.readthedocs.io), but note the `--help` flag |
16 | | -should document most of what Retis can do. |
17 | | - |
18 | | -``` |
19 | | -$ retis --help |
20 | | -... |
21 | | -$ retis <command> --help |
22 | | -... |
23 | | -``` |
| 12 | +## Installation |
24 | 13 |
|
25 | | -## Examples |
| 14 | +Retis can be used as a container image, installed on supported distributions or |
| 15 | +built from sources. All details on the [official |
| 16 | +documentation](https://retis.readthedocs.io/en/stable/install/). |
26 | 17 |
|
27 | | -### Drop monitoring |
28 | | -Listing packets being dropped by the kernel with an associated stack trace and drop reason |
29 | | -``` |
30 | | -$ retis -p dropmon collect |
31 | | -4 probe(s) loaded |
32 | | -
|
33 | | -3392678938917 [nc] 2311 [tp] skb:kfree_skb drop (NO_SOCKET) |
34 | | - bpf_prog_3a0ef5414c2f6fca_sd_devices+0xa0ad |
35 | | - bpf_prog_3a0ef5414c2f6fca_sd_devices+0xa0ad |
36 | | - bpf_trace_run3+0x52 |
37 | | - kfree_skb_reason+0x8f |
38 | | - tcp_v6_rcv+0x77 |
39 | | - ip6_protocol_deliver_rcu+0x6b |
40 | | - ip6_input_finish+0x43 |
41 | | - __netif_receive_skb_one_core+0x62 |
42 | | - process_backlog+0x85 |
43 | | - __napi_poll+0x28 |
44 | | - net_rx_action+0x2a4 |
45 | | - __do_softirq+0xd1 |
46 | | - do_softirq.part.0+0x5f |
47 | | - __local_bh_enable_ip+0x68 |
48 | | - __dev_queue_xmit+0x293 |
49 | | - ip6_finish_output2+0x2a3 |
50 | | - ip6_finish_output+0x160 |
51 | | - ip6_xmit+0x2c0 |
52 | | - inet6_csk_xmit+0xe9 |
53 | | - __tcp_transmit_skb+0x534 |
54 | | - tcp_connect+0xaf6 |
55 | | - tcp_v6_connect+0x515 |
56 | | - __inet_stream_connect+0x103 |
57 | | - inet_stream_connect+0x3a |
58 | | - __sys_connect+0xa8 |
59 | | - __x64_sys_connect+0x18 |
60 | | - do_syscall_64+0x5d |
61 | | - entry_SYSCALL_64_after_hwframe+0x72 |
62 | | - if 1 (lo) rxif 1 ::1.60634 > ::1.80 ttl 64 label 0x9c404 len 40 proto TCP (6) flags [S] seq 3918324244 win 65476 |
63 | | -... |
64 | | -``` |
| 18 | +## Use cases |
65 | 19 |
|
66 | | -### Monitoring packets dropped by netfilter |
67 | | -The exact nft rule can be retrieved using `nft -a list table ...`. |
| 20 | +Retis aims at providing better visibility on complex single-host topologies and |
| 21 | +linking useful context. It it designed to be modular in terms of what kind of |
| 22 | +data is retrieved and where it is retrieved from. Retis can be used for |
| 23 | +debugging networking issues, exploring the Linux networking stack or for testing |
| 24 | +features (eg. in a CI script). |
68 | 25 |
|
69 | | -``` |
70 | | -$ retis -p nft-dropmon collect --allow-system-changes |
71 | | -4 probe(s) loaded |
72 | | -
|
73 | | -3443313082998 [swapper/0] 0 [k] __nft_trace_packet |
74 | | - __nft_trace_packet+0x1 |
75 | | - nft_do_chain+0x3ef |
76 | | - nft_do_chain_inet+0x54 |
77 | | - nf_hook_slow+0x42 |
78 | | - ip_local_deliver+0xd0 |
79 | | - ip_sublist_rcv_finish+0x7e |
80 | | - ip_sublist_rcv+0x186 |
81 | | - ip_list_rcv+0x13d |
82 | | - __netif_receive_skb_list_core+0x29d |
83 | | - netif_receive_skb_list_internal+0x1d1 |
84 | | - napi_complete_done+0x72 |
85 | | - virtnet_poll+0x3ce |
86 | | - __napi_poll+0x28 |
87 | | - net_rx_action+0x2a4 |
88 | | - __do_softirq+0xd1 |
89 | | - __irq_exit_rcu+0xbe |
90 | | - common_interrupt+0x86 |
91 | | - asm_common_interrupt+0x26 |
92 | | - pv_native_safe_halt+0xf |
93 | | - default_idle+0x9 |
94 | | - default_idle_call+0x2c |
95 | | - do_idle+0x226 |
96 | | - cpu_startup_entry+0x1d |
97 | | - __pfx_kernel_init+0x0 |
98 | | - arch_call_rest_init+0xe |
99 | | - start_kernel+0x71e |
100 | | - x86_64_start_reservations+0x18 |
101 | | - x86_64_start_kernel+0x96 |
102 | | - __pfx_verify_cpu+0x0 |
103 | | - if 2 (eth0) rxif 2 172.16.42.1.52294 > 172.16.42.2.8080 ttl 64 tos 0x0 id 37968 off 0 [DF] len 60 proto TCP (6) flags [S] seq 1971640626 win 64240 |
104 | | - table firewalld (1) chain filter_IN_FedoraServer (202) handle 215 drop |
105 | | -... |
106 | | -$ nft -a list table inet firewalld |
107 | | -... |
108 | | - chain filter_IN_FedoraServer { # handle 202 |
109 | | -... |
110 | | - jump filter_INPUT_POLICIES_post # handle 214 |
111 | | - meta l4proto { icmp, ipv6-icmp } accept # handle 273 |
112 | | - reject with icmpx admin-prohibited # handle 215 <- This one |
113 | | - } |
114 | | -... |
115 | | -``` |
| 26 | +A few key points: |
116 | 27 |
|
117 | | -## Installation |
| 28 | +- Operates on "skb-enabled" functions and tracepoints. |
| 29 | +- Offers filtering and tracking (the same packet can be seen multiple times, |
| 30 | + modified, etc) capabilities. |
| 31 | +- Can retrieve more than the packet itself: additional metadata and contextual |
| 32 | + information. |
| 33 | +- Does not require compilation on the target. |
| 34 | +- Has post-processing abilities (eg. reconstructing a packet journey). |
| 35 | +- Tries to have sane defaults. |
118 | 36 |
|
119 | | -Retis can be installed from [COPR](https://copr.fedorainfracloud.org/coprs/g/retis/retis/) |
120 | | -for rpm-compatible distributions, from a container image or from sources. |
| 37 | +Collecting packet events going in and out network devices (similarly to |
| 38 | +well-known `AF_PACKET` existing utilities) can be as simple as: |
121 | 39 |
|
122 | | -### COPR |
| 40 | +``` |
| 41 | +$ retis collect -p net:netif_receive_skb -p net:net_dev_start_xmit |
| 42 | +Collector(s) started: nft, skb, ct, skb-tracking, skb-drop |
| 43 | +7 probe(s) loaded |
123 | 44 |
|
124 | | -RPM packages for Fedora (currently supported releases including Rawhide), RHEL (>= |
125 | | -8) and EPEL (>= 8) are available. |
| 45 | +6034438235097 (9) [ping] 22026 [tp] net:net_dev_start_xmit #57d008c23d9ffff93bc8e6a6580 (skb ffff93bc8fe2f700) |
| 46 | + if 4 (wlp82s0) [redacted] > 2606:4700:4700::1111 ttl 64 label 0x87f1c len 64 proto ICMPv6 (58) type 128 code 0 |
126 | 47 |
|
127 | | -``` |
128 | | -$ dnf -y copr enable @retis/retis |
129 | | -$ dnf -y install retis |
130 | | -$ retis --help |
| 48 | +6034449727598 (5) [irq/185-iwlwifi] 1359 [tp] net:netif_receive_skb #57d013b806effff93bc8b645180 (skb ffff93bc81f0d300) |
| 49 | + if 4 (wlp82s0) 2606:4700:4700::1111 > [redacted] ttl 54 label 0x9f52e len 64 proto ICMPv6 (58) type 129 code 0 |
131 | 50 | ``` |
132 | 51 |
|
133 | | -Or on older distributions, |
| 52 | +The output is described in the [official |
| 53 | +documentation](https://retis.readthedocs.io/en/stable/). The above example is |
| 54 | +similar to running the [ifdump](https://retis.readthedocs.io/en/stable/profiles/#ifdump) |
| 55 | +profile (`retis -p ifdump c`). |
| 56 | + |
| 57 | +More advanced collections can be performed by providing more probes and by |
| 58 | +adding filtering rules. For example one can use the [generic |
| 59 | +profile](retis/profiles/generic.yaml) which defines a bigger set of probes. |
134 | 60 |
|
135 | 61 | ``` |
136 | | -$ yum -y copr enable @retis/retis |
137 | | -$ yum -y install retis |
138 | | -$ retis --help |
139 | | -``` |
| 62 | +$ retis -p generic collect -f 'udp port 53 and host 2606:4700:4700::1111' |
| 63 | +L2+L3 packet filter(s) loaded |
| 64 | +29 probe(s) loaded |
140 | 65 |
|
141 | | -### Container image |
| 66 | +6464781565852 (10) [isc-net-0000] 22818/22819 [k] ip6_output #5e133023f9cffff93bc85f28a00 (skb ffff93bc8148b000) |
| 67 | + [redacted].60578 > 2606:4700:4700::1111.53 ttl 64 label 0x116de len 59 proto UDP (17) len 51 |
142 | 68 |
|
143 | | -The preferred method to run Retis in a container is by using the provided |
144 | | -[retis_in_container.sh](tools/retis_in_container.sh) script, |
| 69 | +6464781577262 (10) [isc-net-0000] 22818/22819 [tp] net:net_dev_queue #5e133023f9cffff93bc85f28a00 (skb ffff93bc8148b000) |
| 70 | + if 4 (wlp82s0) [redacted].60578 > 2606:4700:4700::1111.53 ttl 64 label 0x116de len 59 proto UDP (17) len 51 |
145 | 71 |
|
146 | | -``` |
147 | | -$ curl -O https://raw.githubusercontent.com/retis-org/retis/main/tools/retis_in_container.sh |
148 | | -$ chmod +x retis_in_container.sh |
149 | | -$ ./retis_in_container.sh --help |
150 | | -``` |
| 72 | +6464781579859 (10) [isc-net-0000] 22818/22819 [tp] net:net_dev_start_xmit #5e133023f9cffff93bc85f28a00 (skb ffff93bc8148b000) |
| 73 | + if 4 (wlp82s0) [redacted].60578 > 2606:4700:4700::1111.53 ttl 64 label 0x116de len 59 proto UDP (17) len 51 |
151 | 74 |
|
152 | | -### From sources |
153 | | -For details on how to build retis, visit the |
154 | | -[documentation](https://retis.readthedocs.io/en/stable/install/). |
| 75 | +6464794631087 (11) [irq/191-iwlwifi] 1365 [tp] net:napi_gro_receive_entry #5e133c99bafffff93bc89dd4000 (skb ffff93bfd77f9f00) |
| 76 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].60578 ttl 54 label 0xfacb2 len 79 proto UDP (17) len 71 |
155 | 77 |
|
156 | | -## Limitations |
| 78 | +6464794636532 (11) [irq/191-iwlwifi] 1365 [k] udp6_gro_receive #5e133c99bafffff93bc89dd4000 (skb ffff93bfd77f9f00) |
| 79 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].60578 ttl 54 label 0xfacb2 len 79 proto UDP (17) len 71 |
157 | 80 |
|
158 | | -Known and current limitations: |
| 81 | +6464794638402 (11) [irq/191-iwlwifi] 1365 [k] udp_gro_receive #5e133c99bafffff93bc89dd4000 (skb ffff93bfd77f9f00) |
| 82 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].60578 ttl 54 label 0xfacb2 len 79 proto UDP (17) len 71 |
159 | 83 |
|
160 | | -- By default Retis does not modify the system (e.g. load kernel modules, change |
161 | | - the configuration, add a firewalling rule). This is done on purpose but might |
162 | | - mean some prerequisites will be missing if not added manually. The only |
163 | | - example for now is the `nft` module that requires a specific nft rule to be |
164 | | - inserted. If that rule is not there, no nft event will be reported. To allow |
165 | | - Retis to modify the system, use the `--allow-system-changes` option when |
166 | | - running the `collect` command. See `retis collect --help` for further details |
167 | | - about changes applied to the system. |
| 84 | +6464794640624 (11) [irq/191-iwlwifi] 1365 [tp] net:netif_receive_skb #5e133c99bafffff93bc89dd4000 (skb ffff93bfd77f9f00) |
| 85 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].60578 ttl 54 label 0xfacb2 len 79 proto UDP (17) len 71 |
168 | 86 |
|
169 | | -- Retis operates mainly on `struct sk_buff` objects meaning a good part of |
170 | | - locally generated traffic can't be traced at the moment. E.g. locally |
171 | | - generated traffic from a container can be traced when it exits the container. |
| 87 | +6464794657429 (11) [irq/191-iwlwifi] 1365 [k] udpv6_rcv #5e133c99bafffff93bc89dd4000 (skb ffff93bfd77f9f00) |
| 88 | + if 4 (wlp82s0) rxif 4 2606:4700:4700::1111.53 > [redacted].60578 ttl 54 label 0xfacb2 len 79 proto UDP (17) len 71 |
| 89 | +``` |
172 | 90 |
|
173 | | -- Profiles combination might fail if flags are used multiple times or if some |
174 | | - arguments are incompatible. Use with care. |
| 91 | +When storing events for later post-processing, the packets' journeys can be |
| 92 | +reconstructed: |
175 | 93 |
|
176 | | -Additional notes (not strictly limitations): |
| 94 | +``` |
| 95 | +$ retis -p generic collect -f 'udp port 53 and host 2606:4700:4700::1111' -o \ |
| 96 | + --cmd 'dig redhat.com @2606:4700:4700::1111' |
| 97 | +$ retis sort |
| 98 | +6946866196800 (11) [isc-net-0000] 23898/23899 [k] ip6_output #651717df140ffff93bc89dd7c00 (skb ffff93bc8c491500) n 0 |
| 99 | + [redacted].54205 > 2606:4700:4700::1111.53 ttl 64 label 0x86973 len 59 proto UDP (17) len 51 |
| 100 | + ↳ 6946866208851 (11) [isc-net-0000] 23898/23899 [tp] net:net_dev_queue #651717df140ffff93bc89dd7c00 (skb ffff93bc8c491500) n 1 |
| 101 | + if 4 (wlp82s0) [redacted].54205 > 2606:4700:4700::1111.53 ttl 64 label 0x86973 len 59 proto UDP (17) len 51 |
| 102 | + ↳ 6946866211760 (11) [isc-net-0000] 23898/23899 [tp] net:net_dev_start_xmit #651717df140ffff93bc89dd7c00 (skb ffff93bc8c491500) n 2 |
| 103 | + if 4 (wlp82s0) [redacted].54205 > 2606:4700:4700::1111.53 ttl 64 label 0x86973 len 59 proto UDP (17) len 51 |
| 104 | +
|
| 105 | +6946876837639 (7) [irq/187-iwlwifi] 1361 [tp] net:napi_gro_receive_entry #65172204f07ffff93bc93bf6580 (skb ffff93c01ebd8f00) n 0 |
| 106 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].54205 ttl 54 label 0x7ff08 len 79 proto UDP (17) len 71 |
| 107 | + ↳ 6946876842090 (7) [irq/187-iwlwifi] 1361 [k] udp6_gro_receive #65172204f07ffff93bc93bf6580 (skb ffff93c01ebd8f00) n 1 |
| 108 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].54205 ttl 54 label 0x7ff08 len 79 proto UDP (17) len 71 |
| 109 | + ↳ 6946876843587 (7) [irq/187-iwlwifi] 1361 [k] udp_gro_receive #65172204f07ffff93bc93bf6580 (skb ffff93c01ebd8f00) n 2 |
| 110 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].54205 ttl 54 label 0x7ff08 len 79 proto UDP (17) len 71 |
| 111 | + ↳ 6946876845210 (7) [irq/187-iwlwifi] 1361 [tp] net:netif_receive_skb #65172204f07ffff93bc93bf6580 (skb ffff93c01ebd8f00) n 3 |
| 112 | + if 4 (wlp82s0) 2606:4700:4700::1111.53 > [redacted].54205 ttl 54 label 0x7ff08 len 79 proto UDP (17) len 71 |
| 113 | + ↳ 6946876855603 (7) [irq/187-iwlwifi] 1361 [k] udpv6_rcv #65172204f07ffff93bc93bf6580 (skb ffff93c01ebd8f00) n 4 |
| 114 | + if 4 (wlp82s0) rxif 4 2606:4700:4700::1111.53 > [redacted].54205 ttl 54 label 0x7ff08 len 79 proto UDP (17) len 71 |
| 115 | +``` |
177 | 116 |
|
178 | | -- Filtering & tracking packets being modified can only work if the packet is at |
179 | | - least seen once in a form where it can be matched against the filter. E.g. |
180 | | - tracking SNATed packets only in `skb:consume_skb` with a filter on the |
181 | | - original address won't generate any event. |
| 117 | +Retis offers many more features including retrieving [conntrack |
| 118 | +information](https://retis.readthedocs.io/en/stable/modules/ct/), [advanced |
| 119 | +filtering](https://retis.readthedocs.io/en/stable/filtering/), [monitoring |
| 120 | +dropped packets](https://retis.readthedocs.io/en/stable/profiles/#dropmon) and |
| 121 | +[dropped packets from Netfilter](https://retis.readthedocs.io/en/stable/profiles/#nft-dropmon), |
| 122 | +generating `pcap` files from the collected packets, allowing [writing |
| 123 | +post-processing scripts in Python](https://retis.readthedocs.io/en/stable/python/) |
| 124 | +and more. |
182 | 125 |
|
183 | | -- As explained in the [filtering section](https://retis.readthedocs.io/en/stable/#filtering) |
184 | | - filters are eventually translated to eBPF instructions. Currently, the maximum |
185 | | - size of an eBPF filter is 4096 instructions. |
| 126 | +## Contributing |
186 | 127 |
|
187 | | -- Some fields present in the packet might not be reported when probes are early |
188 | | - in the stack, while being shown in later ones. This is because Retis probes |
189 | | - rely on the networking stack knowledge of the packet and if some parts weren't |
190 | | - processed yet they can't be reported. E.g. TCP ports won't be reported from |
191 | | - `kprobe:ip_rcv`. |
| 128 | +Retis is under [GPL v2](retis/LICENSE) and welcomes contributions. See our |
| 129 | +[contributing guide](https://retis.readthedocs.io/en/stable/CONTRIBUTING/) for |
| 130 | +more details. |
0 commit comments