马哥Linux培训课堂笔记(4)

2017-11-17|Categories: Magedu-training|

以下内容主要按照在课堂讲述的顺序记录,有适当整理和延伸,便于回顾复习。

重要知识点

id vs id

  • id:从系统读取当前用户的登录身份信息
  • id <user_name>:从文件读取指定用户的身份信息

登录身份信息(尤其是uid)是用户在登录系统时获取,即使在登录期间被强制修改,也必须等到注销并重新登录之后才会生效:

# `id`不带参数:从系统读取当前用户登录身份信息
[root@centos7 ~] id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# `id <user_name>`:从文件读取指定用户身份信息
[root@centos7 ~] id root
uid=0(root) gid=0(root) groups=0(root)

# `usermod -u`无法修改已登录用户的uid
[root@centos7 ~] usermod -u 1234 root
usermod: user root is currently used by process 1

# 直接从`/etc/passwd`修改root的uid
[root@centos7 ~] vim /etc/passwd
[root@centos7 ~] head -n1 /etc/passwd
root:x:1234:0:root:/root:/bin/bash

# 再次用`id`读取,找不到`uid=0`对应的用户名,其它信息未变
[root@centos7 ~] id
uid=0 gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# 再次用`id <user_name>`:root的uid已经改变
[root@centos7 ~] id root
uid=1234(root) gid=0(root) groups=0(root)

执行权限x的用途

目录

如果用户对某个目录没有x权限:

  • 无法cd进入目录。
  • 无法读取目录所包含文件的元数据,只能查看到包含的文件名。
# 更改`/app`目录权限:others=r
[root@centos7 ~] chmod o=r /app

[root@centos7 ~] su - test
Last login: Sat Nov 18 15:48:26 CST 2017 on pts/1

# test用户对`/app`目录仅有r权限,
# 可以读取目录包含的文件列表,但无法读取文件元数据
[test@centos7 ~]$ ll -d /app /app/*
ls: cannot access /app/file01: Permission denied
ls: cannot access /app/file02: Permission denied
ls: cannot access /app/file03: Permission denied
ls: cannot access /app/file04: Permission denied
ls: cannot access /app/file05: Permission denied
ls: cannot access /app/file06: Permission denied
ls: cannot access /app/file07: Permission denied
ls: cannot access /app/file08: Permission denied
ls: cannot access /app/file09: Permission denied
ls: cannot access /app/file10: Permission denied
drwxr-xr--. 2 root root 146 Nov 18 15:46 /app

# test用户无法`cd`进入`/app`目录
[test@centos7 ~]$ cd /app
-bash: cd: /app: Permission denied
# 更改`/app`目录权限:others=x
[root@centos7 ~] chmod o=x /app

[root@centos7 ~] su - test
Last login: Sat Nov 18 15:50:54 CST 2017 on pts/1

# test用户可以进入`/app`
[test@centos7 ~]$ cd /app

# test无法读取目录文件列表
[test@centos7 app]$ ls -l
ls: cannot open directory .: Permission denied
[test@centos7 app]$ ls -l *
ls: cannot access *: No such file or directory

# 但在知道文件名的情况下,可以读取文件元数据
[test@centos7 app]$ ls -l /app/file{01..10}
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file01
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file02
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file03
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file04
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file05
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file06
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file07
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file08
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file09
-rw-r--r--. 1 root root 0 Nov 18 15:46 /app/file10

基于以上两个小实验,可以发现,如果要让一个用户能够正常操作目录,也就是读取文件列表及每个文件对应的元数据,至少要授予rx两个权限。

普通文件

如果用户对某个文件没有x权限,将无法执行该文件,即使root用户也一样

二进制文件

只要用户对某个二进制文件拥有x权限,即使没有rw两种权限,也可以执行该文件。

# 添加一个临时用户test
[root@centos7 ~] useradd test

# 让`others`用户仅对二进制文件`/bin/ls`拥有执行权限
[root@centos7 ~] chmod o=x /bin/ls
[root@centos7 ~] ls -l /bin/ls
-rwxr-x--x. 1 root root 117656 Nov  6  2016 /bin/ls

# 切换到test用户
[root@centos7 ~] su - test
# 检查test登录时获取的身份
[test@centos7 ~]$ id
uid=1001(test) gid=1001(test) groups=1001(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# test没有`/bin/ls`的rw权限,但可以执行
[test@centos7 ~]$ ls -l /bin/ls
-rwxr-x--x. 1 root root 117656 Nov  6  2016 /bin/ls

涉及的命令

newgrp

切换当前登录用户的group ID:

# 把test用户追加到liyang组
[root@centos7 ~] usermod -aG liyang test
# 确认test用户的新身份信息
[root@centos7 ~] id test
uid=1001(test) gid=1001(test) groups=1001(test),1000(liyang)

# 切换到test用户
[root@centos7 ~] su - test
# 确认身份信息:gid=1001
[test@centos7 test]$ id
uid=1001(test) gid=1001(test) groups=1001(test),1000(liyang) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 新建一个文件file1
[test@centos7 test]$ touch file1
# file1的所属组是test
[test@centos7 test]$ ll file1
-rw-rw-r--. 1 test test 0 Nov 19 21:08 file1

# 把group ID切换到liyang
[test@centos7 test]$ newgrp liyang
# 确认新身份信息:gid=1000
[test@centos7 test]$ id
uid=1001(test) gid=1000(liyang) groups=1000(liyang),1001(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 新建一个文件file2
[test@centos7 test]$ touch file2
# file2的所属组是liyang
[test@centos7 test]$ ll file2
-rw-r--r--. 1 test liyang 0 Nov 19 21:10 file2

切换回默认的group ID也很简单:

[root@centos7 ~] su - test
Last login: Sun Nov 19 21:08:04 CST 2017 on pts/0

[test@centos7 ~]$ id
uid=1001(test) gid=1001(test) groups=1001(test),1000(liyang) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

[test@centos7 ~]$ newgrp liyang

[test@centos7 ~]$ id
uid=1001(test) gid=1000(liyang) groups=1000(liyang),1001(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# 切换回默认的group ID
[test@centos7 ~]$ exit
exit

[test@centos7 ~]$ id
uid=1001(test) gid=1001(test) groups=1001(test),1000(liyang) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

vipw & vigr

man vipw:

vipw, vigr – edit the password, group, shadow-password or shadow-group file

The vipw and vigr commands edits the files /etc/passwd and /etc/group, respectively. With the -s flag, they will edit the shadow versions of those files, /etc/shadow and /etc/gshadow, respectively. The programs will set the appropriate locks to prevent file corruption. When looking for an editor, the programs will first try the environment variable $VISUAL, then the environment variable $EDITOR, and finally the default editor, vi(1).

在全新安装的CentOS 7系统上,默认的编辑器是vi,我喜欢功能更强大的vim,所以我在~/.bashrc做了如下设置:

export EDITOR=vim

pwck & grpck

man pwck:

pwck – verify integrity of password files

The pwck command verifies the integrity of the users and authentication information. It checks that all entries in /etc/passwd and /etc/shadow have the proper format and contain valid data.

man grpck:

grpck – verify integrity of group files

The grpck command verifies the integrity of the groups information. It checks that all entries in /etc/group and /etc/gshadow have the proper format and contain valid data.

useradd

# 新建用户ghost
[root@centos7 ~] useradd -u 1001 -o -N -d /app/ghost ghost
# `-o, --non-unique`:允许创建一个与现有uid重复的用户,仅在与`-u`搭配时有效
# `-N, --no-user-group`:不创建同名用户组,而是添加到`-g`指定的组,或是`/etc/default/useradd`文件中`GROUP`变量指定的组
# `-d, --home-dir`:指定家目录

# 因uid与test用户相同,ghost用户被系统完全当成了test用户
[root@centos7 ~] id ghost
uid=1001(test) gid=1001(test) groups=1001(test),1000(liyang)

# 实际上ghost用户在`/etc/passwd`里是一个独立的条目
[root@centos7 ~] getent passwd ghost
ghost:x:1001:100::/app/ghost:/bin/bash

# ghost用户的家目录的owner是test,group是users
[root@centos7 ~] ll -d /app/ghost/
drwx------. 3 test users 78 Nov 19 21:35 /app/ghost/

groupmems

# 把liyang用户添加到test组
[root@centos7 ~] groupmems -a liyang -g test
[root@centos7 ~] id liyang
uid=1000(liyang) gid=1000(liyang) groups=1000(liyang),1001(test)

# 列出liyang组的成员
[root@centos7 ~] groupmems -l -g liyang
liyang  test
# 列出test组的成员
[root@centos7 ~] groupmems -l -g test
liyang

# 把test组的成员清空
[root@centos7 ~] groupmems -p -g test
# 确认liyang用户已从test组被清除
[root@centos7 ~] id liyang
uid=1000(liyang) gid=1000(liyang) groups=1000(liyang)

技巧

反查某个用户修改密码的时间

# `getent shadow`其实就是读取`/etc/shadow`
# 第三个字段就是修改密码的日期相对于1970-01-01的天数
[root@centos7 ~] getent shadow root
root:$6$MpyNkIBY$rmioye7HoDqBFObugx48eBwvJGIBfOEnUL4QmtMSe/CzdC9fkKBnApzp5HgRFn2zVKfgYEgvUBG4WKsmmWDtA1:17487:0:99999:7:::

# `date`可以把Unix时间(相对于1970-01-01 0:00:00的秒数)转化为UTC时间
# 每一天有`24*60*60=86400`秒
[root@centos7 ~] date -u -d @`echo 17487*86400 | bc`
Fri Nov 17 00:00:00 UTC 2017

删除root用户之后无法开机的恢复方法

手工修改/etc/passwd中root的uid不为0之后,重启系统会失败:

此时必须从安装光盘启动来修复,以CentOS 7为例:

  • 在BIOS(真实机器)或虚拟机设置从安装光盘启动;
  • 选择Troubshooting菜单,按回车键;
  • 选择Rescue a CentOS system,按回车键;
  • 看到Rescue菜单之后,输入1将损坏系统的根目录挂载到/mnt/sysimage,挂载模式为rw

  • chroot /mnt/sysimage/mnt/sysimage作为/目录

  • (可选步骤)验证是否可读写

    • 通过lsblk找出当前/上挂载的分区;
    • mount | grep sda2,输出有rw即可。

  • 修改/etc/passwd

    • uid改回0;
    • (可选)清空密码字段;
    • 建议使用vipw命令,改完可以检查语法。
  • (可选)修改/etc/shadow,清空密码字段;

  • 输入两次exit,系统自动重启;

  • BIOS改为从硬盘启动,系统重启成功,表示root用户恢复成功。

完成以上步骤之后,为了做笔记截图,我再次从光盘启动,挂载根分区,但未修改任何文件,截完图重启居然失败了,出现Failed to load SELinux policy, freezing.错误,具体原因未知,最终通过以下方式修复:

  • e编辑GRUB启动菜单(光标不要选中包含rescue的菜单项);

  • linux16这一行末尾添加selinux=0,在启动过程中禁用SELinux,按ctrl-x重启;

  • 系统重启成功;

  • 重新安装默认的SELinux策略:yum reinstall selinux-policy-targeted

  • 强制系统在下次重启时重新标记所有文件的SELinux context:touch /.autorelabel

  • 重新启动:reboot

批量添加用户、修改密码、删除用户

# 用于批量添加用户的文本文件
[root@centos7 ~] cat batch_add_users.txt
batch01::1002:1002::/home/batch01:/bin/bash
batch02::1003:1003::/home/batch02:/bin/bash
batch03::1004:1004::/home/batch03:/bin/bash
batch04::1005:1005::/home/batch04:/bin/bash
# 批量添加用户
[root@centos7 ~] newusers batch_add_users.txt
# 确认批量添加已成功
[root@centos7 ~] getent passwd | grep batch
batch01:x:1002:1002::/home/batch01:/bin/bash
batch02:x:1003:1003::/home/batch02:/bin/bash
batch03:x:1004:1004::/home/batch03:/bin/bash
batch04:x:1005:1005::/home/batch04:/bin/bash

# 用于批量修改密码的文本文件
[root@centos7 ~] cat batch_change_passwd.txt
batch01:Batch01pw
batch02:Batch02pw
batch03:Batch03pw
batch04:Batch04pw
# 批量修改密码
[root@centos7 ~] cat batch_change_passwd.txt | chpasswd
# 检查当前时间
[root@centos7 ~] date
Sun Nov 19 19:27:49 CST 2017
# 检查密码文件修改时间
[root@centos7 ~] ll /etc/shadow
----------. 1 root root 1.9K Nov 19 19:27 /etc/shadow

# 用于批量删除用户的文本文件
[root@centos7 ~] cat user_list.txt
batch01
batch02
batch03
batch04
# 批量删除用户
[root@centos7 ~] cat user_list.txt | xargs -n1 userdel -r
userdel: batch01 mail spool (/var/spool/mail/batch01) not found
userdel: batch02 mail spool (/var/spool/mail/batch02) not found
userdel: batch03 mail spool (/var/spool/mail/batch03) not found
userdel: batch04 mail spool (/var/spool/mail/batch04) not found
# 确认批量删除的结果
[root@centos7 ~] getent passwd | grep batch
[root@centos7 ~] getent shadow | grep batch
[root@centos7 ~] ls -l /home | grep batch

用户、组改名

# 给组改名
[root@centos7 ~] groupmod -n testgrp test
[root@centos7 ~] id test
uid=1001(test) gid=1001(testgrp) groups=1001(testgrp),1000(liyang)

# 给用户改名
[root@centos7 ~] usermod -l testuser test
[root@centos7 ~] id testuser
uid=1001(testuser) gid=1001(testgrp) groups=1001(testgrp),1000(liyang)

参考某个文件的权限,给其它文件相同权限

# 新建的5个文件权限都是664
[test@centos7 test]$ touch file{01..05}
[test@centos7 test]$ ls -l
total 0
-rw-rw-r--. 1 test test 0 Nov 19 19:56 file01
-rw-rw-r--. 1 test test 0 Nov 19 19:56 file02
-rw-rw-r--. 1 test test 0 Nov 19 19:56 file03
-rw-rw-r--. 1 test test 0 Nov 19 19:56 file04
-rw-rw-r--. 1 test test 0 Nov 19 19:56 file05

# 把file01权限改为755
[test@centos7 test]$ chmod 755 file01
[test@centos7 test]$ ls -l file01
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file01

# 参考file01的权限,把其它4个文件的权限改成和file01一样
[test@centos7 test]$ chmod --reference=file01 file{02..05}
[test@centos7 test]$ ls -l
total 0
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file01
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file02
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file03
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file04
-rwxr-xr-x. 1 test test 0 Nov 19 19:56 file05

将执行权限只授予目录,不授予文件

# 创建目录和文件
[test@centos7 test]$ mkdir dir{1..2}
[test@centos7 test]$ touch dir{1..2}/file{1..2}
# 列出所有目录和文件的权限
[test@centos7 test]$ ll -R
.:
total 0
drwxrwxr-x. 2 test test 32 Nov 19 20:20 dir1
drwxrwxr-x. 2 test test 32 Nov 19 20:20 dir2

./dir1:
total 0
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file1
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file2

./dir2:
total 0
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file1
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file2

# 目录只保留owner的x权限
[test@centos7 test]$ chmod g-x,o-x dir*
# 授予x权限给dir2目录下文件的owner
[test@centos7 test]$ chmod u+x dir2/*
# 修改后的权限
[test@centos7 test]$ ll -R
.:
total 0
drwxrw-r--. 2 test test 32 Nov 19 20:20 dir1
drwxrw-r--. 2 test test 32 Nov 19 20:20 dir2

./dir1:
total 0
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file1
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file2

./dir2:
total 0
-rwxrw-r--. 1 test test 0 Nov 19 20:20 file1
-rwxrw-r--. 1 test test 0 Nov 19 20:20 file2

# 授予所有目录和文件X权限(注意是**大写的X**)
[test@centos7 test]$ chmod -R a+X *
[test@centos7 test]$ ll -R
# 所有目录的group和other都增加了x权限
.:
total 0
drwxrwxr-x. 2 test test 32 Nov 19 20:20 dir1
drwxrwxr-x. 2 test test 32 Nov 19 20:20 dir2
# dir1目录的文件没有获取x权限
./dir1:
total 0
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file1
-rw-rw-r--. 1 test test 0 Nov 19 20:20 file2
# dir2目录的文件的group和other都增加了x权限
./dir2:
total 0
-rwxrwxr-x. 1 test test 0 Nov 19 20:20 file1
-rwxrwxr-x. 1 test test 0 Nov 19 20:20 file2

通过man chmod可以看到:

execute/search only if the file is a directory or already has execute permission for some user (X)

也就是说,+X只会授予目录或某些用户已经拥有x权限的文件全部执行权限,对于那些没有任何用户有执行权限的文件,+X仍然不会授予执行权限。

Leave A Comment