Contents
1. Linux奇技淫巧
1.1. grep与拓展正则表达式
要求:显示/etc/目录下,以非字母开头,后面跟了一个字母以及其他任意长度任意字符的文件或目录
方案:利用grep -E
或者egrep
命令结合扩展正则表达式语法实现标准输出流的过滤。具体如下所示:
拆解上述要求,以便从拆解的信息中构建正则表达式。上述要求拆解如下:
非字母开头的文件或者目录,可以通过
ls /etc/
命令遍历/etc/目录,不做嵌套子目录查询利用grep提供的拓展正则表达式中的
[:alpha:]
表示任意一个字母,将其封装在中括号中,并前面加上脱字符(^),写法如下:
[^[:alpha:]]
上述表示不包含字母,但是要表示开头,还需要在外层中括号的外面再使用一个脱字符,表示匹配行首。另外,开头也可以有多个非字母部分,表示多余1个的正则表达式用
+
号表示,这部分的完整写法如下:
^[^[:alpha:]]+
上述即为以非字母开头的名称匹配表达式。
非字母开头的名称后面跟一个字母
此处限定字母的个数为1个,用正则表达式表示为
{1}
,而字母的正则表达式形式为[:alpha:]
,所以将这两部分组合在一起,就符合这部分的要求了:[[:alpha:]]{1}
。字母后面跟任意长度的任意字符
任意长度的任意字符,可以用正则表达式表示为
.*
所以,将上述三部分按顺序组合在一起,就是目标正则表达式
^[^[:alpha:]]+[[:alpha:]]{1}.*
。由于/etc/目录没有符合要求的文件,手动在/tmp目录构建一个,执行效果如下所示:tmp]# ls | egrep '^[^[:alpha:]]+[[:alpha:]]{1}.*' 1a_123abc...py tmp]#
1.2. xargs结合管道实现参数传递
要求:将/etc/目录下的所有以p开头且以非字母结尾的文件或目录复制到/tmp/mytest1目录中
方案:此处也需要用到上面的grep
命令以及正则表达式,同时需要借助管道和xargs命令传递执行结果。
上述要求可以拆解为两步:
第一步是通过正则表达式匹配出以p开头且以非字母结尾的文件或者目录
这一步的关键是正则表达式的构建,以p开头可以表示为
^p.*
,表示以p开头,后接任意长度的任意字符;以非字母结尾表示为[^[:alpha:]]$
,将这两部分结合在一起,就是最终的正则表达式的写法:^p.*[^[:alpha:]]$
上述正则表达式在实际命令中的执行效果如下所示:
tmp]# ls /etc/ | egrep '^p.*[^[:alpha:]]$' passwd- pkcs11 polkit-1 tmp]#
上述即为匹配出来的以p开头且以非字母结尾的文件或者目录。
第二步为将匹配到的文件或者目录拷贝到/tmp/mytest1这个目录中(如果不存在该目录,则需要先创建该目录)。
要将上一步的执行结果通过cp命令拷贝到/tmp/mytest1这个目录中,就需要将上一步的执行结果通过管道作为cp命令的输入参数来处理,而实际上cp命令并不能接受标准输出的内容作为其输入参数。为此,就需要借助
xargs
这个命令来将前一条命令的标准输出与cp命令结合起来。xargs
命令的使用形式为command1 | xargs -i {} command2 options
。至此,就可以将上述两步结合在一起执行了,其效果如下所示:
tmp]# mkdir /tmp/mytest1 tmp]# ls /etc/ | egrep '^p.*[^[:alpha:]]$' | xargs -i cp -rf /etc/{} /tmp/mytest1/ tmp]# ls /tmp/mytest1/ passwd- pkcs11 polkit-1
从上述输出可以看出,此处就可以通过一行命令将/etc/目录下的以p开头且以非字母解为的文件或者目录拷贝到/tmp/mytest1这个目录中了。
1.3. 通过tr命令实现文本内容的大小写转换
要求:将/etc/issue文件的内容转换为大写之后保存到/tmp/issue.out中
方案:通过cat
命令将/etc/issue文件的内容写入到标准输出流中,然后通过管道将标准输出流传递给tr
命令进行大小写转换。
tr
命令进行大小写转换的命令使用形式为tr [a-z] [A-Z]
表示将标准输出流中传递给tr命令的内容从小写字母转换为大写字母。具体效果如下所示:
tmp]# cat /etc/issue \S Kernel \r on an \m tmp]# cat /etc/issue | tr 'a-z' 'A-Z' \S KERNEL \R ON AN \M tmp]#
上述即为转换后和转换前的内容,只是写入到标准输出流中,并没有保存到文件/tmp/issue.out这个文件中。
将上述的转换结果保存到文件中,具体如下所示:
tmp]# cat /etc/issue | tr 'a-z' 'A-Z' > /tmp/issue.out tmp]# cat /tmp/issue.out \S KERNEL \R ON AN \M tmp]#
上述即为进行转换之后的结果。
2. Linux用户、组的权限管理
这部分主要分为两部分内容,第一部分为用户和组的管理命令;第二部分为这些命令的2个综合使用示例。
2.1. 用户和组管理相关命令的用法
这部分分为4块内容来介绍,分别为:用户管理相关的命令、组管理相关的命令、提权命令以及查询登录系统的用户相关命令。
2.1.1. 用户管理相关的命令,主要有如下几种:
-
useradd
:用于向系统中添加用户该命令的使用形式为:
useradd [-u uid] [-g initial_login_group] [-G supplementary_groups] [-mM] [-d /path/to/home] [-s shell] username
上述命令的选项参数解释如下:
-
-u uid
:通过-u选项指定新建用户的uid,系统账户在CentOS6.x以前的发行版中默认是使用1-499作为有效的uid,一般用户则是使用500以后的数字作为有效的uid;这种情况在CentOS7.x中发生了改变,系统账户使用的有效uid范围扩大为1-999,而一般用户的uid有效范围则为1000以后的数字。无论在哪个发行版中,root用户作为超级管理员,其uid默认总是0。 -
-g initial_login_group
:通过-g选项指定新建用户的初始登录组,即该用户所属的主组,该选项的值只能有1个,可以是组名,也可以是gid,表示该用户登录系统之后,创建文件或者目录时,文件或者目录的属组,就是由这个参数决定的。 -
-G supplementary_groups
:通过-G选项指定新建用户的附属组,该选项的值可以有多个,各个选项值之间用英文半角逗号分隔,逗号前后无空格。附属组用于实现组级别的权限划分,新用户创建文件或者目录的所属组并不由这个属性值决定,该属性值指定的组表示新建用户对于指定的组具有或者不具有某种权限。 -
-m
:该选项不带选项值,表示创建为新建用户创建家目录,对于一般用户,家目录默认为/home目录下的用户名同名的子目录。 -
-M
:该选项同样不带选项值,表示不为新建用户创建家目录。 -
-d /path/to/home
:该选项接一个路径作为选项值,路径表示家目录创建的位置,该目录指定的路径作为新建用的家目录,不会在该目录下创建用户同名的子目录。 -
-r
:该选项同样不接选项值,表示创建一个系统账户。 -
-s shell
:该选项接一个shell解释器的路径作为参数,表示用户所具有的默认登录的shell解释器是什么,默认时/bin/bash。可用的shell解释器参见/etc/shells这个文件中记录的内容,具体如下所示:~]# cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/bash /usr/bin/bash /bin/rbash /usr/bin/rbash /bin/dash /usr/bin/dash /usr/bin/tmux /usr/bin/screen
上述输出中,记录的shell解释器,除了/bin/bash之外,还有其他几种。
-
-
passwd
:用于设置用户的密码该命令的使用形式为:
passwd [--stdin] options username
常用的选项参数解释如下:
--stdin
:通常与echo
命令组合使用,将密码用echo命令打印到标准输出,然后通过管道传递给passwd --stdin
命令,通过–stdin将echo命令的标准输出流的内容作为passwd命令的标准输入流来替代手动交互式输入密码的过程。这个选项在批量创建用户并自动设置默认初始密码的时候很有用。不过这个选项在Ubuntu系统上并没有得到支持,而在CentOS/RHEL系列发行版上是能够被支持的。-l
:该选项只能被root用户使用,通过将/etc/passwd文件中对应用用户的记录密码的字段设置为不可用状态来达到锁定用户的目的。注意,这种锁定并不会导致用户完全无法登录系统,比如被锁定的用户仍然可以通过ssh的公钥验证远程登录系统。要实现用户的完全锁定,可以执行命令chage -E 0 username
将username这个用户完全锁定,使其完全无法登录系统。-u
:与-l
选项意义相反,表示解锁用户,使用户可以在本地登录系统。-n minium_days
:表示用户密码的最短生命周期,即不提示修改密码的最短天数。-x maximum_days
:表示用户密码的最长生命周期,即不提示修改密码的最长天数。-w warning_days
:表示用户即将接收到密码生命周期即将完结的警告信息的天数。-i inactive_days
:表示用户的密码失效的天数。
-
chage
:用于修改用户密码的过期相关信息该命令的使用形式为:
chage [-ldEImMW]
选项参数解释如下:
-l
:显示账户的密码过期等相关日期信息-d LAST_DAY
:设置最近一次修改密码的日期,可以接YYYY-MM-DD的日期格式,如果LAST_DAY被设置为0,表示强制用户下次登录系统的时候更改密码。-E EXPIRE_DAY
:指定账户的失效日期,可以接YYYY-MM-DD的日期格式,该日期之后,账号进入锁定状态,此时如果需要再次使用该账户,就联系系统管理员。比如设置当前账户180天之后过期进入锁定状态,可以执行命令chage -E $(date -d +180days +%Y-%m-%d)
。-I INACTIVE
:密码失效日期,选项值为天数。-m MIN_DAYS
:密码保留的最小天数。如果将MIN_DAYS的值设置为0,则表示用户可以随时修改其密码。-M MAX_DAYS
:设置密码的最大有效期限,当MAX_DAYS+LAST_DAY的值小于当前日期的时候,就要求用户修改密码之后才能正常使用该账户。-W WARN_DAYS
:要求更改密码前的警告日期。
-
usermod
:用于修改用户账户的信息该命令的使用形式为:
usermod [-degGlsuLU] username
其选项参数解释如下:
-d HOME_DIR
:表示修改用户的家目录-e EXPIRE_DATE
:表示用户被禁用的日期,格式为YYYY-MM-DD-g GROUP
:表示修改用户的初始登录组,即主组,GROUP可以是组名,也可以是gid-G GROUPS
:表示修改用户的附属组,GROUPS可以是英文半角逗号分隔的多个组,可以是组名,也可以是gid-a
:与-G
选项结合使用,表示给该用户增加附属组,-a表示append,-G表示指定用户的附属组都有哪些。如果不指定-a,单独指定-G选项,原有的附属组会被新指定的值替代掉-l NEW_LOGIN
:表示修改用户的登录名,即登录系统的用户名,效果为修改账户名称-s shell
:表示修改用户的shell解释器-u UID
:表示修改用户的uid数值-L
:表示在那时冻结用户的密码,使其无法在本地登录,但是仍然可以通过ssh的公钥验证进行远程登录-U
:与-L
选项相对,表示解冻用户的密码,使其可以在本地登录
-
userdel
:删除用户该命令的使用形式为:
userdel [-r] username
其选项参数解释如下:
-r
:表示连同用户的家目录一起删除
-
id
:打印真实有效的用户和组信息该命令的使用形式为:
id [username]
其选项参数解释如下:
-g
:只打印gid-G
:打印所有的gid-n
:以名字的形式打印,而不是以id的形式打印-u
:只打印uid-r
:打印real ID而不是打印effective ID
-
chsh
:用于更改登录shell该命令的使用形式为:
chsh [-ls]
其选项参数解释如下:
-l
:列出系统上当前支持的所有shell解释器,与/etc/shells文件中记录的内容一致-s
:修改自己的shell解释器
2.1.2. 组管理相关的命令,主要有如下几种:
-
groupadd
:创建一个新的组该命令的使用形式为:
groupadd [-g gid] [-r] group_name
其选项参数解释如下:
-g gid
:表示给新建的组指定GID-r
:表示创建的组为系统账户组
-
groupmod
:修改系统的组定义信息该命令的使用形式为:
groupmod [-g gid] [-n group_name] grouop_name
其选项参数解释如下:
-g gid
:将当前的gid修改为该选项指定的gid值-n group_name
:将当前的组名修改为该选项指定的组名
-
groupdel
:删除系统上存在的组该命令的使用形式为:
groupdel groupname
其选项参数解释如下:
删除指定组名的组
-
gpasswd
:管理/etc/group和/etc/shadow该命令的使用形式为:
gpasswd groupname
:修改组密码gpasswd [-A user1,user2...] [-M user3,user4...] groupname
:指定组管理员并向改组中添加用户gpasswd [-rR] groupname
:将组密码移除或者让其失效
其选项参数解释如下:
-A user1,user2...
:将groupname这个组的管理权限交给该选项指定的用户-M user3,user4...
:将该选项指定的用户加入到groupname这个组中-r
:将groupname的密码删除-R
:将组密码设置为失效,限制对改组的访问
Linux上的每个用户组都可以由管理员、成员以及一个组密码。系统管理员可以使用-A选项指定用户组的管理员,并且可以通过-M选项指定改组的成员有哪些。
2.1.3. 提权
-
su
:switch user的缩写,表示切换用户身份,以其他用户什么执行操作该命令的使用形式为:
su [-lm] [-c command] [username]
其选项参数解释如下:
-
:单纯使用-,比如su -
表示使用login-shell的环境变量文件读取方式来登录系统-l
:与单纯使用-的效果类似,后面需要加上想要切换的账户名称,也是以login-shell的形式登录系统-m
:表示使用当前的环境变量,而不去读取切换的目标用户的环境变量-c command
:表示仅使用该用户身份执行一次命令,而不进行用户身份的切换
-
sudo
:以其他用户的身份执行命令该命令的使用形式为:
sudo [-b] [-u new_user]
其选项参数解释如下:
-b
:表示将执行的命令放在后台让系统自动执行,从而不对当前的shell产生影响,此处放到后台执行的命令是不受shell的jobs
命令控制的-u new_user
:表示想要切换的目标用户的用户名,如果无此选项,表示切换为root账户
2.1.4. 查询登录用户
w
:用于查看当前系统的登录用户,以及他们正在做什么who
:显示当前登录系统的用户last
:显示最近登录的用户lastlog
:报告所有用户或者给定用户的最近登录报告
2.2. 两个用户和组管理的综合示例
2.2.1. 用户和组的创建以及密码管理
-
创建一个名为distro的组,gid为2019
该步操作的命令为:
groupadd -g 2019 distro
-
创建一个名为mandriva的用户,uid为1005,初始登录组为distro
该步操作的命令为:
[root@ubuntu20u04:~]# useradd -u 1005 -g distro mandriva [root@ubuntu20u04:~]# id mandriva uid=1005(mandriva) gid=2019(distro) groups=2019(distro)
-
创建一个名为mageia的用户,uid为1100,家目录为/home/linux
该步操作的命令为:
[root@ubuntu20u04:~]# useradd -u 1100 -m -d /home/linux mageia [root@ubuntu20u04:~]# id mageia uid=1100(mageia) gid=1100(mageia) groups=1100(mageia) [root@ubuntu20u04:~]# ls /home/linux/ -d /home/linux/ [root@ubuntu20u04:~]# egrep mageia /etc/passwd mageia:x:1100:1100::/home/linux:/bin/sh
-
为mageia这个用户设置密码,密码为mageedu,并设置密码7天后过期
该步操作的命令为:
[root@ubuntu20u04:~]# passwd -i 7 mageia passwd: password expiry information changed. [root@ubuntu20u04:~]# passwd mageia New password: Retype new password: passwd: password updated successfully [root@ubuntu20u04:~]# chage -I 7 mageia [root@ubuntu20u04:~]# chage -l mageia Last password change : Mar 28, 2021 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 [root@ubuntu20u04:~]#
-
删除mandriva这个用户,保留其家目录
该步操作的命令为:
[root@ubuntu20u04:~]# userdel mandriva [root@ubuntu20u04:~]# ls -d /home/mandriva /home/mandriva
-
创建一个名为slackware的用户,uid为2002,初始登录组为distro,附属组为peguin
该步操作的命令为:
[root@ubuntu20u04:~]# groupadd peguin [root@ubuntu20u04:~]# useradd -u 2002 -g distro -G peguin slackware [root@ubuntu20u04:~]# id slackware uid=2002(slackware) gid=2019(distro) groups=2019(distro),2021(peguin) [root@ubuntu20u04:~]# grep slackware /etc/passwd slackware:x:2002:2019::/home/slackware:/bin/sh
-
将slackware用户的默认shell修改为/bin/tcsh
该步操作的命令为:
[root@ubuntu20u04:~]# usermod -s /bin/tcsh slackware [root@ubuntu20u04:~]# grep slackware /etc/passwd slackware:x:2002:2019::/home/slackware:/bin/tcsh
-
将admins这个组设置为slackware用户的附属组,并将其设置为不可登录
该步操作的命令为:
[root@ubuntu20u04:~]# groupadd admins [root@ubuntu20u04:~]# usermod -a -G admins -s /sbin/nologin slackware [root@ubuntu20u04:~]# grep slackware /etc/passwd slackware:x:2002:2019::/home/slackware:/sbin/nologin [root@ubuntu20u04:~]# id slackware uid=2002(slackware) gid=2019(distro) groups=2019(distro),2021(peguin),2022(admins)
2.2.2. 用户和组的权限管理
-
创建user1, user2, user3三个用户,并在/data目录下创建子目录test
该步操作的命令为:
[root@ubuntu20u04:~]# for u in user{1..3}; do useradd $u; done [root@ubuntu20u04:~]# for u in user{1..3}; do id $u; done uid=2021(user1) gid=2023(user1) groups=2023(user1) uid=2022(user2) gid=2024(user2) groups=2024(user2) uid=2023(user3) gid=2025(user3) groups=2025(user3) [root@ubuntu20u04:~]# mkdir -p /data/test [root@ubuntu20u04:~]# ls -d /data/test /data/test [root@ubuntu20u04:~]#
-
将目录/data/test的所有者、所属组设置为user1
该步操作的命令为:
[root@ubuntu20u04:~]# chown -R user1.user1 /data/test [root@ubuntu20u04:~]# ls -dl /data/test drwxr-xr-x 2 user1 user1 6 Mar 28 16:16 /data/test
-
保持/data/test用户的所有者和所属组权限不变,使得user2对该目录具有读写权限
该步操作的命令为:
[root@ubuntu20u04:~]# setfacl -R -m u:user2:rw /data/test [root@ubuntu20u04:~]# getfacl /data/test getfacl: Removing leading '/' from absolute path names # file: data/test # owner: user1 # group: user1 user::rwx user:user2:rw- group::r-x mask::rwx other::r-x
-
user1在/data/test目录下创建4个文件,分别为:a1.sh, a2.sh, a3.sh, a4.sh,并且设置所有用户都不可删除a1.sh和a2.sh,以及除了user1和root之外,所有用户都不可删除a3.sh和a4.sh
该步操作的命令为:
user1@ubuntu20u04:/data/test$ touch a{1..4}.sh user1@ubuntu20u04:/data/test$ ls -a . .. a1.sh a2.sh a3.sh a4.sh user1@ubuntu20u04:/data/test$ ls -l total 0 -rw-rw-r-- 1 user1 user1 0 Mar 28 16:25 a1.sh -rw-rw-r-- 1 user1 user1 0 Mar 28 16:25 a2.sh -rw-rw-r-- 1 user1 user1 0 Mar 28 16:25 a3.sh -rw-rw-r-- 1 user1 user1 0 Mar 28 16:25 a4.sh user1@ubuntu20u04:/data/test$ chattr +i a1.sh a2.sh chattr: Operation not permitted while setting flags on a1.sh chattr: Operation not permitted while setting flags on a2.sh user1@ubuntu20u04:/data/test$ lsattr a2.sh -------------------- a2.sh user1@ubuntu20u04:/data/test$ exit logout [root@ubuntu20u04:/data/test]# chattr +i a1.sh a2.sh [root@ubuntu20u04:/data/test]# lsattr a1.sh a2.sh ----i--------------- a1.sh ----i--------------- a2.sh [root@ubuntu20u04:/data/test]# [root@ubuntu20u04:/data/test]# rm a1.sh rm: cannot remove 'a1.sh': Operation not permitted [root@ubuntu20u04:/data/test]# rm -f a2.sh rm: cannot remove 'a2.sh': Operation not permitted [root@ubuntu20u04:/data/test]#
至于只有user1和root能删除a3.sh和a4.sh这两个文件,只需要将/data/test目录的权限设置为其他用户无写入权限即可,因为文件的删除是需要目录的写入权限的。拿掉目录的其他用户权限位的写入权限,就可以使除了root用户以及该目录的所有者之外的其他人无法删除a3.sh和a4.sh这两个文件。
[root@ubuntu20u04:/data/test]# ls -ld . drwxrwxr-x+ 2 user1 user1 58 Mar 28 16:25 .
上述可以看出,test目录的其他人权限位的写入权限默认就被去掉的。
-
为user3这个用户增加附属组user1,同时要求user1不能访问/data/test目录及其下所有文件
该步操作的命令为:
[root@ubuntu20u04:/data]# usermod -a -G user1 user3 [root@ubuntu20u04:/data]# id user3 uid=2023(user3) gid=2025(user3) groups=2025(user3),2023(user1) [root@ubuntu20u04:/data/test]# chown -R user3.user3 . [root@ubuntu20u04:/data/test]# setfacl -m u:user1:- ${PWD} [root@ubuntu20u04:/data/test]# getfacl ${PWD} getfacl: Removing leading '/' from absolute path names # file: data/test # owner: user3 # group: user3 user::rwx user:user1:--- user:user2:rw- group::r-x mask::rwx other::r-x default:user::rwx default:group::r-x default:mask::r-x default:other::r-x user1@ubuntu20u04:~$ cd /data/test -bash: cd: /data/test: Permission denied user1@ubuntu20u04:~$
-
清理/data/test目录以及其下所有文件的acl权限
该步操作的命令为:
[root@ubuntu20u04:/data/test]# setfacl -b ${PWD} [root@ubuntu20u04:/data/test]# getfacl ${PWD} getfacl: Removing leading '/' from absolute path names # file: data/test # owner: user3 # group: user3 user::rwx group::r-x other::r-x [root@ubuntu20u04:/data/test]#