freeradius server can act as dhcp server and it can work as non-root user. But when response to client, it try to insert arp table entry and (regardless of CAP_NET_ADMIN capability) got "permission denied" I think that would be desirable that some capability allow to insert and delete arp entry.
I am not able to reproduce your issue. I assigned cap_net_admin capability to ip(8) and tried adding an arp entry as a non-root user and it works. (as root did this) # setcap cap_net_admin+ep /usr/sbin/ip (as non-root user did this) $ ip neigh add 1.1.1.1 lladdr 0:1:2:3:4:5 dev eno2 ip neigh show 1.1.1.1 dev eno2 lladdr 00:01:02:03:04:05 PERMANENT $ ip neigh del 1.1.1.1 lladdr 0:1:2:3:4:5 dev eno2 $ On the other hand, without cap_net_admin and running 'ip neigh' command fails like below: (as root user) # setcap -r /usr/sbin/ip (as non-root user) $ ip neigh add 1.1.1.1 lladdr 0:1:2:3:4:5 dev eno2 RTNETLINK answers: Operation not permitted
Well, I tried to use freeradius as non root user. and 1. sudo setcap cap_net_admin,cap_net_bind_service,CAP_NET_RAW=eip /usr/sbin/freeradius 2. I when I set "interfaces = somethin " in config file I got in logs: "Failed adding arp entry: Failed to add entry in ARP cache: Operation not permitted" 3. Greping sources I suppose it is from if (ioctl(fd, SIOCSARP, &req) < 0) { fr_strerror_printf("Failed to add entry in ARP cache: %s (%d)", fr_syserror(errno), errno); return -1; }
BTW, I checked the kernel code (4.13+) and everything in SIOCSARP code path seems fine. Also, it works for me on my test system. This is my configuration: $ radiusd -v radiusd: FreeRADIUS Version 3.0.4, for host x86_64-redhat-linux-gnu, built on Jun 27 2017 at 21:21:01 $ uname -r 4.11.0-rc6.master.20170413.ol7.x86_64 $ id uid=1002(gmg) gid=1002(gmg) groups=1002(gmg),95(radiusd) $ filecap /usr/sbin/radiusd file capabilities /usr/sbin/radiusd net_bind_service, net_admin, net_raw (Note: I assigned the capabilities as root as shown below #setcap cap_net_admin,cap_net_bind_service,cap_net_raw=ep /usr/sbin/radiusd ) I then started radiusd as below ------------------8<------------------------8<------- $ /usr/sbin/radiusd -X ... <output snipped> listen { type = "dhcp" ipaddr = 255.255.255.255 port = 67 src_ipaddr = 1.1.1.2 } Listening on auth address 127.0.0.1 port 18120 as server inner-tunnel Listening on dhcp interface eno2 address 255.255.255.255 port 67 as server dhcp Ready to process requests <I see DHCP* messages and an offer being made to my other test system> ------------------8<------------------------8<------- $ arp -an ? (192.0.2.100) at 02:08:20:e2:2f:d0 [ether] on eno2 So, 192.0.2.100 was leased to my other test system which has a MAC address of 02:08:20:e2:2f:d0. The fact that I can see this entry means that 'radiusd' daemon was able to successfully add the MAC address to the arp table.
Just for sure: do you have set "interface = eno2" in config file? If "interface" option is not set, then freeradius prints warning message: " Warning: No "interface" setting is defined. Only unicast DHCP will work" and seems to working. But if you set "interface" it does not work with message I posted earlier.
Yes, I have 'interface = eno2' enabled in /etc/raddb/sites-available/dhcp, and I have a symbolic link to that file at /etc/raddb/sites-enabled/dhcp.
Something strange :( it does not work for me. BTW. Why do you set "ipaddr = 255.255.255.255"?
Argh. I have done some more testing. It looks like debian's freeradius service is run as root (and eventually drops is privilleges later). In this case ARP cache cannot be updated. When I try to add "User=freerad" to service definition it starts to work. So my ticket can be treat as invalid :(