-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Add RestrictNetworkInterfaces= #18385
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 RestrictNetworkInterfaces= #18385
Conversation
a01e2c4 to
3a13693
Compare
3a13693 to
a9c79a8
Compare
|
This pull request introduces 1 alert when merging a9c79a8 into fa98c99 - view on LGTM.com new alerts:
|
a9c79a8 to
c2d7499
Compare
|
This pull request introduces 1 alert when merging c2d7499 into 5735ab0 - view on LGTM.com new alerts:
|
poettering
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good! A few comments
src/core/restrict-ifaces.c
Outdated
| dummy = 0; | ||
|
|
||
| SET_FOREACH(iface, restrict_network_interfaces) { | ||
| ifindex = if_nametoindex(iface); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use resolve_interface() from socket-netlink.c: it also supports resolving new-style "altnames" for interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean resolve_ifname()? resolve_interface() tries to parse the interface name to an integer before using netlink, I think it's not correct for this use case as an interface with an integer name can have a if_index different to the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, in networkd and elsewhere we generally explicitly check that people cannot name ifaces numerically, so that no ambiguity can happen, and so that ifindex and ifname can be used unambigiously interchangable.
For transient services it might make sense to pinpoint ifaces by ifindex, since they are generated programmatically on the fly. hence i see no eason why not to accept ifindexes here, if people want to specify them
c2d7499 to
eee13b7
Compare
|
This pull request introduces 1 alert when merging eee13b7 into fa02711 - view on LGTM.com new alerts:
|
eee13b7 to
56e90a5
Compare
|
This pull request introduces 1 alert when merging 56e90a5 into 584e9ba - view on LGTM.com new alerts:
|
56e90a5 to
ca463a4
Compare
|
This pull request introduces 1 alert when merging ca463a4 into 8b2620e - view on LGTM.com new alerts:
|
ca463a4 to
c146e5b
Compare
|
This pull request introduces 1 alert when merging c146e5b into 499c851 - view on LGTM.com new alerts:
|
|
Any chance you can rebase now that #17655 has been merged? Should be an easy merge then |
bb1568c to
05d4ac0
Compare
90d7a5f to
89028c4
Compare
mauriciovasquezbernal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I handled the comments.
src/core/restrict-ifaces.c
Outdated
| _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; | ||
| char *iface; | ||
| uint8_t dummy = 0; | ||
| int ifindex; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved dummy and ifindex, others are needed outside.
| log_syntax(unit, LOG_WARNING, filename, line, r, | ||
| "Trailing garbage in %s, ignoring: %s", lvalue, rvalue); | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got it. Thanks for the clarification.
poettering
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks really good, we are close!
| } | ||
|
|
||
| SEC("cgroup_skb/egress") | ||
| int sd_restrictif_e(struct __sk_buff *sk) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just wondering, souldn't the param be const?
src/core/dbus-cgroup.c
Outdated
|
|
||
| if (!c->restrict_network_interfaces) { | ||
| c->restrict_network_interfaces_is_allow_list = is_allow_list; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no {} around single line if blocks
src/core/dbus-cgroup.c
Outdated
| return 1; | ||
| } | ||
|
|
||
| if (!c->restrict_network_interfaces) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd probably check for emptiness rathre than non-NULL here. i.e. if (set_isempty(c->restrict_network_interfaces). note that a NULL set is considered empty, hence such a check is mostly equivalent, but kinda underlines that the set is allocated lazily here
| #include <linux/bpf.h> | ||
| #include <bpf/bpf_helpers.h> | ||
|
|
||
| const volatile __u8 is_allow_list = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does this actually work? i.e. how does the consuming code get access to this, and in particular write access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generated skeleton includes a structure with those variables, they are filled by the user space part (obj->rodata->is_allow_list = is_allow_list; in restrict-ifaces.c) before loading the BPF object. When the object is loaded, libbpf creates an eBPF map that backes up those variables, libbpf copies the value of those to the map and freezes it to avoid further modifications in the case the variable is const.
|
the ifname validity check is still missing... |
89028c4 to
b65230a
Compare
The code is composed by two BPF_PROG_TYPE_CGROUP_SKB programs that
are loaded in the cgroup inet ingress and egress hooks
(BPF_CGROUP_INET_{INGRESS|EGRESS}).
The decision to let a packet pass or not is based on a map that contains
the indexes of the interfaces.
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
This commit introduces all the logic to load and attach the BPF programs to restrict network interfaces when a unit specifying it is loaded. Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
b65230a to
294f3ef
Compare
🙈 I added it to both, load-fragment.c and dbus-cgroup.c. |
|
Excellent! Found one indenting nit, but doesn#t matter. Let's get this baby landed. |
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
294f3ef to
4368984
Compare
|
FYI I refactored the meson build for this in #20429 to try and fix cross compilation, probably good to try and test everything still works there. |
Add
RestrictNetworkInterfaces=option to limit the network interfaces a program in a unit can use.This PR uses the libbpf support introduced in #17655. The feature is implemented with
BPF_PROG_TYPE_CGROUP_SKBprograms attached to theBPF_CGROUP_INET_{INGRESS|EGRESS}hooks.There are still some TODOs but I wanted to open the PR to start the discussion now.
TODO:
RestrictNetworkIntferfacesboth programs should useBPF_F_ALLOW_MULTIbut it's not used by bpf-firewall: acf7f25. Related bpf: pid1: Pin reference to BPF programs for post-coldplug #17495./cc @iaguis