我通常会找到所有已作为问答发布的 Unix 相关问题的答案。然而,这个特殊的问题在过去的一个小时里让我很难过,所以我想我会在这个网站上问我的第一个问题。
我有一个运行 CentOS 5.11 的开发/登台服务器。locate以普通用户身份运行不会产生任何输出(甚至没有错误消息):
locate readdir
Run Code Online (Sandbox Code Playgroud)
但是,以超级用户身份运行命令会打印有效结果列表:
$ sudo locate readdir
/home/anthony/repos/php-src/TSRM/readdir.h
/home/anthony/repos/php-src/ext/standard/tests/dir/readdir_basic.phpt
... etc.
Run Code Online (Sandbox Code Playgroud)
strace通常可以帮助我调试任何此类问题并运行strace locate readdir显示:
stat64("/var/lib/mlocate/mlocate.db", 0xbff65398) = -1 EACCES (Permission denied)
access("/", R_OK|X_OK) = -1 EACCES (Permission denied)
exit_group(1) = ?
Run Code Online (Sandbox Code Playgroud)
我检查了locate二进制文件及其默认数据库的所有权和权限。如所预期的命令是setgid与slocate作为该组所有者而数据库具有适当的所有权和权限。
$ ls -l /usr/bin/locate
-rwx--s--x 1 root slocate 22280 Sep 3 2009 /usr/bin/locate
$ sudo ls -l /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 78395703 May 8 04:02 /var/lib/mlocate/mlocate.db
$ …Run Code Online (Sandbox Code Playgroud) sudo启动时被提升为 root,因为它的二进制文件已setuid启用。但是,当我赋予/bin/login确切的权限时sudo,并尝试从非 root 用户运行它时,出现错误:
No utmp entry. You must exec "login" from the lowest level "sh"
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,这个错误是什么意思?我的第二个是,为什么当我sudo login从同一个用户运行时它会起作用?除了使用asetuuid提升到root之外,还有什么sudo工作?我写了一个简单的dash脚本~/root来运行whoami和退出,但它返回我的非特权用户的用户名。
$ ls -l ./root /usr/bin/sudo
-rwsr-xr-x 1 root root 29 Jul 15 02:40 ./root
-rwsr-xr-x 1 root root 157760 Jan 10 2016 /usr/bin/sudo
$ ./root
unprivileged user
Run Code Online (Sandbox Code Playgroud)
所以我有三个问题:
login?login与sudo?whoami不起作用?我有一项开始使用 systemd 的服务。服务用户和组更改为非特权用户。
[Service]
...
User=regular_user
Group=regular_user
...
Run Code Online (Sandbox Code Playgroud)
在某些时候,服务需要启动另一个进程,该进程有望成为 root。另一个进程设置了它的 's' 位,它setuid()用来成为 root。
如果我启动它,这个过程就可以正常工作。然而,不知何故,当服务尝试启动它时,该setuid()函数返回一个错误:
不允许操作。
我已经看到了一些有关功能的选项,但我不知道是否需要使用这些选项来使setuid()功能在我的服务中正常工作。我尝试了一些东西,到目前为止没有任何帮助。
例如,我试过:
AmbientCapabilities=CAP_SETGID CAP_SETUID
SecureBits=keep-caps
Run Code Online (Sandbox Code Playgroud)
虽然这个过程似乎不再产生错误,但它仍然没有做它应该做的事情(同样,如果我在我的控制台中运行那个过程,它工作得很好!)
我正在调试一个程序,但不太清楚为什么我不能删除权限。
我有 root 权限sudo,可以调用setgid/setuid,但[is]不支持该操作。
重现的基本代码(golang):
package main
import (
"fmt"
"os"
"strconv"
"syscall"
)
func main() {
if os.Getuid() != 0 {
fmt.Println("run as root")
os.Exit(1)
}
uid, err := strconv.Atoi(os.Getenv("SUDO_UID"))
check("", err)
gid, err := strconv.Atoi(os.Getenv("SUDO_GID"))
check("", err)
fmt.Printf("uid: %d, gid: %d\n", uid, gid)
check("gid", syscall.Setgid(gid))
check("uid", syscall.Setuid(uid))
}
func check(message string, err error) {
if err != nil {
fmt.Printf("%s: %s\n", message, err)
os.Exit(1)
}
}
Run Code Online (Sandbox Code Playgroud)
示例输出:
$ sudo ./drop-sudo
uid: 1000, …Run Code Online (Sandbox Code Playgroud) 受这个问题的启发,下面是后续内容:
你们中的一些人可能知道 setuid-binaries 是危险的,因为一些漏洞利用这些来将他们的权限升级到 root。
现在似乎有一个有趣的想法用不同的、更安全的方法来替换 setuid。
如何?
我有一些与用户“root”一起使用的 bash 脚本来管理 iptable 规则。
问题是我同时想要这些东西:
这曾经有效,并且仍然是我在旧发行版中使用的:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid(0);
system("/root/iptables/my-iptables-script.sh");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我编译这个然后使用sudo chown rootand sudo chmod 4777。通过这种方式,用户现在可以执行二进制文件并运行 root 拥有的脚本。
但是现在我安装了 Ubuntu 13.10,当我运行那个二进制文件时,我得到了脚本的“权限被拒绝”。
自 12.04 以来,这方面是否有可能发生变化?
我能做什么?
我被有关 setuid 的警告吓坏了。但是我找不到使用它的方法。
我希望能够运行:
arp -s 198.51.100.1 00:53:00:12:34:56
作为用户steven但 arp -s 需要 root。
这是正确的方法吗?
sudo nano example.sh
sudo chmod u+s example.sh
sudo chmod og-w example.sh
sudo chmod o+x example.sh
./example.sh
Run Code Online (Sandbox Code Playgroud) 据我了解,不同的用户ID如下(从进程的角度):
现在我有两个问题:
在程序开始时将有效的用户 ID 保存在一个变量中会不会使保存的用户 ID 变得不必要?
如何在 C 程序中检索保存的用户 ID?我找不到任何这样做的功能。
我从这里了解到有两种方法可以控制特权活动:setuid和capability。
但是当我在我的机器上玩时ping,它似乎可以绕过这两种机制。
首先,确认我的机器/usr/bin/ping有cap_net_raw能力并且它使用SOCK_RAW:
$ ll /usr/bin/ping
-rwxr-xr-x 1 root root 72K Jan 31 2020 /usr/bin/ping
$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep
$ strace -e socket ping <some-ip>
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 5
Run Code Online (Sandbox Code Playgroud)
复制二进制文件会删除该功能,但它仍然有效:
$ cp /usr/bin/ping ~
$ ll ~/ping
-rwxr-xr-x 1 user user 72K Nov 4 16:54 /home/user/ping
$ getcap ~/ping
[empty result]
$ ~/ping <some-ip>
[it works]
Run Code Online (Sandbox Code Playgroud)
我正在使用Ubuntu 20.04和5.4.0-52-generic。
文件中有一个setuid位。
user@host:~$ ls -l /bin/mount
-rwsr-xr-x 1 root root 40152 May 26 19:31 /bin/mount
Run Code Online (Sandbox Code Playgroud)
为什么操作系统需要 root 访问权限才能执行“挂载”?
user@host:~$ /bin/mount /dev/sdb1 /mnt
mount: only root can do that
user@host:~$ sudo /bin/mount /dev/sdb1 /mnt
user@host:~$ lsblk | grep sdb
sdb 8:16 0 102M 0 disk
??sdb1 8:17 0 101M 0 part /mnt
Run Code Online (Sandbox Code Playgroud)
我的 /etc/fstab
# / was on /dev/sda1 during installation
UUID=026bb2d9-1c0c-4163-85a1-f83b2221eb34 / ext4 errors=remount-ro 0 1
# swap was on /dev/sda5 during installation
UUID=aec6b039-13b1-4568-abb1-2be1f3429325 none swap sw 0 0
Run Code Online (Sandbox Code Playgroud) setuid ×10
capabilities ×3
linux ×3
permissions ×3
sudo ×2
c ×1
chmod ×1
locate ×1
mount ×1
osx ×1
root ×1
security ×1
services ×1
setcap ×1
shell-script ×1
system-calls ×1
systemd ×1
ubuntu ×1
uid ×1
users ×1