Linux系统权限知识和提权操作
基于对安全的考虑,平时应该使用普通用户登录Linux系统,只有在需要的时候"提升权限"到root。本文简单介绍下权限相关的知识和使用sudo进行提权操作的配置。
※用户、文件和权限的基础知识
root用户:Linux的终极管理员,拥有一切权限。
用户组:用户分组,快速配置相同的权限,一般一个用户都有一个同名用户组。
用户信息保存在/etc/passwd中,为安全考虑,用户密码实际保存在/etc/shadow文件中。
用户组信息保存在 /etc/group中,组密码保存在单独的文件中/etc/gshadow中。
管理用户、用户组相关命令:useradd userdel usermod passwd groupadd groupdel groupmod
※ 文件和路径的权限
文件和目录,都是属于某个用户或某个用户组的;
文件的读、写、可执行权限就是字面上的意思;
目录的"读写"指文件列表,没有读权限不能获取文件列表,没有写权限不能重命名文件;"执行"指内部的文件是否可以“读写可执行”。
ls -l 显示的权限分别是属主,分组,其他人的权限;
二进制100表示"读"权限(十进制4)
二进制010表示"写"权限(十进制2)
二进制001表示"可执行"(十进制1)
用一位十进制数即可表示权限,也就是这几个数的相加组合,相关命令是chmod;
umask :创建文件时生成权限的策略是,创建文件时使用权限6减去umask值;创建路径时使用7减去umask值。
扩展权限:读写可执行之外的功能权限,比如锁住一个文件不允许修改的权限i;只允许以append方式打开文件的属性a等等。
相关命令:chattr 、lsattr。详见 man chattr
※ 特权用户与 Linux Capacity
除了文件权限,Linux内核对某些功能进行了能力限制。比如 CAP_CHOWN(修改文件属主的权限)、CAP_KILL(发送信号的权限)、CAP_NET_ADMIN(网络管理的权限)等。
在老系统上,按是否特权用户(UID为0,即root用户)决定这些权限能否使用。Linux内核2.2之后,把这些能力变成独立配置项,授权给线程,内核提供配置权限的接口,启动新线程时会根据线程的用户等信息决定它拥有的权限。
root用户运行的程序一般会拥有这些权限,普通用户则没有。
查看一个进程拥有的权限:
方法1:使用进程id
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路径,查看进程状态
root@aliecs:~# cat /proc/1397267/status | grep Cap
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
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组)的权限。
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路径,不会使用用户的;
具体格式:
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格式(%:#开头)。
例:
User_Alias USERS1 = millert, mikef, dowdyUser_Alias USERS2 = bostley, ! jwfox, crawl :\ USERS3 = will, wendy, wimUser_Alias USERS4 = wubbi, USERS1
Runas_Alias:item格式和User_Alias一样。
Host_Alias:主机名,IP地址,网段(可带掩码),网络组。
例:
User_Alias USERS1 = millert, mikef, dowdy
User_Alias USERS2 = bostley, ! jwfox, crawl :\
USERS3 = will, wendy, wim
User_Alias USERS4 = wubbi, USERS1
Cmnd_Alias:可执行文件,可执行文件的路径(不包含子路径),"sudoedit"(sudo -e 文件路径,编辑文件而不是执行命令)。
其中可执行文件前,可加数字指纹 "sha224" ':' xxxxx (V1.8.7之后的版本支持);后边不加参数代表用户可自由使用参数;后边加参数代表只允许固定的参数;加 "" 代表不允许带参数。
例:
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
※用户规范说明部分
这一部分是最核心的授权描述分为三个部位。
第一位:对谁授权,可以用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项目。
例:
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
※sudo相关命令
# 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