I'm attempting to make a program which uses raw sockets run correctly as non-root with Linux capabilities. The program is as follows:
#include <netinet/ip.h>
int main()
{
int sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if(sd < 0)
{
perror("socket() error");
return 1;
}
return 0;
}
If I compile it and run it as non-root, I get an error, as expected:
[user@localhost ~]$ make socket
cc socket.c -o socket
[user@localhost ~]$ ./socket
socket() error: Operation not permitted
If I add the cap_net_raw
capability, as an effective and permitted capability, it works.
[user@localhost ~]$ sudo setcap cap_net_raw+ep socket
[sudo] password for user:
[user@localhost ~]$ ./socket
[user@localhost ~]$
Now, I want to use pam_cap.so
to make it so that only a particular user can run this program with cap_net_raw
, instead of everyone. My /etc/security/capability.conf
is:
cap_net_raw user
My /etc/pam.d/login
is (note that I also tried /etc/pam.d/sshd
but that did not seem to work either):
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth substack system-auth
auth include postlogin
#Added this line to use pam_cap
auth required pam_cap.so
account required pam_nologin.so
account include system-auth
password include system-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include system-auth
session include postlogin
-session optional pam_ck_connector.so
I had an ssh session, I logged out and back in after that and executed the following commands:
[user@localhost ~]$ sudo setcap cap_net_raw+p socket
[sudo] password for user:
[user@localhost ~]$ getcap socket
socket = cap_net_raw+p
[user@localhost ~]$ ./socket
socket() error: Operation not permitted
[user@localhost ~]$
My question is: Why was I not able to execute the 'socket' program with cap_net_raw
? I thought that when I logged in, my user would obtain it as a permitted capability, and it would allow 'user' to run 'socket' with the cap_net_raw
.
This is what I'm running on:
[user@localhost ~]$ uname -a
Linux localhost.localdomain 3.10.0-123.el7.x86_64 #1 SMP Mon Jun 30 12:09:22 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)
I figured out that I had the wrong capabilities on the file. In order for the process to be able to obtain effective capabilities from the pam_cap module, the file needs to be configured with the "inherited" capability as well. So, setting caps on the file should be:
sudo setcap cap_net_raw+ip socket
However, I still could only get the program to work successfully from a normal tty login, and not an ssh login.