2

I have a situation where I need a non-root user to be allowed to create TUN/TAP interfaces. I understand that this requires the CAP_NET_ADMIN capability.

There have been other questions about this, but the answers seem to focus on granting the CAP_NET_ADMIN capability to a file/program, not to the user. In my case, I need the capability to be assigned to the user, so they can use whatever tool they see fit to create the interfaces (i.e. not restricted to a specific file/program used to create them).

Is this possible in Linux? Specifically, I'm using Ubuntu 22.04.

For context, the reason for this is that I'm creating the TUN interface through a custom program that makes the system calls, and I need this to work while debugging it. Since it builds a new binary every time I run the debugger, switching to root and assigning the capability to the binary and then switching back to debug the binary is not feasible.

2
  • 2
    As a general rule, the kernel does not keep a list of users at all, so you cannot pin any properties to a user. The check whether you can do something by a user is always done by looking at the something, and looking at whether that has set particular privileges for the UID of the user trying to do it. Commented Apr 24, 2023 at 14:40
  • 1
    In short. To create: no. To use: yes (because such device has a uid/gid user setting).
    – A.B
    Commented Apr 24, 2023 at 16:46

1 Answer 1

0

You can use an ambient capability set via some file capabilities on a wrapper (wrapper.c):

#include <stdlib.h>
#include <stdio.h>
#include <sys/capability.h>
#include <unistd.h>

#define SHELL "/bin/bash"

char *const args[] = { SHELL, NULL };

int main(int argc, char **argv) {
  cap_iab_t iab = cap_iab_get_proc();
  if (cap_iab_set_vector(iab, CAP_IAB_AMB, CAP_SYS_ADMIN, CAP_SET)) {
    perror("not able to raise bit");
    exit(1);
  }
  if (cap_iab_set_proc(iab)) {
    perror("unable to set iab bit");
    exit(1);
  }
  execv(SHELL, args);
  perror("execv failed");
  exit(1);
}

If $USERWANTED is the username of the user you want to be able to do this:

$ gcc -o wrapper wrapper.c -lcap
$ sudo chown $USERWANTED wrapper
$ sudo chmod go-wx wrapper
$ sudo setcap "cap_sys_admin,cap_setpcap=pe" wrapper

Only $USERWANTED can execute this binary, because of the chmod line. When they do, the wrapper program adds the Ambient capability and runs a shell. It and its children have the CAP_SYS_ADMIN capability:

$ sudo -u $USERWANTED
$ exec ./wrapper
$ capsh --print|grep Current
Current: cap_sys_admin=eip
Current IAB: ^cap_sys_admin

You may still find it difficult to debug your program. This is because programs that run with capabilities can only be debugged by programs that also have those capabilities.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .