如何使用 PAM 功能模块将功能授予特定用户和可执行文件?
How do I use the PAM capabilities module to grant capabilities to a particular user and executable?
我正在尝试制作一个使用原始套接字 运行 的程序作为具有 Linux 功能的非根用户。程序如下:
#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;
}
如果我编译它并 运行 它作为非 root,我会得到一个错误,正如预期的那样:
[user@localhost ~]$ make socket
cc socket.c -o socket
[user@localhost ~]$ ./socket
socket() error: Operation not permitted
如果我添加 cap_net_raw
功能,作为有效且允许的功能,它会起作用。
[user@localhost ~]$ sudo setcap cap_net_raw+ep socket
[sudo] password for user:
[user@localhost ~]$ ./socket
[user@localhost ~]$
现在,我想使用 pam_cap.so
来实现只有特定用户才能 运行 使用 cap_net_raw
这个程序,而不是每个人。我的 /etc/security/capability.conf
是:
cap_net_raw user
我的 /etc/pam.d/login
是(请注意,我也尝试了 /etc/pam.d/sshd
但似乎也没有用):
#%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
我有一个 ssh 会话,之后我注销并重新登录并执行了以下命令:
[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 ~]$
我的问题是:为什么我无法使用 cap_net_raw
执行 'socket' 程序?我以为当我登录时,我的用户将获得它作为允许的功能,并且它将允许 'user' 到 运行 'socket' 与 cap_net_raw
.
这就是我 运行 的目标:
[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)
我发现我对文件的功能有误。为了让进程能够从pam_cap模块中获取有效的能力,该文件也需要配置"inherited"能力。所以,设置文件上限应该是:
sudo setcap cap_net_raw+ip socket
但是,我仍然只能通过正常的 tty 登录使程序成功运行,而不是 ssh 登录。
我在尝试使用 Google 跳转到 pam_cap.so
文档时遇到了这个问题。
使用 setcap
设置此二进制文件以便与 pam_cap.so
一起使用的方法是:
sudo setcap cap_net_raw=ie socket
也就是说,i
指示二进制文件将进程 Inheritable 能力标志提升为进程 Permitted p
能力,并且 legacy e
指示内核在调用程序时在进程的有效标志中提高其值。
如果您想使用 libcap
s cap_set_proc()
函数从程序内部引发有效标志,则可以跳过 e
部分。类似于:
cap_t c = cap_get_proc();
cap_fill(c, CAP_EFFECTIVE, CAP_PERMITTED);
cap_set_proc(c);
cap_free(c);
FWIW 我在现代内核中 recently written an article on the various ways you can inherit capabilities。
我正在尝试制作一个使用原始套接字 运行 的程序作为具有 Linux 功能的非根用户。程序如下:
#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;
}
如果我编译它并 运行 它作为非 root,我会得到一个错误,正如预期的那样:
[user@localhost ~]$ make socket
cc socket.c -o socket
[user@localhost ~]$ ./socket
socket() error: Operation not permitted
如果我添加 cap_net_raw
功能,作为有效且允许的功能,它会起作用。
[user@localhost ~]$ sudo setcap cap_net_raw+ep socket
[sudo] password for user:
[user@localhost ~]$ ./socket
[user@localhost ~]$
现在,我想使用 pam_cap.so
来实现只有特定用户才能 运行 使用 cap_net_raw
这个程序,而不是每个人。我的 /etc/security/capability.conf
是:
cap_net_raw user
我的 /etc/pam.d/login
是(请注意,我也尝试了 /etc/pam.d/sshd
但似乎也没有用):
#%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
我有一个 ssh 会话,之后我注销并重新登录并执行了以下命令:
[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 ~]$
我的问题是:为什么我无法使用 cap_net_raw
执行 'socket' 程序?我以为当我登录时,我的用户将获得它作为允许的功能,并且它将允许 'user' 到 运行 'socket' 与 cap_net_raw
.
这就是我 运行 的目标:
[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)
我发现我对文件的功能有误。为了让进程能够从pam_cap模块中获取有效的能力,该文件也需要配置"inherited"能力。所以,设置文件上限应该是:
sudo setcap cap_net_raw+ip socket
但是,我仍然只能通过正常的 tty 登录使程序成功运行,而不是 ssh 登录。
我在尝试使用 Google 跳转到 pam_cap.so
文档时遇到了这个问题。
使用 setcap
设置此二进制文件以便与 pam_cap.so
一起使用的方法是:
sudo setcap cap_net_raw=ie socket
也就是说,i
指示二进制文件将进程 Inheritable 能力标志提升为进程 Permitted p
能力,并且 legacy e
指示内核在调用程序时在进程的有效标志中提高其值。
如果您想使用 libcap
s cap_set_proc()
函数从程序内部引发有效标志,则可以跳过 e
部分。类似于:
cap_t c = cap_get_proc();
cap_fill(c, CAP_EFFECTIVE, CAP_PERMITTED);
cap_set_proc(c);
cap_free(c);
FWIW 我在现代内核中 recently written an article on the various ways you can inherit capabilities。