Bug 187791 - CAP_NET_ADMIN (or other) should allow manipulate arp tables?
Summary: CAP_NET_ADMIN (or other) should allow manipulate arp tables?
Status: RESOLVED INVALID
Alias: None
Product: Networking
Classification: Unclassified
Component: Other (show other bugs)
Hardware: x86-64 Linux
: P1 enhancement
Assignee: Stephen Hemminger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-11-15 12:53 UTC by Kamil Jońca
Modified: 2017-08-03 23:19 UTC (History)
1 user (show)

See Also:
Kernel Version: Linux 4.4.0-1 (and newer?)
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Kamil Jońca 2016-11-15 12:53:16 UTC
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.
Comment 1 girish.moodalbail 2017-08-02 02:03:44 UTC
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
Comment 2 Kamil Jońca 2017-08-03 04:02:58 UTC
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;
	}
Comment 3 girish.moodalbail 2017-08-03 06:52:49 UTC
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.
Comment 4 Kamil Jońca 2017-08-03 21:59:50 UTC
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.
Comment 5 girish.moodalbail 2017-08-03 22:12:12 UTC
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.
Comment 6 Kamil Jońca 2017-08-03 22:54:02 UTC
Something strange :( it does not work for me.
BTW. Why do you set "ipaddr = 255.255.255.255"?
Comment 7 Kamil Jońca 2017-08-03 23:18:50 UTC
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  :(

Note You need to log in before you can comment on or make changes to this bug.