文章中实例都是基于CentOS7
用户标识符:UID和GID
虽然我们在登录Linux主机时,输入的用户账号,但其实Linux主机并不会直接认识你的【账号名称】,它仅认识ID(一组号码),计算机只认识0和1,所以计算机对数字比较有概念,账号只是为了让人们容易记忆而已,用户的ID和账号存储在/etc/passwd文件中。
每个登录的用户会拥有两种ID,一种用户ID(UserID,简称UID),一个是用户组ID(Group ID,简称GID)
查看系统中的xpy用户
[xpy@lotus ~]$ id xpy
uid=1000(xpy) gid=1000(xpy) 组=1000(xpy),10(wheel)
[xpy@lotus ~]$ ll -d /home/xpy
drwx------. 15 xpy xpy 4096 12月 8 21:40 /home/xpy
修改xpy的uid为2000
[xpy@lotus ~]$ vim /etc/passwd
xpy:x:2000:1000:xpy:/home/xpy:/bin/bash
[xpy@lotus ~]$ ll -d /home/xpy
drwx------. 15 1000 xpy 4096 12月 8 21:43 /home/xpy
# 1000找不到对应的账号,则显示为1000
用户账户
Linux系统上面的账户如果需要登录主机以获取shell环境来工作,它需要如何进行呢?首先,它必须要在计算机前面利用tty1-tty6的终端提供的登录接中,输入用户名和密码才能够登录。当输入用户名和密码的时候,系统帮助你处理了什么?
- 先查找/etc/passwd里面是否有你输入的账号?如果没有则直接退出,如果账号存在的话,则读取账号对应的UID与GID(在/etc/group文件中),另外,该账号的家目录与shell设置也一并读出。
- 然后核对密码表,这时Linux进入/etc/shadow里面找出对应的账号与UID,然后核对输入的密码是否正确。
- 如果一切都OK的话,进入shell管理的阶段。
/etc/passwd文件结构
每一行都代表一个账号,有几行就代表系统中有几个用户,里面有很多账号本来就是系统正常运行所必需的,它称为系统账号,例如bin,daemon,adm,nobody等,这些账号不要随意删除。
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
每一行中的信息通过【:】分隔开,共有7段:
- 账号名称
就是账号,提供给对数字不太敏感的人类来登录系统,需要用来对应UID,例如root的UID对应的就是0(第3个字段) - 密码
早期的密码就是放在这个字段上,但是因为这个文件的特性是所有的程序都能够读取,这样一来容易造成密码的泄漏,后来将密码数据放到了/etc/shadow中 - UID
- GID
这个与/etc/group有关,其实/etc/group的概念跟/etc/passwd差不多 - 用户信息说明
这个字段并没有什么重要的用途,只是用来解释账号的意义 - 家目录
用户的家目录,以上面为例,root的家目录为/root,默认的用户家目录在/home/yourIDname - shell
当用户登录系统后会获得一个shell来与系统的内核沟通以进行用户的操作任务。
/etc/shadow文件结构
[root@lotus ~]# head -n 4 /etc/shadow
root:$6$g.81k4FUh9s9/Mj5$.tgv8TTVMwplzOWPqg2MCd5dJc.nRGoFksS5AF6kSN5OCrTHnvRSAr9mDZ4CYPWiZiimYcxdwAyTd3ciga40D/::0:99999:7:::
bin:*:17632:0:99999:7:::
daemon:*:17632:0:99999:7:::
adm:*:17632:0:99999:7:::
基本上,shadow同样以【:】作为分隔符,如果数一数,一共有9个字段
- 账号名称
由于密码也需要与账号对应,因此第1个字段就是账号,必须要与/etc/passwd对应 - 密码
这个字段的数据才是真正的密码,而且是经过编码的密码(摘要)。需要注意的是这些加密过的密码难被破解,但并不等于不会,所以这个文件的权限是【----------】,只有root才可以读写,不要随便更改这个文件的权限。
注:由于各种密码编码的技术不一样,因此不同的编码系统会造成这个字段的长度不相同,固定的摘要算法产生的密码是特定的,因此【当你修改这个字段后,该密码就会失效】,在此字段前加上!或*修改密码字段,就会让密码【暂时失效】。 - 最近修改密码的日期
这个字段记录了【修改密码那一天】的日期,这个是从1970年1月1日作为1而累加的日期,至于想要知道某个日期的累积日数,可使用如下的程序计算:
[root@lotus ~]# echo $(($(date --date='2020-12-09' +%s)/86400+1))
18605
上述命令中,2020-12-09是想要计算的日期,86400为每一天的秒数,%s为1970-01-01以来的累积总秒数,由于bash只支持整数,最终需要加上1补齐1970-01-01当天。
- 密码不可被修改的天数
这个字段记录了这个账号的密码在最近一次被更改后需要经过几天才可以再被修改。如果是0,表示密码随时可以修改,如果设置了10天,表示20天之内都无法再修改这个密码。 - 密码需要重新修改的天数
经常修改密码是个好习惯,为了强制用户修改密码,这个字段可以指定在最近一次更改密码后,在多少天数内需要再次修改密码才行。你必须在这个天数内重新设置你的密码,否则这个账号会变为过程。 - 密码需要修改期限前的警告天数
当账号的密码有效期限快要到的时候,系统会根据这个字段的设置,发出【警告】信息,提醒它【再过n天你的密码就要过期了,请尽快重新设置你的密码】 - 密码过期后的账号宽限时间(密码失效日)
- 账号失效日
这个日期跟第三个字段一样,都是使用1970年以来的总天数。这个字段表示:这个账号在此字段规定的日期之后,将无法再使用。 - 保留
这个字段是保留的,为以后新功能的加入
查看/etc/shadow文件的加密机制
[root@lotus ~]# authconfig --test | grep hashing
password hashing algorithm is sha512
# 这就是目前密码的加密机制sha512
创建用户(useradd)
useradd创建linux账号时,至少会参考
- /etc/default/useradd
- /etc/login.defs
- /etc/skel/*
这些文件。
useradd创建用户账号时,会修改以下文件 - 用户账号与密码相关文件 :/etc/passwd,/etc/shadow
- 用户和用户组相关文件:/etc/group,/etc/gshadow
- 用户和家目录:/home/用户账号
[root@localhost ~]# useradd -D
GROUP=100 #新建账号的初始用户组使用GID为100
HOME=/home #用户家目录的基准目录(basedir)
INACTIVE=-1 #密码过期后是否会失效的设置值
EXPIRE= #账号失效的日期(shadow内的第8个字段)
SHELL=/bin/bash #默认使用的shell程序文件名
SKEL=/etc/skel #用户家目录参考基准目录(创建用户时会拷贝这个目录下的文件到用户家目录)
CREATE_MAIL_SPOOL=yes #创建用户的mailbox
-g 添加用户并指定组ID(gid),如果没有指定这项,将会根据/etc/login.defs文件中的USERGROUPS_ENAB变量,如果这个变量设置为yes或者通过-U/–user-group 指定,将根据用户的登录名称来创建组,如果USERGROUPS_ENAB设置为no 或者 -N/–no-user-group在命令行设置,useradd将设置一个主要组根据/etc/default/useradd配置文件中的GROUP变量进行设定
[root@lotus ~]# useradd test1 -g 100
-b 添加用户时指定用户家目录的目录位置,创建用户后会在指定的目录下创建一个用户名称的文件夹
[root@lotus ~]# useradd -b /etc abc
[root@lotus ~]# ll -d /etc/abc
drwx------. 3 abc abc 78 12月 11 22:17 /etc/abc
-c 给用户添加指定注释
[root@lotus abc]# useradd -c 'this is a testuser' testuser
[root@lotus abc]# cat /etc/passwd | grep testuser
testuser:x:1005:1005:this is a testuser:/home/testuser:/bin/bash
-e (/etc/shadow第8栏)设置用户过期日期,如没有设置则根据/etc/default/useradd配置文件中的设置进行设定
[root@localhost ~]# useradd -e '2020-12-13' test1
在/etc/shadow文件中体现出来过期时间距1970-01-01的天数
test1:!!:18608:0:99999:7::***18609***:
-f # (/etc/shadow第7栏)设置账号过期后的宽限时间,如果不指定则根据/etc/default/useradd配置文件中的设置进行设定
[root@localhost ~]# useradd -f 10 test2
test2:!!:18608:0:99999:7:***10***::
-G 指定新创建用户的次要用户组
[root@localhost ~]# useradd -G test1,test2,test3 test5
[root@localhost ~]# vim /etc/group
***test1:x:1000:test3,test4,test5
test2:x:1001:test5
test3:x:1002:test5***
test4:x:1003:
***test5:x:1004:***
-k 指定用户创建家目录时要拷贝的文件和文件夹目录,此选项必须与-m一起使用,如果此项没有设置,则通过/etc/default/useradd配置文件中的SKEL设置(SKEL=/etc/skel)
[root@localhost skel]# ls /root
anaconda-ks.cfg
[root@localhost skel]# useradd -m -k /root test6
[root@localhost skel]# ls /home/test6
anaconda-ks.cfg
-K 覆盖/etc/login.defs中的默认参数,(UID_MIN, UID_MAX, UMASK, PASS_MAX_DAYS 和其它).
[root@localhost skel]# cat /etc/login.defs | grep -v '^#' | grep -v '^$'
MAIL_DIR /var/spool/mail #用户的默认mailbox文件放置目录
PASS_MAX_DAYS 99999 #/etc/shadow第5栏,多久需要修改密码日期
PASS_MIN_DAYS 0 #/etc/shadow第4栏,多久不可重新设置密码
PASS_MIN_LEN 5 #密码的最小长度,已被PAM模块替换,已经弃用该参数
PASS_WARN_AGE 7 #/etc/shadow第6栏,过期前会警告的日数
UID_MIN 1000 #使用者最小的UID,1000以下的UID为系统所保留
UID_MAX 60000 #使用者最大的UID
SYS_UID_MIN 201 #保留给自定义用户自行设置的系统账号最小值UID
SYS_UID_MAX 999 #保留给自定义用户自行设置的系统账号最大值UID
GID_MIN 1000 #使用者组最小的GID,1000以下的GID为系统所保留
GID_MAX 60000 #使用者最大的GID
SYS_GID_MIN 201 #保留给自定义用户自行设置的系统账号最小值GID
SYS_GID_MAX 999 #保留给自定义用户自行设置的系统账号最大值GID
CREATE_HOME yes #在不加-M或-m时,是否主动建立使用者家目录
UMASK 077 #使用者家目录建立的umask,因此权限是700
USERGROUPS_ENAB yes #使用userdel删除时,是否删除初使用户组
ENCRYPT_METHOD SHA512 #密码的加密机制是SHA512
-M 不创建家目录
[root@localhost ~]# useradd -M test7
[root@localhost ~]# ls /home/test7
ls: cannot access /home/test7: No such file or directory
-N 不创建用户组
[root@localhost ~]# useradd -N test8
[root@localhost ~]# tail -n 1 /etc/group
test7:x:1008:
-r 创建一个系统用户,在/etc/shadow文件中系统用户的创建与普通用户的创建不同(如下),系统用户id的选择将根据/etc/login.defs文件中的SYS_UID_MIN-SYS_UID_MAX区间进行选择,并替换掉 UID_MIN-UID_MAX。useradd不会创建家目录,如果需要创建家目录,需要配合-m参数。
[root@localhost ~]# vim /etc/shadow
test1:!!:18609:::::: #系统账号
test2:!!:18609:***0:99999:7***::: #普通账号
[root@localhost ~]# vim /etc/passwd
test1:x:***997***:1000::/home/test1:/bin/bash #系统账号
test2:x:1000:1001::/home/test2:/bin/bash #普通账号
#创建系统用户,默认不创建家目录
[root@localhost ~]# ls /home/test1
ls: cannot access /home/test1: No such file or directory
#创建系统用户并创建家目录,需配合-m使用
[root@localhost ~]# useradd -r -m test5
[root@localhost ~]# ls /home/test5
abc
-s 修改用户的默认shell,默认的shell通过/etc/default/useradd
[root@localhost ~]# useradd test6 -s /bin/sh
[root@localhost ~]# tail -n 1 /etc/passwd
test6:x:1001:1003::/home/test6:/bin/sh
[root@localhost ~]# su - test6
-sh-4.2$
-u 指定用户的UID,值必须是唯一的,除非使用了-o选项,值不能为负值,默认情况下,使用大于或等于UID_MIN且大于其他每个用户的最小ID值
#指定用户UID
[root@localhost ~]# useradd -u 1009 test7
[root@localhost ~]# tail -n 1 /etc/passwd
test7:x:1009:1009::/home/test7:/bin/bash
#默认情况下使用大于其他用户的最小ID值
[root@localhost ~]# useradd test8
[root@localhost ~]# tail -n 1 /etc/passwd
test8:x:1010:1010::/home/test8:/bin/bash
修改用户(usermod)
usermod :修改用户账户
- a 添加指定账户到指定的额外用户组,需与-G配合使用
- G指定额外用户组
[root@localhost ~]# usermod -a -G test2 test1
[root@localhost ~]# tail -n 10 /etc/group
postdrop:x:90:
postfix:x:89:
chrony:x:996:
test1:x:1000:
#用户test1被添加到test2的额外用户组中
**test2:x:1001:test1**
-c 添加或修改账户注释
[root@localhost ~]# usermod -c 'this is a new user' test2
[root@localhost ~]# tail -n 10 /etc/passwd
abrt:x:173:173::/etc/abrt:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
test1:x:997:1000::/home/test1:/bin/bash
test2:x:1000:1001:***this is a new user***:/home/test2:/bin/bash
-d 修改用户的登录文件目录(将旧的用户家目录修改为新的用户家目录名称),可配合-m一起使用,当前家目录下的文件将被移动到新指定的家目录中,如果当前家目录不存在,则新的家目录将不会创建
[root@localhost test2]# usermod -d /home/test12 -m test2
#查看新指定的家目录下的文件,同以前/home/test2下的文件相同
[root@localhost test2]# ll /home/test12 -a
total 24
drwx------. 2 test2 test2 111 Dec 14 08:46 .
drwxr-xr-x. 7 root root 72 Dec 14 08:59 ..
-rw-r--r--. 1 test2 test2 20 Dec 13 08:27 abc
-rw-------. 1 test2 test2 5 Dec 14 08:46 .bash_history
-rw-r--r--. 1 test2 test2 18 Apr 10 2018 .bash_logout
-rw-r--r--. 1 test2 test2 193 Apr 10 2018 .bash_profile
-rw-r--r--. 1 test2 test2 231 Apr 10 2018 .bashrc
-rw-r--r--. 1 root root 21 Dec 14 08:32 test2.txt
[root@localhost tmp]# su - test2
Last login: Mon Dec 14 08:55:17 EST 2020 on pts/1
#查看test2的当前登录目录为新指定的用户家目录
[test2@localhost ~]$ pwd
/home/test12
-e 指定账户过期日期(自1970年以来的天数)
[root@localhost tmp]# usermod -e '2020-12-15' test2
[root@localhost tmp]# cat /etc/shadow | grep test2
test2:$6$sYcS7qMk$0g8YRSwCxZS1I3xznSNQthgWU.pb7I8CFR90isDg6dmJwW3Tqy9ewn1jdLTHKPQ6feHyn5jdjCFE7eJblUnlG.:18610:0:99999:7::***18611***:
-f 指定密码过期后的宽限天数(如果设置0表示到期后账户立即失效,设置为-1表示此项不启用)
[root@localhost test2]# usermod -f 10 test2
[root@localhost test2]# cat /etc/shadow | grep test2
test2:$6$sYcS7qMk$0g8YRSwCxZS1I3xznSNQthgWU.pb7I8CFR90isDg6dmJwW3Tqy9ewn1jdLTHKPQ6feHyn5jdjCFE7eJblUnlG.:18610:0:99999:7:***10***:18611:
-g 修改用户的组ID,用户组的名字或数字,组必须存在,先前属于用户主要组的用户家目录下的文件将属于新的用户组,家目录以后的文件则需要手动的去修改所属组。
#修改test2的用户组为test6[组ID:1003]
[root@localhost test2]# usermod -g 1003 test2
#修改完成后家目录下的文件权限自动变更
[test2@localhost ~]$ ll
total 8
-rw-r--r--. 1 test2 ***test6*** 20 Dec 14 09:19 abc
#其它目录下的文件权限没有自动变更,需要手动来改变
[test2@localhost tmp]$ ll | grep test2
-rw-r--r--. 1 test2 ***test3*** 0 Dec 14 09:27 test12
-G 添加额外用户组(次要用户组)同useradd
[root@localhost test2]# usermod -G test1,test2 test8
[root@localhost test2]# cat /etc/group | grep test8
test1:x:1000:test8
test2:x:1001:test1,test8
test8:x:1010:
-L 锁定用户的密码,在加密的密码串前面加上“!”,有效的禁用密码,不能与-p 或 -U一起使用
注:如果不只要锁定用户密码,而要禁用账户,可以将用户的EXPIRE_DATE值设定为1
[root@localhost test2]# cat /etc/shadow | grep test2
test2:$6$sYcS7qMk$0g8YRSwCxZS1I3xznSNQthgWU.pb7I8CFR90isDg6dmJwW3Tqy9ewn1jdLTHKPQ6feHyn5jdjCFE7eJblUnlG.:18610:0:99999:7:10:18611:
[root@localhost test2]# usermod -L test2
[root@localhost test2]# cat /etc/shadow | grep test2
test2:***!***$6$sYcS7qMk$0g8YRSwCxZS1I3xznSNQthgWU.pb7I8CFR90isDg6dmJwW3Tqy9ewn1jdLTHKPQ6feHyn5jdjCFE7eJblUnlG.:18610:0:99999:7:10:18611:
[root@localhost tmp]# su - test6
Last login: Sun Dec 13 09:53:29 EST 2020 on pts/1
#使用test2再登录的时候,提示认证失败
***-sh-4.2$ su - test2
Password:
su: Authentication failure***
#如果将过期日期设置为1,则会出现以下提示
-sh-4.2$ su - test2
Password:
Your account has expired; please contact your system administrator
su: User account has expired
-U 解除用户的密码的设置,移除加密密码前面的!,不能同-p和-U同时使用
删除用户(userdel)
userdel 删除用户账户和关联的文件
-f 强制删除用户账户,即使用户还在登录,删除用户的家目录和邮件文件,如果USERGROUPS_ENAB设置为yes在/etc/login.defs文件中,如果组存在且与用户名相同,则删除用户组,即使它是其它用户的主要用户组。
-r 删除用户家目录和邮件目录,其它目录的文件需要手工查找删除。邮件文件的目录在login.defs文件中的MAIL_DIR变量定义。