参考链接https://www.linuxprobe.com/
Linux是一个多用户、多任务的操作系统,具有很好的稳定性与安全性,在幕后保障Linux系统安全的则是一系列复杂的配置工作。本章将 详细讲解文件的所有者、所属组以及其他人可对文件进行的读(r)、写(w)、执行(x)等操作,以及如何在Linux系统中添加、删除、 修改用户账户信息。我们还可以使用SUID、SGID与SBIT特殊权限更加灵活地设置系统权限功能,来弥补对文件设置一般操作权限时所带来 的不足。隐藏权限能够给系统增加一层隐形的防护层,让黑客最多只能查看关键日志信息,而不能进行修改或删除。而文件的访问控制列 表(Access Control List,ACL)可以进一步让单一用户、用户组对单一文件或目录进行特殊的权限设置,让文件具有能满足工作需求的 最小权限。本章最后还将讲解如何使用su命令与sudo服务让普通用户具备管理员的权限,不仅可以满足日常的工作需求,还可以确保系统 的安全性 管理员UID为0:系统的管理员用户。 系统用户UID为1~999: Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认服务程序会有独立的系统用户负责 运行,进而有效控制被破坏范围。 普通用户UID从1000开始:是由管理员创建的用于日常工作的用户。 一个用户只有一个基本用户组,但是可以有多个扩展用户组,从而满足日常的工作需要。 useradd -d 指定用户的家目录(默认为/home/username) -e 账户的到期时间,格式为YYYY-MM-DD -u 指定用户的默认UID -g 指定一个初始的用户基本组(必须已存在) -G 指定一个或多个扩展用户组 -N 不创建与用户同名的基本用户组 -s 指定该用户的默认Shell解释器 /sbin/nologin 解释器 和Base解释器相反 其表示用户不能登录到系统中 [root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe [root@linuxprobe ~]# id linuxprobe uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe) groupadd命令 #groupadd ronny usermod命令 用户修改用户属性 如用户的UID 基本、扩展用户组、默认终端 -c 填写用户账户的备注信息 -d -m -d -m参数连用,可重新指定用户的家目录并且自动把旧的数据移过去 -e 账户的到期时间 YYYY-MM-DD -g 变更所属用户组 -G 变更扩展用户组 -L 锁定用户禁止其登录系统 -U 解锁用户,允许其登录系统 -s 变更默认终端 -u 修改用户的UID [root@linuxprobe ~]# id linuxprobe uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe) 然后将用户linuxprobe加入到root用户组中,这样扩展组列表中则会出现root用户组的字样,而基本组不会受到影响: [root@linuxprobe ~]# usermod -G root linuxprobe [root@linuxprobe ~]# id linuxprobe uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root) passwd命令 -l 锁定用户,禁止其登录 lock -u 解锁用户,允许用户登录 unlock --stdin 允许通过标准输入修改用户密码 echo "NewPasswod" |passwd --stdin Username -d 使该用户可用空密码登录系统 -e 强制用户在下次登录时修改密码 -S 显示用户密码是否被锁定,以及密码所采用的加密算法名称 假设您有位同事正在度假,而且假期很长,那么可以使用passwd命令禁止该用户登录系统,等假期结束回归工作岗位时,再使用该命令允 许用户登录系统,而不是将其删除。这样既保证了这段时间内系统的安全,也避免了频繁添加、删除用户带来的麻烦 #passwd -l ljc 锁定 #passwd -S ljc 检测 #passwd -u ljc 解锁 userdel命令 删除用户 当确认某个用户不再登录系统,则通过userdel删除用户 在执行删除,默认家目录会保存,若一起删除则 -r参数 -f 强制删除用户 -r 同时删除用户以及用户家目录 文件权限与归属 - 普通文件 d 目录文件 l 链接文件 b 块设备文件 c 字符设备文件 p 管道文件 对于文件: 可读 可读取文件实际内容 可写 可以编辑新增修改删除文件实际内容 可执行 可以运行一个脚本程序 但对于目录文件 没那么容易 可读 表示可以读取目录内的文件列表 可写 可以对目录新增删除重命名 可执行 表示能够进入该目录 文件的读写执行 rwx 数字 4 2 1来表示 所有者 所属组 其他人 无关联 7表示 4 2 1 可读可写可执行 6表示 4 2 可读可写 转换 764 rwxrw-r-- 642 rw-r---w- 153 --xr-w-wx 731 rwx-wx--x rwxrw-r-- 764 rw--w--wx 623 rw-r--r-- 644 生产环境,单纯设置文件的rwx权限无法满足 因此由了SUID SGID与SBIT蛇叔权限位,这是一种对文件权限设置的特殊功能,可以与一般权限同时使用 以弥补一般权限不能实现的功能 SUID 一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限 看passwd命令属性时发现所有者的权限由rwx变成了rws,其中x改变成s就意味着该文件被赋予了SUID权限。另外有读者会好奇,那么如果 原本的权限是rw-呢?如果原先权限位上没有x执行权限,那么被赋予特殊权限后将变成大写的S。 [root@linuxprobe ~]# ls -l /etc/shadow ----------. 1 root root 1004 Jan 3 06:23 /etc/shadow [root@linuxprobe ~]# ls -l /bin/passwd -rwsr-xr-x. 1 root root 27832 Jan 29 2017 /bin/passwd SGID 让执行者临时拥有所属组的权限(对拥有执行权限的二进制程序进行设置) 在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置) 早期的Linux系统中,/dev/kmem是一个字符设备文件,用于存储内核程序要访问的数据,权限为: cr--r----- 1 root system 2, 1 Feb 11 2017 kmem [root@linuxprobe ~]# cd /tmp [root@linuxprobe tmp]# mkdir testdir [root@linuxprobe tmp]# ls -ald testdir/ drwxr-xr-x. 2 root root 6 Feb 11 11:50 testdir/ [root@linuxprobe tmp]# chmod -Rf 777 testdir/ [root@linuxprobe tmp]# chmod -Rf g+s testdir/ [root@linuxprobe tmp]# ls -ald testdir/ drwxrwsrwx. 2 root root 6 Feb 11 11:50 testdir/ 在使用上述命令设置好目录的777权限(确保普通用户可以向其中写入文件),并为该目录设置了SGID特殊权限位后,就可以切换至一个普 通用户,然后尝试在该目录中创建文件,并查看新创建的文件是否会继承新创建的文件所在的目录的所属组名称: [root@linuxprobe tmp]# su - linuxprobe Last login: Wed Feb 11 11:49:16 CST 2017 on pts/0 [linuxprobe@linuxprobe ~]$ cd /tmp/testdir/ [linuxprobe@linuxprobe testdir]$ echo "linuxprobe.com" > test [linuxprobe@linuxprobe testdir]$ ls -al test -rw-rw-r--. 1 linuxprobe root 15 Feb 11 11:50 test chmod 设置权限 #chmod 760 test rwxrw---- chown设置所属所有者和所属组 -R递归操作,即对整个目录所有文件进行整体操作 #chown -R tomcat.tomcat ,, SBIT(Sticky Bit)特殊权限位了 (也可以称之为特殊权限位之粘滞位) 保护位 RHEL 7系统中的/tmp作为一个共享文件的目录,默认已经设置了SBIT特殊权限位,因此除非是该目录的所有者,否则无法删除这里面的文 件。 与前面所讲的SUID和SGID权限显示方法不同,当目录被设置SBIT特殊权限位后,文件的其他人权限部分的x执行权限就会被替换成t或者T, 原本有x执行权限则会写成t,原本没有x执行权限则会被写成T 当然,要是也想对其他目录来设置SBIT特殊权限位,用chmod命令就可以了。对应的参数o+t代表设置SBIT粘滞位权限: [blackshield@linuxprobe tmp]$ exit Logout [root@linuxprobe tmp]# cd ~ [root@linuxprobe ~]# mkdir linux [root@linuxprobe ~]# chmod -R o+t linux/ [root@linuxprobe ~]# ls -ld linux/ drwxr-xr-t. 2 root root 6 Feb 11 19:34 linux/ 文件的隐藏属性 Linux系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏属性 明明权限充足但却无法删除某个文件的情况,或者仅能在日志文件中追加内容而不能修改或删除内容,这在一定程度上阻止了黑客篡改系 统日志的图谋,因此这种“奇怪”的文件也保障了Linux系统的安全性。 chattr命令 chattr用于设置文件的隐藏权限,如果添加隐藏功能到文件 "+参数" 移除隐藏功能 "-参数" i 无法对文件进行修改,若对目录设置了该参数,则仅能修改其中的子文件内容,不能新建也不能删除文件 a 仅允许追加内容,无法覆盖/删除内容 S 文件内容在变更后立即同步到硬盘(sync) s 彻底从硬盘中删除,不可恢复 A 不再修改这个文件或目录的最后访问时间 b 不再修改文件或目录的存取时间 D 检测压缩文件中的错误 d 使用dump命令备份时忽略本文件/目录 c 默认将文件或目录进行压缩 u 当删除文件后依然保留其在硬盘中的数据,方便日后恢复 t 让文件系统支持尾部合并 x 可直接访问压缩文件中的内容 [root@linuxprobe ~]# echo "for Test" > linuxprobe [root@linuxprobe ~]# chattr +a linuxprobe [root@linuxprobe ~]# rm linuxprobe rm: remove regular file ‘linuxprobe’? y rm: cannot remove ‘linuxprobe’: Operation not permitted lsattr命令 用于显示文件的隐藏属性 格式lsattr 参数 文件 [root@linuxprobe ~]# lsattr linuxprobe -----a---------- linuxprobe [root@linuxprobe ~]# chattr -a linuxprobe [root@linuxprobe ~]# lsattr linuxprobe ---------------- linuxprobe [root@linuxprobe ~]# rm linuxprobe rm: remove regular file ‘linuxprobe’? y 文件访问控制列表 一般权限,特殊权限,隐藏权限都是权限针对某一类用户设置。 如果想要针对某个指定用户进行单独的权限控制,就需要用到文件的访问控制列表ACL 基于普通文件或目录设置ACL其实就是针对指定的用户或用户组设置文件或目录的操作权限。另外,如果针对某个目录设置了ACL,则目录 中的文件会继承其ACL;若针对文件设置了ACL,则文件不再继承其所在目录的ACL。 setfacl命令 用于管理文件的ACL规则 ACL提供的是在所有者所属组其他人的读写执行权限之外的特殊权限控制 使用setfacl命令可以针对单一用户或用户组,单一文件或目录进行读写执行权限的控制,-R递归参数 针对普通目录、文件则使用 -m 如果想要删除某个文件的ACL -b参数 [root@linuxprobe ~]# setfacl -Rm u:linuxprobe:rwx /root [root@linuxprobe ~]# su - linuxprobe Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1 [linuxprobe@linuxprobe ~]$ cd /root [linuxprobe@linuxprobe root]$ ls anaconda-ks.cfg Downloads Pictures Public [linuxprobe@linuxprobe root]$ cat anaconda-ks.cfg [linuxprobe@linuxprobe root]$ exit setfacl -b /root 删除这个目录的ACL访问控制 文件的权限最后一个点(.)变成了加号(+),这就意味着该文件已经设置了ACL了。 [root@linuxprobe ~]# ls -ld /root dr-xrwx---+ 14 root root 4096 May 4 2017 /root getfacl命令用于显示文件上设置的ACL信息,格式为“getfacl 文件名称”。Linux系统中的命令就是这么又可爱又好记。想要设置ACL, 用的是setfacl命令;要想查看ACL,则用的是getfacl命令。下面使用getfacl命令显示在root管理员家目录上设置的所有ACL信息。 [root@linuxprobe ~]# getfacl /root getfacl: Removing leading '/' from absolute path names # file: root # owner: root # group: root user::r-x user:linuxprobe:rwx group::r-x mask::rwx other::--- su命令与sudo服务 su命令用于解决用户身份切换需求 su命令与用户名之间有一个-号 意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不保留原始数据 建议都这样设置 su - ljc su - tomcat 使用sudo命令把特定命令的执行权限赋予给指定用户,这样既可保证普通用户能够完成特定的工作,也可以避免泄露root管理员密码。我 们要做的就是合理配置sudo服务,以便兼顾系统的安全性和用户的便捷性。sudo服务的配置原则也很简单—在保证普通用户完成相应工作 的前提下,尽可能少地赋予额外的权限。 sudo -h 列出帮助信息 -I 列出当前用户可执行的命令 -u 用户名、UID值 以指定的用户身份执行命令 -k 清空密码的有效时间,下次执行sudo时需要再次进行密码验证 -b 在后台执行指定的密码 -p 更改询问密码的提示语 限制用户执行指定的命令: 记录用户执行的每一条命令; 配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数; 验证密码的后5分钟内(默认值)无须再让用户再次验证密码。 只有root管理员才可以使用visudo命令编辑sudo服务的配置文件 使用visudo命令配置sudo命令的配置文件时,其操作方法与Vim编辑器中用到的方法一致,因此在编写完成后记得在末行模式下保存并退出 。在sudo命令的配置文件中,按照下面的格式将第99行(大约)填写上指定的信息: 谁可以使用 允许使用的主机=(以谁的身份) 可执行命令的列表 [root@linuxprobe ~]# visudo 96 ## 97 ## Allow root to run any commands anywhere 98 root ALL=(ALL) ALL 99 linuxprobe ALL=(ALL) ALL 在填写完毕后记得要先保存再退出,然后切换至指定的普通用户身份,此时就可以用sudo -l命令查看到所有可执行的命令了(下面的命令 中,验证的是该普通用户的密码,而不是root管理员的密码,请读者不要搞混了): 效果立竿见影!但是考虑到生产环境中不允许某个普通用户拥有整个系统中所有命令的最高执行权(这也不符合前文提到的权限赋予原则 ,即尽可能少地赋予权限),因此ALL参数就有些不合适了。因此只能赋予普通用户具体的命令以满足工作需求,这也受到了必要的权限约 束。如果需要让某个用户只能使用root管理员的身份执行指定的命令,切记一定要给出该命令的绝对路径,否则系统会识别不出来。我们 可以先使用whereis命令找出命令所对应的保存路径,然后把配置文件第99行的用户权限参数修改成对应的路径即可: [linuxprobe@linuxprobe ~]$ exit logout [root@linuxprobe ~]# whereis cat cat: /usr/bin/cat /usr/share/man/man1/cat.1.gz /usr/share/man/man1p/cat.1p.gz [root@linuxprobe ~]# visudo 96 ## 97 ## Allow root to run any commands anywhere 98 root ALL=(ALL) ALL 99 linuxprobe ALL=(ALL) /usr/bin/cat 在编辑好后依然是先保存再退出。再次切换到指定的普通用户,然后尝试正常查看某个文件的内容,此时系统提示没有权限。这时再使用 sudo命令就可以顺利地查看文件内容了: [root@linuxprobe ~]# su - linuxprobe Last login: Thu Sep 3 15:51:01 CST 2017 on pts/1 [linuxprobe@linuxprobe ~]$ cat /etc/shadow cat: /etc/shadow: Permission denied [linuxprobe@linuxprobe ~]$ sudo cat /etc/shadow root: $6$GV3UVtX4ZGg6ygA6$J9pBuPGUSgZslj83jyoI7ThJla9ZAULku3BcncAYF00Uwk6Sqc4E36MnD1hLtlG9QadCpQCNVJs/5awHd0/pi1:16626:0:99999: 7::: 每次执行sudo命令都要输入一次密码其实也挺麻烦的,这时可以添加NOPASSWD参数,使得用户执行sudo命令时不再需要密码验证: [linuxprobe@linuxprobe ~]$ exit logout [root@linuxprobe ~]# whereis poweroff poweroff: /usr/sbin/poweroff /usr/share/man/man8/poweroff.8.gz [root@linuxprobe ~]# visudo 96 ## 97 ## Allow root to run any commands anywhere 98 root ALL=(ALL) ALL 99 linuxprobe ALL=NOPASSWD: /usr/sbin/poweroff 这样,当切换到普通用户后再执行命令时,就不用再频繁地验证密码了,我们在日常工作中也就痛快至极了。 [root@linuxprobe ~]# su - linuxprobe Last login: Thu Sep 3 15:58:31 CST 2017 on pts/1 [linuxprobe@linuxprobe ~]$ poweroff User root is logged in on seat0. Please retry operation after closing inhibitors and logging out other users. Alternatively, ignore inhibitors and users with 'systemctl poweroff -i'. [linuxprobe@linuxprobe ~]$ sudo poweroff 1.UID为0则为root 2.增加或删除用户 useradd userdel 3.链式文件755 lrwxr-xr-x 4.如果希望用户执行某命令时临时拥有该命令所有者的权限,应该设置什么特殊权限? SUID 5.对文件设置隐藏权限+i 则意味着无法对文件进行修改,若对目录设置了该参数,则仅能修改其中的子文件内容,不能新建也不能删除文 件 6.设置访问控制来限制linuxprobe用户组,使该组不能在tmp目录下写入内容 setfacl -Rm g:linuxprobe:r-x /tmp 7.普通用户使用sudo命令时需要验证当前用户的密码,若不想验证,可以添加NOPASSWD参数