1 用户和组的基本概念
每个用户都有用户名、用户的唯一编号uid(user id)、所属组及其默认的shell,可能还有密码、家目录、附属组、注释信息等。
每个组也有自己的名称、组唯一编号gid(group id)。一般来说,gid和uid是可以不相同的,但绝大多数都会让它们保持一致,大致属于约定俗成类的概念吧。
在Linux中,用户分为3类:
(1). 超级管理员
超级管理员是最高权限者,它的uid=0,默认超级管理员用户名为root。因为uid默认具有唯一性,所以超级管理员默认只能有一个(如何添加额外的超级管理员,见useradd命令),但这一个超级管理员的名称并非一定要是root。但是没人会去改root的名称,在后续非常非常多的程序中,都认为超级管理员名称为root,这里要是一改,牵一发而动全身。
(2). 系统用户
有时候需要一类具有某些特权但又不需要登录操作系统的用户,这类用户称为系统用户。它们的uid范围从201到999(不包括1000),有些老版本范围是1到499(centos 6),出于安全考虑,它们一般不用来登录,所以它们的shell一般是/sbin/nologin,而且大多数时候它们是没有家目录的。
(3). 普通用户
普通用户是权限受到限制的用户,默认只能执行/bin、/usr/bin、/usr/local/bin和自身家目录下的命令。它们的uid从500开始。尽管普通用户权限收到限制,但是它对自身家目录下的文件是有所有权限的。
超级管理员和其他类型的用户,它们的命令提示符是不一样的。uid=0的超级管理员,命令提示符是"#",其他的为"$"。
默认root用户的家目录为/root,其他用户的家目录一般在/home下以用户名命名的目录中,如longshuai这个用户的家目录为/home/longshuai。当然,家目录是可以自定义位置和名称的。
2 用户和组管理相关的文件
2.1 用户文件/etc/passwd
/etc/passwd文件里记录的是操作系统中用户的信息,这里面记录了几行就表示系统中有几个系统用户。它的格式大致如下:
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash nginx:x:498:499:Nginx web server:/var/lib/nginx:/sbin/nologin longshuai:x:1000:1000::/home/longshuai:/bin/bash |
每一行表示一个用户,每一行的格式都是6个冒号共7列属性,其中有很多用户的某些列属性是留空的。
用户名: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这个程序的功能实现的,假如修改Linux的源代码,将/sbin/nologin这个程序变成可登录,那么shell为/sbin/nologin时也是可以登录的。
2.2 密码文件/etc/shadow
/etc/shadow文件中存放的是用户的密码信息。该文件具有特殊属性,除了超级管理员,任何人都不能直接读取和修改该文件,而用户自身之所以能修改密码,则是因为该文件的suid属性,使得修改密码时临时提升为root权限。
该文件的格式大致如下:
每一行表示一个用户密码的属性,有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.3 用户和组管理命令
2.3.1 useradd和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文件中。默认情况下,用户信息会写入到这两个文件中 useradd -D [options] 修改/etc/default/useradd文件 选项说明:不加任何选项时会列出默认属性 -b, --base-dir BASE_DIR -e, --expiredate EXPIRE_DATE -f, --inactive INACTIVE -g, --gid GROUP -s, --shell SHELL
示例:
[root@xuexi ~]# useradd -D -e "2016-08-20" # 设置用户2016-08-20过期 [root@xuexi ~]# useradd -D GROUP=100 HOME=/home INACTIVE=-1 EXPIRE=2016-08-20 SHELL=/bin/bash SKEL=/etc/skel CREATE_MAIL_SPOOL=yes [root@xuexi ~]# cat /etc/default/useradd # useradd defaults file GROUP=100 HOME=/home INACTIVE=-1 EXPIRE=2016-08-20 SHELL=/bin/bash SKEL=/etc/skel CREATE_MAIL_SPOOL=yes
useradd创建用户时,默认会自动创建一个和用户名相同的用户组,这是/etc/login.defs中的USERGROUP_ENAB变量控制的。
useradd创建普通用户时,不加任何和家目录相关的选项时,是否创建家目录是由/etc/login.defs中的CREATE_HOME变量控制的。
2.3.2 批量创建用户newusers
newusers用于批量创建或修改已有用户信息。在创建用户时,它会读取/etc/login.defs文件中的配置项。
newusers [options] [file]
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:指定用户家目录,若不存在则自动创建。留空则不创建。
- :注意,newusers命令不会递归创建父目录,父目录不存在时将会给出信息,但newusers命令仍会继续执行
- :以完成创建剩下的用户,所以这些错误的用户家目录需要手动去创建。
- pw_shell:指定用户的默认shell
newusers [options] [file]
选项说明:
-c:指定加密方法,可选DES,MD5,NONE,SHA256和SHA512
-r:创建一个系统用户
newusers首先尝试创建或修改所有指定的用户,然后将信息写入到user和group的文件中。如果尝试创建或修改用户过程中发生错误,则所有动作都将回滚,但如果在写入过程中发生错误,则写入成功的不会回滚,这将可能导致文件的不一致性。要检查用户、组文件的一致性,可以使用showdow-utils包提供的grpck和pwck命令。
示例:
shell> cat /tmp/userfile zhangsan:123456:2000:2000::/home/zhangsan:/bin/bash lisi:123456:::::/bin/bash shell> newusers -c SHA512 /tmp/userfile shell> tail -2 /etc/passwd zhangsan:x:2000:2000::/home/zhangsan:/bin/bash lisi:x:2001:2001:::/bin/bash shell> tail -2 /etc/shadow zhangsan:$6$aI1Mk/krF$xN0TFOIRibrb/mYngJ/sV3M7g4zOxqOh8CWyDlI0uwmr5qNTzsmwauRFvCpfLtvtiJYZ/5bil.XfJMNB.sqDY1:17323:0:99999:7::: lisi:$6$bngXo/V6wWW$.TlQCJtEm9krBX0Oiep/iahS59a/BwVYcSc8F9lAnMGF55K6W5YoUZ2nK6WkMta3p7sihkxHm/AuNrrJ6hqNn1:17323:0:99999:7:::
2.3.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.3.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.3.5 批量修改密码chpasswd
以批处理模式从标准输入中获取提供的用户和密码来修改用户密码,可以一次修改多个用户密码。也就是说不用交互。适用于一次性创建了多个用户时为他们提供密码。
chpasswd [-e -c] "user:passwd" -c:指定加密算法,可选的算法有DES,MD5,NONE,SHA256和SHA512 user:passwd为用户密码对,其中默认passwd是明文密码,可以指定多对,每行一个用户密码对。前提是用户是已存在的。 -e:passwd默认使用的是明文密码,如果要使用密文,则使用-e选项。参见man chpasswd
chpasswd会读取/etc/login.defs中的相关配置,修改成功后会将密码信息写入到密码文件中。
该命令的修改密码的处理方式是先在内存中修改,如果所有用户的密码都能设置成功,然后才写入到磁盘密码文件中。在内存中修改过程中出错,则所有修改都回滚,但若在写入密码文件过程中出错,则成功的不会回滚。
示例:
修改单个用户密码。
shell> echo "user1:123456" | chpasswd -c SHA512
修改多个用户密码,则提供的每个用户对都要分行。
shell> echo -e 'usertest:123456\nusertest2:123456' | chpasswd
更方便的是写入到文件中,每行一个用户密码对。
shell> cat /tmp/passwdfile zhangsan:123456 lisi:123456 shell> chapasswd -c SHA512 </tmp/passwdfile
2.3.6 chage
chage命令主要修改或查看和密码时间相关的内容。具体的看man文档,可能用到的两个选项如下:
-l:列出指定用户密码相关信息
-E:指定帐户(不是密码)过期时间,所以是强锁定,如果指定为0,则立即过期,即直接锁定该用户
[root@server2 ~]# chage -l zhangsan Last password change : Jun 06, 2017 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@server2 ~]# chage -E 0 zhangsan [root@server2 ~]# chage -l zhangsan Last password change : Jun 06, 2017 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
2.3.7 删除用户和组
userdel命令用于删除用户。
userdel [options] login_name -r:递归删除家目录,默认不删除家目录。 -f:强制删除用户,即使这个用户正处于登录状态。同时也会强制删除家目录。
一般不直接删除家目录,即不用-r,可以vim /etc/passwd,将不需要的用户直接注释掉。
groupdel命令删除组。如果要删除的组是某用户的主组,需要先删除主组中的用户。