第 2 章 Linux 系统用户

作者: Brinnatt 分类: ARM64 Linux 基础精修 发布时间: 2022-01-20 14:46

用户和组是操作系统中一种身份认证资源。

用户,都有用户名、用户的唯一编号 uid(user id)、所属组及其默认的 shell,可能还有密码、家目录、附属组、注释信息等。

,也有自己的名称、组唯一编号 gid(group id)。组分为主组(primary group)和辅助组(secondary group)两种,用户一定会属于某个主组,也可以同时加入多个辅助组。

Linux 有 3 种用户:

  1. 超级管理员

    超级管理员是最高权限者,它的 uid=0,默认超级管理员用户名为 root。超级管理员默认只能有一个。

  2. 系统用户

    有时候需要一类具有某些特权但又不需要登录操作系统的用户,这类用户称为系统用户。Centos 7+ uid 范围从 201 到 999。Centos 6- uid 范围是 1 到 499。出于安全考虑,它们一般不用来登录,所以它们的shell一般是 /sbin/nologin,而且大多数时候它们是没有家目录的。

  3. 普通用户

    普通用户是权限受到限制的用户,默认只能执行 /bin、/usr/bin、/usr/local/bin 和自身家目录下的命令。它们的 uid 从 1000 开始。尽管普通用户权限收到限制,但是它对自身家目录下的文件是有所有权限的。

uid=0 的超级管理员,命令提示符是 "#",其他的为 "$"。

默认 root 用户的家目录为 /root,其他用户的家目录一般在 /home 下以用户名命名的目录中。家目录可以自定义位置和名称。

2.1、用户和组相关文件

2.1.1、用户文件

/etc/passwd 文件里记录的是操作系统中用户的信息,这里面记录了几行就表示系统中有几个用户。它的格式大致如下:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
python:x:1000:1000::/home/python:/bin/bash

用户名 : x : uid : gid : 用户注释信息 : 家目录 : 使用的 shell 类型

  • 第一列:用户名。注意两个个特殊的用户名,root、nobody
  • 第二列:x,在以前老版本的系统上,第二列是存放用户密码的,但是密码和用户信息放在一起不便于管理(密钥要保证其特殊属性),所以后来将密码单独放在另一个文件 /etc/shadow 中,这里就都写成x了
  • 第三列:uid
  • 第四列:gid
  • 第五列:用户注释信息。
  • 第六列:用户家目录。注意 root 用户的家目录为 /root
  • 第七列:用户的默认 shell,虽然叫 shell,但其实可以是任意一个可执行程序或脚本。例如上面的 /bin/bash、/sbin/nologin、/sbin/shutdown

用户的默认 shell 表示的是用户登录(如果允许登录)时的环境或执行的命令。

shell 为 /bin/bash 时,表示登录时就执行 /bin/bash 命令进入 bash 环境。

shell 为 /sbin/nologin 表示该用户不能登录,之所以不能登录不是因为指定了这个特殊的程序,而是由 /sbin/nologin 这个程序的功能实现的。

2.1.2、密码文件

/etc/shadow 文件中存放的是用户的密码信息。该文件具有特殊属性,除了超级管理员,任何人都不能直接读取和修改该文件,而用户自身之所以能修改密码,则是因为 passwd 程序的 suid 属性,使得修改密码时临时提升为 root 权限。

该文件的格式大致如下:

root:$6$SELV0CfK0HK7Llac$gK1WevRicfGlijDSNFGFIDzdjoHUCYFBaUDifCdaWDDVstc/iuRIPyBxhLJ9rG0cZZ7qLnTKkfEZSPpiz3X9E0::0:99999:7:::
bin:*:17632:0:99999:7:::
daemon:*:17632:0:99999:7:::

每一行表示一个用户密码的属性,有 8 个冒号共 9 列属性。

  • 第一列:用户名。
  • 第二列:加密后的密码。但是这一列是有玄机的,有些特殊的字符表示特殊的意义。
    • 该列留空,即 "::",表示该用户没有密码。
    • 该列为 "!",即 ":!:",表示该用户被锁,被锁将无法登陆,但是可能其他的登录方式是不受限制的,如 ssh key 的方式,su 的方式。
    • 该列为 "*",即 ":*:",也表示该用户被锁,和 "!" 效果是一样的。
    • 该列以 "!" 或 "!!" 开头,则也表示该用户被锁。
    • 该列为 "!!",即 ":!!:",表示该用户从来没设置过密码。
    • 如果格式为 "$id$salt$hashed",则表示该用户密码正常。其中 $id$ 的 id 表示密码的加密算法,$1$ 表示使用 MD5 算法,$2a$ 表示使用 Blowfish 算法,"$2y$" 是另一算法长度的 Blowfish, "$5$" 表示 SHA-256 算法,而 "$6$" 表示 SHA-512 算法,可见上面的结果中都是使用 sha-512 算法的。$5$$6$ 这两种算法的破解难度远高于 MD5。$salt$ 是加密时使用的 salt,$hashed 才是真正的密码部分。
  • 第三列:从 1970 年 1 月 1 日到上次密码修改经过的时间(天数)。通过计算现在离 1970 年 1 月 1 日的天数减去这个值,结果就是上次修改密码到现在已经经过了多少天,即现在的密码已经使用了多少天。
  • 第四列:密码最少使用期限(天数)。省略或者 0 表示不设置期限。例如,刚修改完密码又想修改,可以限制多久才能再次修改。
  • 第五列:密码最大使用期限(天数)。超过了它不一定密码就失效,可能下一个字段设置了过期后的宽限天数。设置为空时将永不过期,后面设置的提醒和警告将失效。root 等一些用户的已经默认设置为了 99999,表示永不过期。如果值设置小于最短使用期限,用户将不能修改密码。
  • 第六列:密码过期前多少天就开始提醒用户密码将要过期。空或 0 将不提醒。
  • 第七列:密码过期后宽限的天数,在宽限时间内用户无法使用原密码登录,必须改密码或者联系管理员。设置为空表示没有强制的宽限时间,可以过期后的任意时间内修改密码。
  • 第八列:帐号过期时间。从 1970 年 1 月 1 日开始计算天数。设置为空帐号将永不过期,不能设置为 0。不同于密码过期,密码过期后账户还有效,改密码后还能登录;帐号过期后帐号失效,修改密码重设密码都无法使用该帐号。
  • 第九列:保留字段。

2.1.3、组文件

大致知道有 /etc/group 和 /etc/gshadow 这两件文件即可。

/etc/group 包含了组信息。每行一个组,每一行 3 个冒号共 4 列属性。

root:x:0:
bin:x:1:
daemon:x:2:
  • 第一列:组名。
  • 第二列:占位符。
  • 第三列:gid。
  • 第四列:该组下的 user 列表,这些 user 成员以该组做为辅助组,多个成员使用逗号隔开。

/etc/gshadow 包含了组密码信息

2.1.4、骨架目录

骨架目录 /etc/skel 中的文件是每次新建用户时,都会复制到新用户家目录里的文件。默认只有 3 个环境配置文件,可以修改这里面的内容,或者添加几个文件在骨架目录中,以后新建用户时就会自动获取到这些环境和文件。

[root@arm64v8 ~]# ll -A /etc/skel/
total 12
-rw-r--r--. 1 root root  18 Apr 11  2018 .bash_logout
-rw-r--r--. 1 root root 193 Apr 11  2018 .bash_profile
-rw-r--r--. 1 root root 231 Apr 11  2018 .bashrc
[root@arm64v8 ~]# 

删除家目录下这些文件,会导致某些设置出现问题。万一删除其中某个文件,只需拷贝一个正常的同名文件到其家目录中即可,一般还会修改该文件的所有者和权限。

2.1.5、账号限制文件

/etc/login.defs 设置用户帐号限制,该文件里的配置对root用户无效。

如果 /etc/shadow 文件里有相同的选项,则以 /etc/shadow 里的设置为准,也就是说 /etc/shadow 的配置优先级高于 /etc/login.defs。

该文件有很多配置项,文件的默认内容只给出了一小部分,若想知道全部的配置项以及配个配置项的详细说明,可以 "man 5 login.defs" 查看。

[root@arm64v8 ~]# cat /etc/login.defs
#QMAIL_DIR      Maildir              # QMAIL_DIR是Qmail邮件的目录,所以可以不设置它
MAIL_DIR        /var/spool/mail      # 默认邮件根目录,即信箱
#MAIL_FILE      .mail                # mail文件的格式是.mail

# Password aging controls:
PASS_MAX_DAYS   99999         # 密码最大有效期(天)
PASS_MIN_DAYS   0             # 两次密码修改之间最小时间间隔
PASS_MIN_LEN    5             # 密码最短长度
PASS_WARN_AGE   7             # 密码过期前给警告信息的时间

# 控制useradd创建用户时自动选择的uid范围
# Min/max values for automatic uid selection in useradd
UID_MIN                  1000
UID_MAX                 60000
# System accounts
SYS_UID_MIN               201
SYS_UID_MAX               999

# 控制groupadd创建组时自动选择的gid范围
# Min/max values for automatic gid selection in groupadd
GID_MIN                  1000
GID_MAX                 60000
# System accounts
SYS_GID_MIN               201
SYS_GID_MAX               999

# 设置此项后,在删除用户时,将自动删除用户拥有的at/cron/print等job
#USERDEL_CMD    /usr/sbin/userdel_local

# 控制useradd添加用户时是否默认创建家目录,useradd -m选项会覆盖此处设置
CREATE_HOME     yes

# 设置创建家目录时的umask值,若不指定则默认为022
UMASK           077

# 设置此项表示当组中没有成员时自动删除该组
# 且useradd是否同时创建同用户名的主组。(该文件中并没有此项说明,来自于man useradd中-g选项的说明)
USERGROUPS_ENAB yes

# 设置用户和组密码的加密算法
ENCRYPT_METHOD SHA512

注意:/etc/login.defs中的设置控制的是shadow-utils包中的组件,也就是说,该组件中的工具执行操作时会读取该文件中的配置。该组件中包含下面的程序

/usr/bin/gpasswd      :administer /etc/group and /etc/gshadow
/usr/bin/newgrp       :log in to a new group,可用来修改gid,哪怕是正在登陆的会话也可以修改
/usr/bin/sg           :execute command as different group ID
/usr/sbin/groupadd    :添加组
/usr/sbin/groupdel    :删除组
/usr/sbin/groupmems   :管理当前用户的主组中的成员,root用户则可以指定要管理的组
/usr/sbin/groupmod    :modify a group definition on the system
/usr/sbin/grpck       :verify integrity of group files
/usr/sbin/grpconv     :无视它
/usr/sbin/grpunconv   :无视它
/usr/sbin/pwconv      :无视它
/usr/sbin/pwunconv    :无视它
/usr/sbin/adduser     :是useradd的一个软链接,添加用户
/usr/sbin/chpasswd    :update passwords in batch mode
/usr/sbin/newusers    :update and create new users in batch
/usr/sbin/pwck        :verify integrity of passsword files
/usr/sbin/useradd     :添加用户
/usr/sbin/userdel     :删除用户
/usr/sbin/usermod     :重定义用户信息
/usr/sbin/vigr        :edit the group and shadow-group file
/usr/sbin/vipw        :edit the password and shadow-password file
/usr/bin/lastlog      :输出所有用户或给定用户最近登录信息

2.1.6、创建用户默认配置文件

/etc/default/useradd 创建用户时的默认配置。useradd -D 修改的就是此文件。

[root@arm64v8 ~]# cat /etc/default/useradd  
# useradd defaults file
GROUP=100       # 在useradd使用-N或/etc/login.defs中USERGROUPS_ENAB=no时表示创建用户时不创建同用户名的主组(primary group),
                # 此时新建的用户将默认以此组为主组,网上关于该设置的很多说明都是错的,具体可看man useradd的-g选项或useradd -D的-g选项
HOME=/home      # 把用户的家目录建在/home中
INACTIVE=-1     # 是否启用帐号过期设置(是帐号过期不是密码过期),-1表示不启用
EXPIRE=         # 帐号过期时间,不设置表示不启用
SHELL=/bin/bash # 新建用户默认的shell类型
SKEL=/etc/skel  # 指定骨架目录,前文的/etc/skel就在这里
CREATE_MAIL_SPOOL=yes  # 是否创建用户mail缓冲

man useradd 的 useradd -D 选项介绍部分说明了这些项的意义。

2.2、用户和组管理命令

2.2.1、useradd or adduser 命令

adduser 是 useradd 的一个软链接。

useradd [options] login_name

选项说明:
-b:指定家目录的basedir,默认为/home目录
-d:指定用户家目录,不写时默认为/home/user_name
-m:要创建家目录时,若家目录不存在则自动创建,若不指定该项且/etc/login.defs中的CREATE_HOME未启用时将不会创建家目录
-M:显式指明不要创建家目录,会覆盖/etc/login.defs中的CREATE_HOME设置
-g:指定用户主组,要求组已存在
-G:指定用户的辅助组,多个组以逗号分隔
-N:明确指明不要创建和用户名同名的组名
-U:明确指明要创建一个和用户名同名的组,并将用户加入到此组中
-o:允许创建一个重复UID的用户,只有和-u选项同时使用时才生效
-r:创建一个系统用户。useradd命令不会为此选项的系统用户创建家目录,除非明确使用-m选项
-s:指定用户登录的shell,默认留空。此时将选择/etc/default/useradd中的SHELL变量设置
-u:指定用户uid,默认uid必须唯一,除非使用了-o选项
-c:用户的注释信息 
-k:指定骨架目录(skeleton)
-K:修改/etc/login.defs文件中有关于用户的配置项,不能修改组相关的配置。设置方式为KEY=VALUE,如-K UID_MIN=100
-D:修改useradd创建用户时的默认选项,就修改/etc/default/useradd文件
-e:帐户过期时间,格式为"YYYY-MM-DD"
-f:密码过期后,该账号还能存活多久才被禁用,设置为0表示密码过期立即禁用帐户,设置为-1表示禁用此功能
-l:不要将用户的信息写入到lastlog和faillog文件中。默认情况下,用户信息会写入到这两个文件中
# 修改/etc/default/useradd文件
useradd -D [options]

选项说明:不加任何选项时会列出默认属性
-b, --base-dir BASE_DIR
-e, --expiredate EXPIRE_DATE
-f, --inactive INACTIVE
-g, --gid GROUP
-s, --shell SHELL

[root@arm64v8 ~]# useradd -D -e "2050-05-29"
[root@arm64v8 ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=2050-05-29
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
[root@arm64v8 ~]#

useradd 创建用户时,默认会自动创建一个和用户名相同的用户组,这是 /etc/login.defs 中的 USERGROUP_ENAB 变量控制的。

useradd 创建普通用户时,不加任何和家目录相关的选项时,是否创建家目录是由 /etc/login.defs 中的 CREATE_HOME 变量控制的。

2.2.2、newusers 命令

newusers 用于批量创建或修改已有用户信息。在创建用户时,它会读取 /etc/login.defs 文件中的配置项。

newusers 命令从 file 中或标准输入中读取要创建或修改用户的信息,文件中每行格式都一样,一行代表一个用户。格式如下:

pw_name:pw_passwd:pw_uid:pw_gid:pw_gecos:pw_dir:pw_shell

  • pw_name:用户名,若不存在则新创建,否则修改已存在用户的信息
  • pw_passwd:用户密码,该项使用明文密码,在修改或创建用户时会按照指定的算法自动对其进行加密转换
  • pw_uid:指定 uid,留空则自动选择 uid。如果该项为已存在的用户名,则使用该用户的 uid,但不建议这么做,uid 应尽量保证唯一性
  • pw_gid:用户主组的 gid 或组名。若给定组不存在,则自动创建组。若留空,则创建同用户名的组,gid 将自动选择
  • pw_gecos:用户注释信息
  • pw_dir:指定用户家目录,若不存在则自动创建。留空则不创建。
  • pw_shell:指定用户的默认 shell

注意:newusers 命令不会递归创建父目录,父目录不存在时将会给出信息,但 newusers 命令仍会继续执行以完成创建剩下的用户,所以这些错误的用户家目录需要手动去创建。

newusers [options] [file]

选项说明:
-c:指定加密方法,可选DES,MD5,NONE,SHA256和SHA512
-r:创建一个系统用户

newusers 首先尝试创建或修改所有指定的用户,然后将信息写入到 user 和 group 的文件中。

如果尝试创建或修改用户过程中发生错误,则所有动作都将回滚,但如果在写入过程中发生错误,则写入成功的不会回滚,这将可能导致文件的不一致性。

要检查用户、组文件的一致性,可以使用 showdow-utils 包提供的 grpck 和 pwck 命令。

[root@arm64v8 ~]# cat /tmp/userlist
Brinnatt:password:2000:2000::/home/Brinnatt:/bin/bash
Monkey:password:2001:2001::/home/Monkey:/bin/bash
[root@arm64v8 ~]# 
[root@arm64v8 ~]# newusers -c SHA512 /tmp/userlist 
[root@arm64v8 ~]# 
[root@arm64v8 ~]# tail -2 /etc/passwd
Brinnatt:x:2000:2000::/home/Brinnatt:/bin/bash
Monkey:x:2001:2001::/home/Monkey:/bin/bash
[root@arm64v8 ~]# 
[root@arm64v8 ~]# tail -2 /etc/shadow
Brinnatt:$6$d/1MVonTJl/$XhjoDACS8Zs40yZsuLXIh5d5PsZBMYN67H0HFwSgvoMIunFPDIVYqFLM7O80pTbizNoa/zWQ6l6p8xkSsvN4Q/:18777:0:99999:7:::
Monkey:$6$/9F7daRNS$b3/n1WBRj.qNXqDMUWpdL9yfmzMl5ao2gHzHRFBz/.BBNUq6UxTHzy8d.0/YFjdvDE2VvtEo/0P/9C0w6VtjB.:18777:0:99999:7:::
[root@arm64v8 ~]# 

2.2.3、groupadd

创建一个新组。

groupadd [options] group
选项说明:
-f:如果要创建的组已经存在,默认会错误退出,使用该选项则强制创建且以正确状态退出,只不过gid可能会不受控制。
-g:指定gid,默认gid必须唯一,除非使用了-o选项。
-K:修改/etc/login.defs中关于组相关的配置项。配置方式为KEY=VALUE,例如-K GID_MIN=100 -K GID_MAX=499
-o:允许创建一个非唯一gid的组
-r:创建系统组

2.2.4、passwd 命令

修改密码的工具。默认 passwd 命令不允许为用户创建空密码。

passwd 修改密码前会通过 pam 认证用户,pam 配置文件中与此相关的设置项如下:

passwd password requisite pam_cracklib.so retry=3
passwd password required pam_unix.so use_authtok

命令的用法如下:

passwd options [username]

选项说明:
-l:锁定指定用户的密码,在/etc/shadow的密码列加上前缀"!"或"!!"。这种锁定不是完全锁定,使用ssh公钥还是能登录。要完全锁定,使用chage -E 0来设置帐户过期。
-u:解锁-l锁定的密码,解锁的方式是将/etc/shadow的密码列的前缀"!"或"!!"移除掉。但不能移除只有"!"或"!!"的项。
--stdin:从标准输入中读取密码
-d:删除用户密码,将/etc/shadow的密码列设置为空
-f:指定强制操作
-e:强制密码过期,下次登录将强制要求修改密码
-n:密码最小使用天数
-x:最大密码使用天数
-w:过期前几天开始提示用户密码将要过期
-i:设置密码过期后多少天,用户才过期。用户过期将被禁用,修改密码也无法登陆。

2.2.5、chpasswd 命令

以批处理模式从标准输入中获取提供的用户和密码来修改用户密码,可以一次修改多个用户密码。也就是说不用交互。适用于一次性创建了多个用户时为他们提供密码。

chpasswd [-e -c] "user:passwd"

-c:指定加密算法,可选的算法有 DES,MD5,NONE,SHA256和SHA512
-e:passwd 默认使用的是明文密码,如果要使用密文,则使用-e选项。参见 man chpasswd

user:passwd 为用户密码对,其中默认 passwd 是明文密码,可以指定多对,每行一个用户密码对。前提是用户是已存在的。

chpasswd 会读取 /etc/login.defs 中的相关配置,修改成功后会将密码信息写入到密码文件中。

该命令的修改密码的处理方式是先在内存中修改,如果所有用户的密码都能设置成功,然后才写入到磁盘密码文件中。在内存中修改过程中出错,则所有修改都回滚,但若在写入密码文件过程中出错,则成功的不会回滚。

# 修改单个用户密码
[root@arm64v8 ~]# echo "Brinnatt:aes123" | chpasswd -c SHA512
[root@arm64v8 ~]#

# 修改多个用户密码,则提供的每个用户对都要分行
[root@arm64v8 ~]# echo -e "Brinnatt:aes456\nMonkey:aes456" | chpasswd 
[root@arm64v8 ~]#

提示:如果有大批量的用户名要改密码,可以使用文件的标准输入

2.2.6、chage 命令

chage 命令主要修改或查看和密码时间相关的内容。具体的看 man 文档

chage [options] LOGIN

-l:列出指定用户密码相关信息
-E:指定帐户(不是密码)过期时间,所以是强锁定,如果指定为0,则立即过期,即直接锁定该用户

[root@arm64v8 ~]# chage -l Brinnatt
Last password change                    : May 30, 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@arm64v8 ~]# 
[root@arm64v8 ~]# chage -E 0 Brinnatt 
[root@arm64v8 ~]# 
[root@arm64v8 ~]# chage -l Brinnatt
Last password change                    : May 30, 2021
Password expires                    : never
Password inactive                   : never
Account expires                     : Jan 01, 1970
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@arm64v8 ~]#

2.2.7、userdel 命令

userdel 命令用于删除用户

userdel [options] login_name

选项说明:
-r:递归删除家目录,默认不删除家目录。
-f:强制删除用户,即使这个用户正处于登录状态。同时也会强制删除家目录。

一般不直接删除家目录,即不用 -r,可以 vim /etc/passwd,将不需要的用户直接注释掉。

2.2.8、groupdel 命令

删除组,如果要删除的组是某用户的主组,需要先删除主组中的用户。

2.2.9、usermod 命令

修改帐户属性信息。必须要确保在执行该命令的时候,待修改的用户没有在执行进程。

usermod [options] login

选项说明:
-l: 修改用户名,仅仅只是改用户名,其他的一切都不会改动(uid、家目录等)
-u: 新的uid,新的uid必须唯一,除非同时使用了-o选项
-g: 修改用户主组,可以是以gid或组名。对于那些以旧组为所属组的文件(除原家目录),需要重新手动修改其所属组
-m: 移动家目录内容到新的位置,该选项只在和-d选项一起使用时才生效
-d: 修改用户的家目录位置,若不存在则自动创建。默认旧的家目录不会删除
    如果同时指定了-m选项,则旧的家目录中的内容会移到新家目录
    如果当前用户家目录不存在或没有家目录,则也不会创建新的家目录
-o: 允许用户使用非唯一的UID
-s: 修改用的shell,留空则选择默认shell
-c: 修改用户注释信息

-a: 将用户以追加的方式加入到辅助组中,只能和-G选项一起使用
-G: 将用户加入指定的辅助组中,若此处未列出某组,而此前该用户又是该组成员,则会删除该组中此成员

-L: 锁定用户的密码,将在/etc/shadow的密码列加上前缀"!"或"!!"
-U: 解锁用户的密码,解锁的方式是移除shadow文件密码列的前缀"!"或"!!"
-e: 帐户过期时间,时间格式为"YYYY-MM-DD",如果给一个空的参数,则立即禁用该帐户
-f: 密码过期后多少天,帐户才过期被禁用,0表示密码过期帐户立即禁用,-1表示禁用该功能

2.2.10、groupmod 命令

修改系统中一个组的相关定义

groupmod [options] GROUP

选项说明:
-g, --gid GID:修改指定组的 GID
-n, --new-name NEW_GROUP:修改指定组的名字

2.2.11、vipw or vigr 命令

vipw 和 vigr 是编辑用户和组文件的工具

vipw 可以修改 /etc/passwd 和 /etc/shadow

vigr 可以修改 /etc/group 和 /etc/gshadow

用这两个工具比较安全,在修改的时候会检查文件的一致性。

2.3、手动创建用户

手动创建用户的全过程,需要管理员权限。

  1. 在 /etc/group 中添加用户所属组的相关信息。如果用户还有辅助组则在对应组中加入该用户作为成员。

  2. 在 /etc/passwd 和 /etc/shadow 中添加用户相关信息。此时指定的家目录还不存在,密码不存在,所以 /etc/shadow 的密码位使用"!!"代替。

  3. 创建家目录,并复制骨架目录中的文件到家目录中。

    [root@arm64v8 ~]# mkdir /home/Seri
    [root@arm64v8 ~]# cp -a /etc/skel/. /home/Seri/
    [root@arm64v8 ~]#
  4. 修改家目录及子目录的所有者和属组。

    [root@arm64v8 ~]# chown -R Seri:Seri /home/Seri/
    [root@arm64v8 ~]#
  5. 修改家目录及子目录的权限。例如设置组和其他用户无任何权限但所有者有。

    [root@arm64v8 ~]# chmod -R 700 /home/Seri/
    [root@arm64v8 ~]#

    到此为止,用户已经创建完成了,只是没有密码,所以只能 su,不能登录。

  6. 生成密码

    • 使用 openssl passwd 生成密码。但 openssl passwd 生成的密码只能是 MD5 算法的,很容易被破解

      # 生成使用 md5 算法的密码,然后将其复制到 /etc/shadow 对应的密码位
      # 其中 -1 是指 md5,-salt '12345678' 是使用 8 位字符创建密码的杂项
      [root@arm64v8 ~]# openssl passwd -1 -salt '12345678' '123456'
      $1$12345678$a4ge4d5iJ5vwvbFS88TEN0
      [root@arm64v8 ~]#
    • 直接使用passwd命令创建密码

  7. 测试手动创建的用户是否可以正确登录。

2.4、补充命令

2.4.1、finger 命令

从 CentOS 6 版本开始就没有该命令了,要先安装。

[root@arm64v8 ~]# yum install finger -y
[root@arm64v8 ~]# finger root
Login: root                     Name: root
Directory: /root                        Shell: /bin/bash
On since Mon May 31 11:37 (CST) on pts/0 from 110.52.210.213
   1 second idle
No mail.
No Plan.
[root@arm64v8 ~]# 

2.4.2、id 命令

id username

选项说明:
-u:得到uid
-n:得到用户名而不是uid
-z:无任何空白字符输出模式,不能在默认的格式下使用。
[root@arm64v8 ~]# id root
uid=0(root) gid=0(root) groups=0(root)
[root@arm64v8 ~]#

2.4.3、users 命令

查看当前正在登陆的用户名。

2.4.4、last 命令

查看最近登录的用户列表,其实 last 查看的是 /var/log/wtmp 文件。

-n 显示行数:列出最近几次登录的用户

[root@arm64v8 ~]# last -n 6
root     pts/0        110.52.210.213   Mon May 31 11:37   still logged in   
root     pts/0        120.227.21.217   Sat May 29 21:48 - 23:01  (01:12)    
root     pts/0        120.227.21.217   Sat May 29 21:00 - 21:48  (00:47)    
root     pts/0        120.227.21.217   Sat May 29 10:39 - 10:39  (00:00)    
root     tty1                          Sat May 29 10:25 - 10:25  (00:00)    
root     pts/0        120.227.21.217   Sat May 29 10:19 - 10:20  (00:01)    

wtmp begins Fri Apr 23 11:19:11 2021
[root@arm64v8 ~]# 

2.4.5、lastb 命令

查看谁尝试登陆过但没有登录成功的。即能够审核和查看谁曾经不断的登录,可能那就是黑客。

-n:只列出最近的n个尝试对象。

[root@arm64v8 ~]# lastb -n 3
root     ssh:notty    143.198.156.250  Sun May 30 14:08 - 14:08  (00:00)    
root     ssh:notty    143.198.156.250  Sun May 30 14:08 - 14:08  (00:00)    
root     ssh:notty    143.198.156.250  Sun May 30 14:08 - 14:08  (00:00)    

btmp begins Mon May 10 14:12:54 2021
[root@arm64v8 ~]#

2.4.6、who or w 命令

都是查看谁登录过,并干了什么事

w 查看的信息比 who 多

[root@arm64v8 ~]# w
 12:37:16 up 2 days,  2:21,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    110.52.210.213   11:37    2.00s  0.07s  0.00s w
[root@arm64v8 ~]# 
[root@arm64v8 ~]# who
root     pts/0        2021-05-31 11:37 (110.52.210.213)
[root@arm64v8 ~]#

其中 w 的第一行,分别表示当前时间,已开机时长,当前在线用户,过去 1、5、15 分钟的平均负载率。这一行和 uptime 命令获取的信息是完全一致的。

2.4.7、lastlog 命令

可以查看登录的来源IP

-u 指定查看用户

[root@arm64v8 ~]# lastlog | head -n 6
Username         Port     From             Latest
root             pts/0    110.52.210.213   Mon May 31 11:37:52 +0800 2021
bin                                        **Never logged in**
daemon                                     **Never logged in**
adm                                        **Never logged in**
lp                                         **Never logged in**
[root@arm64v8 ~]#

2.5、用户身份切换

2.5.1、su 命令

切换用户或以指定用户运行命令。

使用 su 可以指定运行命令的身份(user/group/uid/gid)。

为了向后兼容,su 默认不会改变当前目录,且仅设置 HOME 和 SHELL 这两个环境变量(若目标用户非 root,则还设置 USER 和 LOGNAME 环境变量)。推荐使用 --login 选项(即 "-" 选项)避免环境变量混乱。

su [options...] [-] [user [args...]]

选项说明:
-c command:使用-c选项传递要指定的命令到shell上执行。使用-c执行命令会为每个su都分配新的会话环境
-, -l, --login:启动shell作为登录的shell,模拟真正的登录环境。它会做下面几件事:
                1.清除除了TERM外的所有环境变量
                2.初始化HOME,SHELL,USER,LOGNAME,PATH环境变量
                3.进入目标用户的家目录
                4.设置argv[0]为"-"以便设置shell作为登录的shell
                  使用--login的su是交互式登录。不使用--login的su是非交互式登录(除不带任何参数的su外)
-m, -p, --preserve-environment:保留整个环境变量(不会重新设置HOME,SHELL,USER和LOGNAME),
                                保留环境的方法是新用户shell上执行原用户的各配置文件,如~/.bashrc。
                                当设置了--login时,将忽略该选项
-s SHELL:运行指定的shell而非默认shell,选择shell的顺序优先级如下:
                1.--shell指定的shell
                2.如果使用了--preserve-environment,选择SHELL环境变量的shell
                3.选项目标用户在passwd文件中指定的shell
                4./bin/sh

注意:

  1. 若 su 没有给定任何参数,将默认以 root 身份运行交互式的 shell(交互式,所以需要输入密码),即切换到 root 用户,但只改变 HOME 和 SHELL 环境变量。
  2. su - username 是交互式登录,要求密码,会重置整个环境变量,它实际上是在模拟真实的登录环境。
  3. su username 是非交互登录,不会重置除 HOME/SHELL 外的环境变量。

举例:

  1. 创建 hadoop 用户,家目录是 /home/hadoop,其 shell 为 /bin/zsh

    [root@arm64v8 ~]# useradd -c "special user with zsh" -s /bin/zsh hadoop
    [root@arm64v8 ~]# head -1 /etc/passwd; tail -1 /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    hadoop:x:1000:1000:special user with zsh:/home/hadoop:/bin/zsh
    [root@arm64v8 ~]#
  2. 首先 su 到 hadoop 上,再执行一个完全不带参数的 su

    # 使用su - username后,以登录shell的方式模拟登录,会重新设置各环境变量,su - username是交互式登录
    [root@arm64v8 ~]# su - hadoop
    [hadoop@arm64v8]~% env | egrep -i "^home|^shell|^path|^logname|^user"
    HOME=/home/hadoop
    SHELL=/bin/zsh
    USER=hadoop
    LOGNAME=hadoop
    PATH=/usr/local/bin:/bin:/usr/bin:/home/hadoop/bin:/usr/local/sbin:/usr/sbin
    [hadoop@arm64v8]~%
    
    # 不带任何参数的su,是交互式登录切换回root,但只会改变HOME和SHELL环境变量
    [hadoop@arm64v8]~% su
    Password: 
    [root@arm64v8 hadoop]# env | egrep -i '^home|^shell|^path|^logname|^user|^pwd'
    SHELL=/bin/bash
    USER=hadoop
    PATH=/usr/local/bin:/bin:/usr/bin:/home/hadoop/bin:/usr/local/sbin:/usr/sbin
    PWD=/home/hadoop
    HOME=/root
    LOGNAME=hadoop
    [root@arm64v8 hadoop]#
    
    # su - 的方式切换回root
    [root@arm64v8 hadoop]# su -
    Last login: Mon May 31 15:38:56 CST 2021 on pts/0
    [root@arm64v8 ~]# env | egrep -i '^home|^shell|^path|^logname|^user|^pwd'
    SHELL=/bin/bash
    USER=root
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    HOME=/root
    LOGNAME=root
    [root@arm64v8 ~]# 
    
    # 再直接su username,它只会重置SHELL和HOME两个环境变量,其他环境变量保持不变
    [root@arm64v8 ~]# su hadoop
    [hadoop@arm64v8]/root% env | egrep -i '^home|^shell|^path|^logname|^user|^pwd'
    SHELL=/bin/zsh
    USER=hadoop
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    HOME=/home/hadoop
    LOGNAME=hadoop
    [hadoop@arm64v8]/root% 

    在某些环境下或脚本中,可能需要临时切换身份执行命令,注意这时候的环境变量是否会改变,否则很可能报错提示命令找不到。

2.5.2、sudo 配置

sudo 可以让一个用户以某个身份(如 root 或其他用户)执行某些命令,它隐含的执行方式是切换到指定用户再执行命令,因为涉及到了用户的切换,所以环境变量是否重置是需要设置的。

sudo 支持插件实现安全策略。默认的安全策略插件是 sudoers,它是通过 /etc/sudoers 或 LDAP 来配置的。

安全策略是控制用户使用 sudo 命令时具有什么权限,但要注意,安全策略可能需要用户进行身份认证,如密码认证的机制或其他认证机制,如果开启了认证要求,则在指定时间内未完成认证时 sudo 会退出,默认超时时间为 5 分钟。

安全策略支持对认证进行缓存,使得在一定时间内该用户无需再次认证就可以执行 sudo 命令,默认缓存时间为 5 分钟,sudo -v 可以更新认证缓存。

sudo 支持日志审核,可以记录下成功或失败的 sudo。

/etc/sudoers 配置文件

该文件里主要配置 sudo 命令时指定的用户和对应的权限

# visudo 是专门打开 /etc/sudoers 配置文件的命令
[root@arm64v8 ~]# visudo 

# 主机别名
## Host Aliases
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

# 用户别名
## User Aliases
# User_Alias ADMINS = jsmith, mikem

# 命令别名
## Command Aliases
## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable
## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb
## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

# 核心配置区域,sudo权限的配置
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL

## Allows members of the users group to mount and unmount the
## cdrom as root
# %users  ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

在这个文件里,主要有别名(用户别名,主机别名,命令别名)的配置和 sudo 权限的配置。

安全策略配置格式为:

用户名 主机名 = (可切换到的用户身份) 权限和命令

​ ① ② ③ ④

  • 用户名:可以用组,只需在组名前加个百分号 % 表示。
  • 主机名:表示该用户可以在哪些主机上运行 sudo,可以用 hostname 也可以用 ip 指定。
  • 可切换的用户身份:即指定执行命令的用户,也可以用组。
  • 权限和命令:允许执行和不允许执行的命令(多个命令间用逗号分隔)和特殊权限,命令可以带其选项及参数。命令要写绝对路径。不允许执行的命令需要在命令前加上 "!" 来表示。可以使用标签,如 NOPASSWD 标签表示切换或以指定用户执行该标签后的命令时不需要输入密码。一行写不下时可使用"\"续行。

标签使用方法:

NOPASSWD:/usr/sbin/useradd,PASSWD:/usr/sbin/userdel
  • 它表示 useradd 命令不需要输入密码,而 userdel 需要输入密码。

对于别名,相当于用户对于用户组。权限配置处都可以使用别名,即①②③④处都能使用别名来配置。

# 示例
DEFAULT=/bin/*,/sbin/ldconfig,/sbin/ifconfig,/usr/sbin/useradd,/usr/sbin/userdel,/bin/rpm,/usr/bin/yum,/sbin/service,/sbin/chkconfig,sudoedit /etc/rc.local,sudoedit /etc/hosts,sudoedit /etc/ld.so.conf,/bin/mount,sudoedit /etc/exports,/usr/bin/passwd [!-]*,!/usr/bin/passwd root,/bin/su - [!-]*,!/bin/su - root,!/bin/su root, /bin/bash, /usr/sbin/dmidecode, /usr/sbin/lsof, /usr/bin/du, /usr/bin/python, /usr/sbin/xm,sudoedit /etc/profile,sudoedit /etc/bashrc,/usr/bin/make,sudoedit /etc/security/limits.conf,/etc/init.d/*,/usr/bin/ruby

ADMINS ALL=(ALL)NOPASSWD:DEFAULT

其中上面的 "/usr/bin/passwd [!-]*" 表示允许修改加参数的密码。"/bin/su - [!-]*" 表示允许 "su -" 到某用户下,但必须给参数。

2.5.3、sudo or sudoedit 命令

当 sudo 执行指定的 command 时,它会调用 fork 函数,并设置命令的执行环境(如某些环境变量),然后在子进程中执行 command,sudo 的主进程等待命令执行完毕,然后传递命令的退出状态码给安全策略并退出。

sudoedit 等价于 sudo -e,它是以 sudo 的方式执行文件编辑动作。

sudo [options] [command]
选项说明:
-b             : (background)该选项告诉sudo在后台执行指定的命令。
                 注意,如果使用该选项,将无法使用任务计划(job)来控制维护这些后台进程,
                 需要交互的命令应该考虑是否真的要后台,因为可能会失败

-l[l] [command]: 当单独使用-l选项时,将列出(list)用户可执行和被禁止的命令。
                 当配合command时,且该command是被允许执行的命令,将列出命令的全路径及该命令参数。
                 如果command是不被允许执行的,则sudo直接以状态码-1退出。
                 可以指定多个字母"l"来显示更详细的格式

-n             : 使得sudo变成非交互模式,但如果安全策略是要求输入密码的,则sudo将报错

-S             : (stdin)该选项使得sudo从标准输入而非终端设备上读取密码,给定的密码必须在尾部加上换行符

-s [command]   : (shell)指定要切换到的shell,如果给定command,则在此shell上执行该命令

-U user        : (other user)配合-l选项来指定要列出哪个用户的权限信息

-u user        : (user)该选项明确指定要以此处指定的用户而非root来运行command。
                 若使用uid的方式指定用户,则需要使用"#uid",但很多时候可能需要对"#"使用"\"转义,即使用"\#uid"

-E             : (environment)该选项告诉sudo在执行命令时保留自己的环境变量,保留环境变量的方式是执行环境配置文件。
                 但因为跨了用户,所以很可能某些家目录下的环境配置文件会因为无权限而执行失败,此时sudo将报错   

-k [command]   : 当单独使用-k选项时,sudo将使得用户的认证缓存失效。下次执行sudo命令需要输入密码。
                 当配合command时,-k选项将忽略用户的缓存,所以sudo将要求用户输入密码,但这次输入密码不会更新认证缓存
                 但执行-k选项本身,不需要密码

-K             : (sure kill)类似于-k选项,但它会完全移除用户的认证缓存,且不会配合command,执行-K本身不需要密码

-v             : (validate)该选项使得sudo更新用户认证缓存

--             : 暗示sudo命令行参数到此结束

在 sudo 上可以直接设置环境变量,它会传递为 command 的环境。设置的方式为 var=value,如 LD_LIBRARY_PATH=/usr/local/pkg/lib

由于 sudo 默认的安全策略插件是 sudoers,所以当用户执行 sudo 时,系统会自动去寻找 /etc/sudoers 文件(该文件里被 root 配置了用户对应的权限,也即安全策略),查看 sudo 要使用的用户是否有对应的权限,如果有则执行,如果没有权限就失败退出 sudo。

标签云