radvd-project / radvd

radvd | Official repository: https://github.com/radvd-project/radvd
https://radvd.litech.org/
Other
203 stars 107 forks source link

radvd should support Linux capabilities for more fine-grained permissions dropping. #167

Open robbat2 opened 2 years ago

robbat2 commented 2 years ago

Followup to #165 where the users want to start radvd as non-root, and still have it further drop capabilities.

audreylace commented 11 months ago

radvd can be even simpler and just ask for something else to create the raw socket and pass it in. No need for capabilities or root as far as opening an ICMP socket is concerned.

Example code - Takes a file descriptor as one of the inputs. https://github.com/audreylace/radvd-stinput/commit/da61e79b36d6da4725f0cb50ef6c174c89f803cc#diff-7ded337c5dd8d7af58cc6064e8e40eac13251fa6d2935effe2e1797023138b63

Example of how to use new parameter, this program would have the raw capabilities bit set on its program. This would bypass the need for radvd to run as root or drop capabilities. Ideally of course the path to radvd should be hard code but definitely out of scope.

Do note - we still would get complaints about not being able to write to proc file system. My thoughts are either turn that off in this situation or provide some sort of way to out source the action to an external program or script sort of like how dhclient can invoke an external script.

#include "../../includes.h"

int main(int argc, char** args) {

if (argc < 2) {
    fprintf(stderr, "expects at least one argument, path to radvd\r\n");
    fflush(stderr);
    return -1;
}

int sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);

char** radvd_args = malloc(sizeof(char**) * argc + 1);

for (int i = 0; i < argc - 1; i++) {
    radvd_args[i] = args[i + 1];
}

fflush(stdout);

char* fd_str = malloc(255 * sizeof(char));
radvd_args[argc - 1] = fd_str;
radvd_args[argc] = NULL;
sprintf(fd_str, "--fd=%d", sock);

execv(args[1], radvd_args);

fprintf(stderr, "failed to start program\r\n");
fflush(stderr);

return 1;
}
robbat2 commented 11 months ago
  1. Will this work on non-Linux systems?
  2. Does setup_allrouters_membership and other setsockopt calls all work as non-root? (I think some of them might need CAP_NET_ADMIN)