首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux系统权限知识一览

Linux系统权限知识一览

作者头像
YaoQi
发布2025-07-14 18:53:38
发布2025-07-14 18:53:38
21500
代码可运行
举报
运行总次数:0
代码可运行

操作Linux时经常会遇到权限不足的问题,这就需要对Linux系统的权限机制有比较全面的了解,本文尝试总结Linux系统所具有的各种权限控制机制,然后介绍下使用sudo提权的操作。

一、Linux上的各种权限

※ 基于用户和组的权限

Linux系统最基本的权限系统,是基于用户和组的权限系统,每个文件都根据用户、用户组和其他设定读、写、可执行权限。

用户和用户组

root 用户:Linux 的终极管理员,拥有一切权限。

普通用户:普通用户一般只对自己的home路径有权限,但可以配置允许普通用户可以提权到root权限,也就是允许执行sudo,后文再介绍。

用户组:用户分组,快速配置相同的权限,一般一个用户都有一个和用户同名的用户组,比如用户thht也属于thht用户组。

用户信息保存在 /etc/passwd 中,为安全考虑,用户密码并没有保存在这里,实际保存在 /etc/shadow 文件中。

用户组信息保存在 /etc/group 中,同样组密码保存在单独的文件中 /etc/gshadow 中。

管理用户、用户组相关命令:useradd userdel usermod passwd groupadd groupdel groupmod

文件和目录,都是属于某个用户或某个用户组;

文件的读、写、可执行权限就是字面上的意思;

目录的 " 读、写 " 控制对象是目录内部文件列表,没有读权限不能获取文件列表,没有写权限不能重命名文件;"执行 " 指内部的文件是否可以“读写可执行”。

二进制 100 表示 " 读 " r权限(十进制 4)

二进制 010 表示 " 写 " w权限(十进制 2)

二进制 001 表示 " 可执行"x权限(十进制 1)

三个权限组合到一起就是rwx,没有权限的用-,比如r-x代表没有写权限。

用一位十进制数即可代替三个字母表示权限,也就是上边三个权限十进制数的相加组合,比如7权限就是4+2+1,对应二进制111,表示拥有所有权限。

一般用三位十进制数分别表示用户、组、和其它用户的权限。修改权限的命令是 chmod:

chmod 644 a.txt

代表用户有读写权限,组成员和其他人只有读权限。

umask :创建文件时生成权限的策略,是创建文件时使用权限 6 减去 umask 值;创建路径时使用 7 减去 umask 值。

ls -l 显示的权限分别是文件类型、属主、组、其他人的权限:

※特殊权限

SUID: 能够让二进制程序的执行者临时拥有属主的权限。

SGID: 有两种应用场景,当对二进制程序进行设置时,能够让执行者临时获取到文件所有组的权限;而对目录进行设置时,则是让目录内新创建的文件自动继承该目录原有用户组的名称。

SBIT: 粘滞位,当时文件使用时,该文件只能被其所有者执行删除操作;当对某个目录使用时,该目录中的文件就只能被其所有者执行删除操作。

代码语言:javascript
代码运行次数:0
运行
复制
chmod u+s /tmp/test # 设置 SUID 权限
chmod u-s /tmp/test # 取消 SUID 权限
chmod g+s /tmp/test # 设置 GUID 权限
chmod g-s /tmp/test # 取消 GUID 权限
chmod o+t /tmp/test # 设置 SBIT 权限
chmod o-t /tmp/test # 取消 SBIT 权限

SUID、SGID 与 SBIT 也有对应的数字法表示,分别也是 4、2、1,也就是用数字配置权限最左边增加一位,用四位数:

代码语言:javascript
代码运行次数:0
运行
复制
chmod 7777 /tmp/test # 设置所有权限

被设置的特殊权限会在 ls 权限列表中的“可执行”位的位置体现出来:

代码语言:javascript
代码运行次数:0
运行
复制
root@qc:~# touch test1 test2
root@qc:~# chmod 7000 test1
root@qc:~# chmod 7111 test2
root@qc:~# ls -l test1 test2
---S--S--T 1 root root 0 Oct 22 10:12 test1 # 大写代表没有可执行权限
---s--s--t 1 root root 0 Oct 22 10:12 test2 # 小写代表有可执行权限
root@qc:~#

用户权限位:S代表SUID,s代表SUID+x

组权限位:S代表SGID,s代表SGID+x

其他权限位:T代表SBIT,t代表SBIT+x

也就是小写表示同时有可执行权限,大写表示没有可执行权限。

※隐藏属性权限

读写可执行之外的功能权限,比如锁住一个文件不允许修改的权限 i;只允许以 append 方式打开文件的权限属性 a 等等。

相关命令:chattr 、lsattr。详见 man chattr

※基于文件系统的 FACL 控制

基本的权限只能对文件或目录的所有者、组、其他人配置权限,FACL 可以指定多个用户和分组独立配置权限。目前绝大部分的文件系统都有支持 ACL 的功能,包括 ReiserFS, ext2/ext3/ext4, JFS, XFS 等等。

有些文件系统挂载时自动开启,显式开启可以在 /etc/fstab 文件的 options 列添加acl。

相关命令 getfacl、setfacl

代码语言:javascript
代码运行次数:0
运行
复制
setfacl -m u:hare:rw graph.svg #给用户hare设置rw权限
setfacl -m g:sudo:rwx graph.svg #给sudo组设置rwx权限
setfacl -x g:sudo graph.svg #删除sudo的组权限

root@aliecs:/tmp# ls -l graph.svg  # 配置了ACL的文件权限最后显示+号
-rw-r--r--+ 1 root root 20776 Jan 13 11:57 graph.svg
root@aliecs:/tmp# getfacl graph.svg  #查看文件权限配置
# file: graph.svg
# owner: root
# group: root
user::rw-
user:hare:rw-                   #effective:r--
group::r--
group:sudo:rwx                  #effective:r--
mask::r--
other::r--

※ 特权用户与 Linux Capacity

除了文件权限,Linux 内核对某些功能进行了能力限制。比如 CAP_CHOWN(修改文件属主的权限)、CAP_KILL(发送信号的权限)、CAP_NET_ADMIN(网络管理的权限)等。

在老系统上,按是否特权用户(UID 为 0,即 root 用户)决定这些权限能否使用。Linux 内核 2.2 之后,把这些能力变成独立配置项,授权给线程,内核提供配置权限的接口,启动新线程时会根据线程的用户等信息决定它拥有的权限。

root 用户运行的程序一般会拥有这些权限,普通用户则没有。

查看一个进程拥有的权限:

方法 1:使用进程 id

代码语言:javascript
代码运行次数:0
运行
复制
root@aliecs:~# getpcaps 1397267
1397267: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip

方法 2:通过 /proc 路径,查看进程状态

代码语言:javascript
代码运行次数:0
运行
复制
root@aliecs:~# cat /proc/1397267/status | grep Cap
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
代码语言:javascript
代码运行次数:0
运行
复制
root@aliecs:~# capsh --decode=00000000a80425fb
0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap

相关知识参考 man capabilities

※针对进程的权限

SELinux 和 AppArmor 等权限控制机制,是在进程层面管控文件系统资源的访问。如果配置了相关限制,即使 root 用户也可报权限错误。它们对于所有的文件,目录,端口这类的资源的访问是基于策略设定的。

具体如何使用请自行搜索相关文档。

二、用户切换和提权

首先提醒下读者,切换用户或提权到 root 也解决不了的问题,需要考虑上文所提到的扩展权限、 SELinux 等机制。

su 用于切换用户的登录身份

省略参数默认切换到 root 用户,只有知道 root 密码或拥有 root 权限的用户才可以使用。已经是 root 用户切换到其他用户不需密码,其他用户切换需要目标账号密码

经常用于普通用户切到 root 用户,获得 root 权限。常用的参数是 --login 或 -l ,再简写成一个 - 也可。详情见 man su

sudo 是以其他用户身份执行命令

一般是获取 root 权限执行命令。需要输入密当前用户的密码,这种方式可以不用知道 root 密码就可以提权。但允许哪些用户可以提权执行命令需要提前配置,默认配置文件是 /etc/sudoers,也可以通过 LDAP 配置。

注:编辑配置文件应该使用 visudo,会自动调用系统默认编辑器,有语法检查,防止出错。指定文件使用 -f 参数。

sudoers 配置文件内容

下边这个文件是一般系统的初始化配置,主要是配置了 root 用户和管理员用户组(admin、sudo 组)的权限。

代码语言:javascript
代码运行次数:0
运行
复制
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

root    ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL

#includedir /etc/sudoers.d

Defaults 部分

上例中:

env_reset 重置环变量,移除执行 sudo 命令用户的环境变量; mail_badpass 执行 sudo 时输错密码,会给管理员发邮件,默认是 root; secure_path 重置安全的 PATH 路径,不会使用用户的;

具体格式:

代码语言:javascript
代码运行次数:0
运行
复制
Defaults  Parameter = Value  # 可以用+= -=配置Value细节
Defaults  ! Parameter # 关闭参数
# 也可以指定影响范围,相关的List见下文
Defaults @ Host_List Parameter = Value # 对Host_List配置
Defaults : User_List Parameter = Value # 对User_List配置
Defaults ! Cmnd_List Parameter = Value # 对Cmnd_List配置
Defaults > Runas_List Parameter = Value # 对Runas_List配置

更多参数及具体细节,可以参考 man sudoers 的 SUDOERS OPTIONS 部分。


列表别名

配置文件主要描述的是”某个用户在哪个主机上能以什么身份运行什么命令 “,这其中有四个对象可以预定义一个别名,每个别名定义一组对象。

语法格式 Alias_Type NAME = item1, item2, ...

Alias_Type 有四种:User_Alias, Host_Alias, Runas_Alias, Cmnd_Alias

NAME 只能由大写字母、数字和下划线组成,必须以大写字母开头。已经定义好的别名可以作为同类的 item 使用。

item 前加 "!" 代表取反。NAME=item 可以用冒号 ":" 分隔一次定义多个。

具体的 item 格式分别为:

User_Alias:用户名,用户id(#开头),用户组(%开头),组id(%#开头),网络组(+开头),非Linux用户组名格式(%:开头),非Linux用户组名id格式(%:#开头)。

例:

代码语言:javascript
代码运行次数:0
运行
复制
User_Alias      USERS1 = millert, mikef, dowdy
User_Alias      USERS2 = bostley, ! jwfox, crawl :\
                     USERS3 = will, wendy, wim
User_Alias      USERS4 = wubbi, USERS1

Runas_Alias:item格式和User_Alias一样。

Host_Alias:主机名,IP地址,网段(可带掩码),网络组。

例:

代码语言:javascript
代码运行次数:0
运行
复制
Host_Alias      SPARC = bigtime, eclipse, moet, anchor :\
                SGI = grolsch, dandelion, black :\
                ALPHA = widget, thalamus, foobar :\
                HPPA = boa, nag, python
Host_Alias      CUNETS = 128.138.0.0/255.255.0.0
Host_Alias      CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
Host_Alias      SERVERS = master, mail, www, ns
Host_Alias      CDROM = orion, perseus, hercules

Cmnd_Alias:可执行文件,可执行文件的路径(不包含子路径),"sudoedit"(sudo -e 文件路径,编辑文件而不是执行命令)。

其中可执行文件前,可加数字指纹 "sha224" ':' xxxxx (V1.8.7之后的版本支持);后边不加参数代表用户可自由使用参数;后边加参数代表只允许固定的参数;加 "" 代表不允许带参数。

例:

代码语言:javascript
代码运行次数:0
运行
复制
Cmnd_Alias      DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
                        /usr/sbin/restore, /usr/sbin/rrestore,\
                        sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \
                        /home/operator/bin/start_backups
Cmnd_Alias      KILL = /usr/bin/kill
Cmnd_Alias      PRINTING = /usr/sbin/lpc, /usr/bin/lprm
Cmnd_Alias      SHUTDOWN = /usr/sbin/shutdown
Cmnd_Alias      HALT = /usr/sbin/halt
Cmnd_Alias      REBOOT = /usr/sbin/reboot
Cmnd_Alias      SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\
                         /usr/local/bin/tcsh, /usr/bin/rsh,\
                         /usr/local/bin/zsh
Cmnd_Alias      SU = /usr/bin/su
Cmnd_Alias      PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less

用户规范说明部分

这一部分是最核心的授权描述分为三个部位。

第一位:对谁授权,可以用 User_Alias 别名; 第二位:主机名,一个 sudoers 文件可以复制给多个设备共用,此项指定哪个设备上配置生效,可以用 Host_Alias 别名,ALL 为所有设备的别名。 第三位:可以执行的命令,这一位可以继续分为 3 部分

1)作为 "( 用户 : 分组 )" 执行命令,可以用 Runas_Alias 别名,ALL 代表所有用户或分组,可完全省略或省略部分,完全省略则默认为 root。

2)功能选项或标签,比如 NOTAFTER=2023022008Z , NOPASSWD: , 可省略

3)允许执行的命令、命令路径,可以用 Cmnd_Alias 别名,ALL 代表所有命令。

比如 root ALL=(ALL:ALL) ALL 就代表 root 用户,可以在任何主机上,以任何用户或用户组,执行任何命令,这一条保证了 root 用户执行 sudo 命令时也可以得到运行。

凡是可以用别名的地方,都可以直接写组成别名的 item 项目。

例:

代码语言:javascript
代码运行次数:0
运行
复制
User_Alias    GROUPONE = abby, brent, carl
User_Alias    GROUPTWO = brent, doris, eric,
User_Alias    GROUPTHREE = doris, felicia, grant

# 允许GROUPONE以root身份执行apt-get update
GROUPONE  ALL = /usr/bin/apt-get update

# 允许GROUPTHREE以root身份执行开关机相关命令
Cmnd_Alias    POWER = /sbin/shutdown, /sbin/halt, /sbin/reboot, /sbin/restart
GROUPTHREE  ALL = POWER

# 允许GROUPONE 以www-data或apache身份执行命令
Runas_Alias    WEB = www-data, apache
GROUPONE  ALL = (WEB) ALL

# 执行命令时免密码
GROUPONE  ALL = NOPASSWD: /usr/bin/*

# 多个命令,部分免密码
GROUPTWO  ALL = NOPASSWD: /usr/bin/updatedb, PASSWD: /bin/kill

# 不允许命令内执行新的命令(在less内,!后加命令可以执行其他命令)
username  ALL = NOEXEC: /usr/bin/less

sudo 相关命令

代码语言:javascript
代码运行次数:0
运行
复制
# sudo 使用自己的密码验证,拥有root权限后执行su就可以root登录了
sudo su
# 指定作为哪个用户
sudo -u run_as_user command
# 指定作为哪个分组
sudo -g run_as_group command
# 查看允许执行的命令
sudo -l
# sudo输入密码后会保持一段时间不用重复输入
sudo -k # 不保持,立即超时
sudo -v # 续期

更多细节参考 man sudoers、man sudo

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漫跑的小兔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档