问题

linux如何赋予用户sudo权限?

回答
让用户在 Linux 系统上拥有 `sudo` 权限,可以让他们在需要管理员权限时,通过输入自己的密码来执行命令,而不是整个系统的 root 密码。这是一种更安全、更精细的权限管理方式。下面我将详细地介绍几种常见的方法。

方法一:直接修改 `/etc/sudoers` 文件 (慎用!)

这是最直接的方式,但也是最容易出错的方式。强烈建议不要直接用文本编辑器打开 `/etc/sudoers` 文件进行修改。 为什么?因为如果在这个文件里写错了任何一个字符,都可能导致所有人都无法使用 `sudo` 命令,甚至可能无法通过 `sudo` 获取 root 权限来修复问题。

正确且安全的方式是使用 `visudo` 命令。

1. 打开 `/etc/sudoers` 文件进行编辑:

```bash
sudo visudo
```

`visudo` 命令在编辑 `/etc/sudoers` 文件时会执行语法检查。如果发现语法错误,它会阻止你保存文件,从而避免了潜在的灾难。

2. 添加用户权限:
文件打开后,你会看到很多配置项。要给一个用户 `your_username` 赋予 `sudo` 权限,你需要找到类似下面的行:

```
User privilege specification
root ALL=(ALL:ALL) ALL
```

在这行下面,添加一行:

```
your_username ALL=(ALL:ALL) ALL
```

`your_username`: 替换成你想要赋予权限的实际用户名。
`ALL`: 表示该用户可以在所有主机上使用 `sudo`。通常情况下,这没什么问题,除非你是在一个非常复杂的分布式环境中。
`(ALL:ALL)`: 这部分比较有意思。
第一个 `ALL` 表示该用户可以以 任何用户 的身份运行命令。
第二个 `ALL` 表示该用户可以以 任何组 的身份运行命令。
所以 `(ALL:ALL)` 意味着用户可以切换到任何用户和任何组。
最后的 `ALL`: 表示该用户可以运行 `sudo` 后跟的 所有命令。

3. 保存并退出:
如果你使用的是 `vi` 或 `vim` 作为默认编辑器(大多数 Linux 系统都是如此),按 `Esc` 键,然后输入 `:wq` 并按回车键保存并退出。
如果你使用的是 `nano`,按 `Ctrl+X`,然后按 `Y` 确认保存,最后按回车键确认文件名。

给用户添加特定命令的 sudo 权限 (更安全):

如果你不想让用户拥有执行 所有 命令的权限,可以通过 `visudo` 来限制。例如,只允许 `your_username` 使用 `apt update` 和 `apt upgrade`:

```
your_username ALL=/usr/bin/apt update, /usr/bin/apt upgrade
```

注意:这里需要指定命令的完整路径。你可以通过 `which apt` 来查找 `apt` 的路径。

方法二:将用户添加到 `sudo` 或 `wheel` 用户组

大多数 Linux 发行版都预设了一个名为 `sudo` (Debian/Ubuntu 系) 或 `wheel` (Red Hat/CentOS/Fedora 系) 的用户组。属于这些组的用户,默认情况下就拥有了在 `/etc/sudoers` 文件中被配置好的 `sudo` 权限。这是比直接修改 `/etc/sudoers` 文件更常见、更推荐的做法。

1. 确定你的发行版对应的用户组:

Debian/Ubuntu 系: 通常是 `sudo` 组。
Red Hat/CentOS/Fedora 系: 通常是 `wheel` 组。

2. 将用户添加到用户组:

你可以使用 `usermod` 命令来完成。

如果你想让用户 `your_username` 加入 `sudo` 组 (Debian/Ubuntu):

```bash
sudo usermod aG sudo your_username
```

`a`: 表示 append (追加),即添加到现有用户组,而不是替换用户原有的组。
`G`: 指定要加入的用户组。
`sudo`: 要加入的组名。
`your_username`: 要添加的用户名。

如果你想让用户 `your_username` 加入 `wheel` 组 (Red Hat/CentOS/Fedora):

```bash
sudo usermod aG wheel your_username
```

3. 生效:

用户组的更改需要用户 重新登录 才能生效。这意味着,如果用户 `your_username` 当前正以自己的身份登录,他们需要退出当前的会话,然后重新登录才能使用 `sudo`。

方法三:使用 `gpasswd` 命令(更精简)

`gpasswd` 命令也可以用于管理用户组,提供了一个更简洁的添加用户到组的语法。

将用户 `your_username` 添加到 `sudo` 组:

```bash
sudo gpasswd a your_username sudo
```

`a`: 添加用户到指定的组。

将用户 `your_username` 添加到 `wheel` 组:

```bash
sudo gpasswd a your_username wheel
```

同样,用户需要重新登录才能使更改生效。

如何验证用户是否拥有 sudo 权限?

1. 让目标用户登录,然后尝试执行一个需要 sudo 的命令:

```bash
sudo apt update 或者 sudo yum update
```

如果系统提示输入 `your_username` 的密码,并且在输入密码后命令成功执行,那么权限就已经赋予了。

2. 查看用户所属的组 (推荐):

```bash
groups your_username
```

如果输出中包含了 `sudo` 或 `wheel` (取决于你的发行版),那么用户就已经拥有了通过组机制赋予的 `sudo` 权限。

总结与最佳实践

新手入门: 对于大多数个人用户或小型服务器,将用户添加到 `sudo` 或 `wheel` 组是 最简单、最安全 的方法。
精细控制: 如果你需要对某些用户执行特定命令的权限进行严格限制,那么使用 `visudo` 直接编辑 `/etc/sudoers` 文件,并指定命令路径,是 最灵活 的方式。
安全第一: 永远 不要 直接用文本编辑器修改 `/etc/sudoers` 文件。始终使用 `visudo`。
最小权限原则: 尽可能给予用户完成其任务所需的最低权限。如果用户只需要执行少数几个管理命令,就只赋予那几个命令的权限,而不是让他们拥有 `/etc/sudoers` 中的 `ALL=(ALL:ALL) ALL` 这样的完全权限。

选择哪种方法取决于你的具体需求和对系统安全性的考量。不过,对于初学者来说,从将用户添加到预设的 `sudo` 或 `wheel` 组开始,是一个非常好的起点。

网友意见

user avatar

“linux如何赋予用户sudo权限”这个问题其实问的并不准确,因为根本没有"sudo"这个权限,这个问题应该说成“Linux系统的sudo命令如何让非特权的普通用户具有了执行特权操作的权限?”下面我就来解释一下这个问题。

Set-user-ID位

sudo能够赋予普通用户特权的根本原因,是一个叫set-user-ID的权限位及其所对应的运行机制带来的:

       $ ls -l `which sudo` ---s--x--x. 1 root root 189600 Jan 27  2021 /usr/bin/sudo     

如上,就是那个"---s--x--x"中的"s"。

其实系统中还有很多带这个S位的程序,比如:

       -rwsr-xr-x. 1 root root 57328 Jul 27  2020 /usr/bin/at -rwsr-xr-x. 1 root root 74224 Aug 16 16:00 /usr/bin/chage -rws--x--x. 1 root root 32760 Jan  7  2021 /usr/bin/chfn -rws--x--x. 1 root root 24536 Jan  7  2021 /usr/bin/chsh -rwsr-xr-x. 1 root root 53800 Mar 29  2021 /usr/bin/crontab -rwsr-xr-x. 1 root root 36840 Jul 28  2020 /usr/bin/fusermount -rwsr-xr-x. 1 root root 41768 Aug 10  2020 /usr/bin/fusermount3 -rwsr-xr-x. 1 root root 78576 Aug 16 16:00 /usr/bin/gpasswd -rwsr-xr-x. 1 root root 49184 Jan  7  2021 /usr/bin/mount -rwsr-xr-x. 1 root root 42280 Aug 16 16:00 /usr/bin/newgrp -rwsr-xr-x. 1 root root 32640 Jun  3  2021 /usr/bin/pkexec -rwsr-xr-x. 1 root root 32624 Jul 29  2020 /usr/bin/passwd -rwsr-xr-x. 1 root root 36832 Jan  7  2021 /usr/bin/umount -rwsr-xr-x. 1 root root 57752 Jan  7  2021 /usr/bin/su ---s--x--x. 1 root root 189600 Jan 27  2021 /usr/bin/sudo     

我们管这个位叫set-user-ID位,简称suid位。同样的,还有一个set-group-ID位,简称sgid位,当然suid位比较常见。

suid位一般给一个可执行程序设置,其主要作用就是“让运行带有suid位程序的进程的有效用户ID(euid)等于这个程序文件的属主ID”。这样说可能对于不了解的人有点难懂,下面我们详细说一下。

比如如果有一个文件它的属性如下:

       -rwsr-xr-x. 1 userA userA 57328 Jul 27  2020 mytest     

那么比如我用userB执行这个程序,那么运行起来的进程的euid等于userA,而不等于userB。

那这有什么用呢?如果上面的userA是一个普通用户,那用处不太大,就是改变了进程的euid(还是有作用的)。但是如果上面的userA是root,那作用就很大了,因为如果一个进程的euid变成了root(0),那这个进程就获得了root的特权,因为它相当于在代替root做事(当然不是完全等同于root亲自执行,但是几乎等同了)。所以你看到sudo的属主就是root,我们习惯性管属主是root的suid位叫“suid root”位,你和行内的人一提suid root,他就能知道你在说什么。

设置SUID位

相信很多初学Linux的人都很熟悉0777这个权限,也就是rwxrwxrwx,分别表示属主、属组和其它人的读写执行权限。也经常能看到有人说给Linux系统所有文件都改成0777,是不是就无敌了。对于这样天真的孩子我只能说你将系统安全机制想的太简单了,这还只是冰山一角而已。

即使光讨论permission bits,也不止0777这么多,777上面还有更多呢。比如我们这里提到的set-user-id位就是其中一个,其定义是:

       #define S_ISUID 0004000     

你要设置这个位,就可以写04777或者04111等。比如有一个文件的权限是0644:

       $ ls -l testfile -rw-r--r--. 1 test test 0 Jan 11 22:21 testfile     

那么我要给它加S位,就可以写:

       $ chmod 04644 testfile $ ls -l testfile -rwSr--r--. 1 test test 0 Jan 11 22:21 testfile     

我们看到这里有一个大"S",这就是set-user-id位。有人可能问了,这个S不就占了"x"的位置了吗?如果再设置上x的权限,比如04744,那会怎么样呢?答案是:

       $ chmod 04744 testfile $ ls -l testfile -rwsr--r--. 1 test test 0 Jan 11 22:21 testfile     

是的,S+x就变成了小"s",这个小s就是我们这个回答的重点,也就是具有执行权的程序同时具有suid位。

设置suid位的方法除了你直接写04xxx以外,用u+s这种方式也可以,比如:

       # chmod u+s testfile # chmod u-s testfile     

这样可以方便的增加或去掉suid位。当然有set-user-id位,也有set-group-id位,不过sgid位和sudo没有关系,我们本回答不讲。

用程序说话

为了更直观的理解,我们用一个程序来说明一下suid位的作用。假设我现在的系统上有一个id是1000的用户叫test,还有一个id是1001的用户叫userA,当然还有id是0的root用户,我用test用户作为测试用户,编写并执行下面的程序(mytest.c):

       #include <stdio.h> #include <unistd.h> #include <sys/types.h>  int main() {         printf("The process' uid is: %u
", getuid());         printf("The process' euid is: %u
", geteuid());          return 0; }     

这个程序编译后得到的可执行程序现在的属性是:

       [test]$ ls -l mytest -rwxr-xr-x. 1 test test 25800 Jan 11 20:52 mytest     

我用uid是1000的用户test来执行它:

       [test]$ ./mytest The process' uid is: 1000 The process' euid is: 1000     

接下来我们(用root用户操作)改变这个文件的属主:

       [root]# chown userA mytest [root]# ls -l mytest -rwxr-xr-x. 1 userA test 25800 Jan 11 20:52 mytest     

再用id为1000的test用户执行:

       [test]$ ./mytest  The process' uid is: 1000 The process' euid is: 1000     

结果进程的uid和euid还是1000(test)。

现在我(用root用户操作)给这个程序设置suid位:

       [root]# chmod u+s mytest [root]# ls -l mytest -rwsr-xr-x. 1 userA test 25800 Jan 11 20:52 mytest     

再用test用户用执行:

       [test]$ ./mytest  The process' uid is: 1000 The process' euid is: 1001     

这次我们看到进程的euid变成了1001,不再是1000了,这个1001就是userA的ID:

       [test]$ id userA uid=1001(userA) gid=1001(userA) groups=1001(userA)     

这就是suid位的作用,但是在程序文件的属主是普通用户的情况下,除了能获得属主相同的euid外,没有别的影响。

因为现代Linux系统已经区别于过去的Unix系统,分出了各种细节的权能(具体可man capabilities),为了能看一下当前程序的特权,我修改了一下程序,将特权信息打出来:

       #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/capability.h>  int main() {         printf("The process' uid is: %u
", getuid());         printf("The process' euid is: %u
", geteuid());          cap_t caps = NULL;         char *txt_caps = NULL;         caps = cap_get_proc();         if (!caps) {                 perror("cap_get_proc");                 return 1;         }         txt_caps = cap_to_text(caps, NULL);         if (!txt_caps) {                 perror("cap_to_text");                 return 2;         }         printf("Current capabilities: %s
", txt_caps);                  return 0; }     

编译后重新将suid位设置好,属主改为userA(跟上面一样),再用test用户执行:

       [test]$ gcc -o mytest mytest.c -lcap -Wall [root]# chown userA mytest [root]# chmod u+s mytest [test]$ ./mytest The process' uid is: 1000 The process' euid is: 1001 Current capabilities: =     

我们看到euid变成了1001,最后一行那个"="的意思你可以简单理解为"All=nothing",也就是什么特权都没有。这里我不想展开解释capabilities的东西,展开的话又够另一个篇章了。

现在我们将mytest的属主变成root,然后还用test用户执行:

       [root]# chown root mytest [root]# chmod u+s mytest [root]# ls -l mytest -rwsr-xr-x. 1 root test 25936 Jan 11 21:32 mytest [test]$ ./mytest The process' uid is: 1000 The process' euid is: 0 Current capabilities: =ep     

这次我们看到进程的uid还维持是test用户的id=1000,但是euid变成了0,而且当前的特权是"=ep",也就是"ALL=ep",“ep”分别表示Effective特权集和Permitted特权集,也就是这两个特权集都是满的,这里我不展开解释Permitted, Effective和Inheritable特权集合的概念了,总之这里你可以理解为当前进程具有全部的特权。

这就是suid root的作用,让一个程序即使被普通用户执行,也可以越权。sudo程序就是借助suid root这个特性获得的特权,让普通用户可以执行特权操作。

结语:

这里说的一些概念只是Linux安全相关的冰山一角,感兴趣的可以自己去学习更多。上面之所以euid是0的进程直接就具有了全部特权,那是从古老的Unix系统至今的一种使用习惯的继承,现在的Linux系统其实可以配置成将root超级用户的特权分开分给几个具有不同用途的管理员,而取消root的使用,我们也做过这样的课题和研究,也确实能做到分权,但是目前对于普通的使用者来说将系统配成那样过于不便,所以目前的系统状态仍然是主流。但是将来系统去root化是一个研究方向和发展趋势。

关于sudo我还写过下面一个回答,感兴趣的可以看一下,并不属于技术问题。

user avatar

将用户加入可以 sudo 的用户组即可,如果不知道怎样将用户加入某个指定名称的用户组,可单独查找相关问题的答案。

Linux 中的权限是以用户组来划分的

至于,什么用户组拥有sudo权限?很抱歉这个问题没有统一的答案,因为每个Linux发行版有不同的设定。

你可以启动 sudo visudo 查看哪个用户组拥有sudo权限。

例如我手头这个发行版含有这样的字样:

       # Allow members of group sudo to execute any command %sudo   ALL=(ALL:ALL) ALL      

可以看出在这个发行版中,名为 sudo 的用户组具备 sudo 权限。

于是,你选择将你需要加的用户加入 sudo 用户组,就能令其具备 sudo 权限了。

再次声明一下:不同发行版的用户组名称不同,其它发行版中的 sudo 权限用户组并不一定叫 sudo,你需要先使用 sudo visudo 查询一下才知道。


另外补充一下:某位RH工程师回答的内容本身是正确的,但他似乎并没有理解题主所问的问题。或者说他可能将题主的问题想复杂了。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有