每个登录的使用者都会至少取得两个ID,UID(User ID)和GID(Group ID)
输入帐号后,系统的工作:
1. 在/etc/passwd中寻找帐号,若存在则读出UID 与GID(在/etc/group中读出),同时读出家目录与使用的shell
2. 核对密码(/etc/shadow)
/etc/passwd档案结构:
每一行都代表一个帐号,有几行就代表系统有几个帐号。每行有7个字段,用":"隔开。字段具体内容:
1. 帐号名称(用来对应UID)
2. 密码(显示为"x",实际内容存储在/etc/shadow中)
3. UID:0:表示系统管理员(要让其他帐号也具有root权限时,将该帐号的UID改为0即可)
1~499:默认500以下的数字留给系统作为保留帐号。这些系统帐号通常是不可登录的。通常系统帐号分为两类,1-99为由distribution自行建立的帐号;100-499为用户使用的UID
500+:给一般使用者使用的帐号(可登录帐号)
(Ubuntu是1000以下的UID保留给系统使用)
4. GID(与/etc/group有关)
5. 用户信息说明栏(没有什么重要用途,只是说明帐号的意义)
6. 家目录
8. 用户使用的shell
/etc/shadow档案结构(有9个字段,用":"隔开):
1. 帐号名称
2. 密码
3. 上次改动密码的日期(数字是从1970-01-01开始累加到现在的天数)
4. 连续变更密码需要的天数:即这个帐号的密码在最后一次被更改后需要几天才可以再被更改(数字是建立在上次更改(第3个字段)的基础上)
5. 密码过期的天数:在上一次更改密码后多少天内需要再次更改密码(数字建立在上次改动密码的日期),若未及时更改密码会过期
6. 更新密码期限前的警告天数(建立在密码过期(第5字段)的基础上)
7. 密码失效天数:即密码过期后帐号的宽限时间(建立在密码过期日的基础上)
密码过期:帐号可以继续进行其他工作,在登入系统时会被要求重新设定密码
密码失效:该帐号无法使用密码登录
8. 帐号失效日期(也是从1970-01-01累加的天数)
9. 保留字段
/etc/group档案结构:(每行表示一个群组,每行4个字段)
1. 组名
2. 群组密码
3. GID
4. 此群组支持的帐号名称:若想将一个帐号加入该群组,在该行最后添加【,帐号名】即可,注意不要有空格
初始群组(initial group)和有效群组(effective group)
初始群组:用户一登入系统,就立刻拥有该群组的相关权限,即/etc/passwd中每个用户的GID(第4栏)
有效群组:建立新档案时使用的群组
在读取/修改档案时,只要执行者支持该档案所属的群组就可以,不需要将该群组设置为有效群组
groups:显示该用户所有支持的群组,其中第一个列出的即为有效群组
newgrp:变更该用户当前的有效群组(是以一个新的shell来提供这个功能,完成工作后注意使用exit回到原shell中)
/etc/gshadow档案结构:(4个字段,":"分隔)
1. 组名
2. 密码:若该栏为"!",表示该群组不具有群组管理员;若开头为"!",表示无合法密码,也无群组管理员
3. 群组的管理员帐号
4. 该群组所支持的帐号(与/etc/group内容相同)
useradd [-DugGMmcdrsef] 账户名
-D:列出useradd默认值
-u:后接UID,是数字,直接指定一个UID给该帐号
-g:后接initial group组名,该群组的GID会被放置到/etc/passwd的第4个字段内
-G:后接组名,表示该帐号支持的其他群组(这个选项会修改/etc/group中的内容)
-M:不建立用户家目录
-m:建立用户家目录
-c:即/etc/passwd第5栏的说明内容
-d:制定某个目录成为家目录而不使用默认值(一定要使用绝对路径!)
-r:建立系统帐号
-s:后接shell,指定该帐号使用的shell,预设是/bin/bash
-e:后接帐号失效日期,格式为【YYYY-MM-DD】,会写入/etc/shadow第8个字段
-f:指定密码过期后是否会失效,0为立刻失效,-1为永不失效(密码只会过期),会修改/etc/shadow的第7个字段
创建用户时系统进行的工作:
1. 在/etc/passwd中添加新的一行,建立新帐号的UID、GID、家目录等
2. 在/etc/shadow中添加此帐号密码的相关参数,但尚未有密码
3. 在/etc/group中添加一个与帐号名相同的群组(若群组已存在则不会再建立新群组)
(可能在/home下建立一个与帐号名相同的目录作为用户家目录,权限为取决于/etc/login.defs的UMASK参数)
useradd默认值内容:
GROUP=100:新建帐号的初始群组使用GID为100者。针对初始群组有两种不同的设置机制:
私有群组机制:系统会建立一个与帐号名相同的群组给使用者作为初始群组
公共群组机制:以GROUP=100这个设定值作为新建帐号的初始群组,故每个帐号都属于users群组
HOME=/home:用户家目录的基准目录
INACTIVE=-1:密码过期是是否会失效(-1永不失效,0立即失效,n表示n天后失效)
EXPIRE=:帐号失效日期
SHELL=/bin/bash:默认使用的shell程序文件名
SKEL=/etc/skel:建立用户家目录的参考基准目录,新建的用户家目录下的所有数据都是从/etc/skel复制过去的
CREATE_MAIL_SPOOL=no:建立使用者的mailbox
/etc/login.defs:新建帐号的其他设定
MAIL_DIR /var/mail:用户默认邮件信箱放置目录
PASS_MAX_DAYS 99999:/etc/shadow的第5栏,密码过期的天数
PASS_MIN_DAYS 0:/etc/shadow的第4栏,连续变更密码需要的天数
PASS_WARN_AGE 7:/etc/shadow的第6栏,密码过期前的警告日期
UID_MIN 1000:使用者的最小UID小于1000为系统保留
UID_MAX 60000:使用者能够用的最大UID
GID_MIN 1000:使用者自定义组的最小GID,小于1000为系统保留
GID_MAX 60000:使用者自动一组的最大GID
UMASK 022:用户家目录建立的umask
USERGROUPS_ENA yes:使用userdel删除时,是否会删除初始群组(若该帐号所属群组已经没有用户了,则会删除该群组)
ENCRYPT_METHOD SHA512:密码加密方式
当系统给一个帐号UID时,(1)首先参考UID_MIN的,再(2)由/etc/passwd搜寻最大的UID,然后将(1)(2)对比,找出较大的那个再+1就是新帐号的UID
passwd [-luSnxwi] 帐号
-l:即lock,在/etc/shadow第2栏前加上"!"使密码失效(使用户无法通过密码登录)
-u:与-l相对,unlock
-S:列出密码相关参数,即/etc/shadow档案内的大部分信息
-n:后接天数,/etc/shadow的第4字段,连续修改密码的天数
-x:后接天数,/etc/shadow的第5字段,密码过期的天数
-w:后接天数,/etc/shadow的第6字段,密码过期前的警告天数
-i:后接日期,/etc/shadow的第7字段,密码失效日期
不接任何参数时表示设置所接帐号的密码
chage [-ldEImMW] 帐号名 (主要修改/etc/shadow的相关内容)
-l:列出该帐号详细密码参数
-d:后接日期,修改上次更改密码的日期(/etc/shadow第3字段),格式为【YYYY-MM-DD】
-E:后接日期,修改帐号失效日(/etc/shadow第8字段),格式为【YYYY-MM-DD】
-I:后接天数,修改密码失效日期(/etc/shadow第7字段)
-m:后接天数,修改连续修改密码的天数(/etc/shadow第4字段)
-M:后接天数,修改密码过期天数(/etc/shadow第5字段)
-W:后接天数,修改密码过期前警告天数(/etc/shadow第6字段)
当通过"-d 0"将一个账户的上次修改密码时间改为1970/01/01后,该用户第一次登录后就会被强制修改密码
usermod [-cdegGlsuLU] username
-c:修改帐号说明(/etc/passwd第5栏)
-d:修改帐号家目录(/etc/passwd第6栏)
-e:后接日期,修改帐号失效日期,格式为YYYY-MM-DD(/etc/shadow的第8个字段)
-f:后接天数,修改密码失效日期(/etc/shadow第7字段)
-g:修改初始群组(/etc/passwd第4个字段GID)
-G:后接次要群组,设定支持当前用户的所有群组,用逗号","分隔(如果用户当前在某一群组中,而此群组并未出现在"-G"后,则用户会被从这个群组中删除。也就是说,"-G"后面是用户所在的所有次要群组)
-a:与-G合用,增加支持当前用户的次要群组
-l:修改帐号名称(/etc/passwd第一栏)
-s:修改用户默认使用的shell,后接shell实际档案,如/bin/bash
-u:修改UID(/etc/passwd第3栏)
-L:暂时锁住用户密码,使其无法登录(修改/etc/passwd第2栏)
-U:解锁用户
userdel [-r] username 删除用户
-r:连同用户的家目录一起删除
通常情况下,如果一个帐号只是暂时不是用的话,只要将/etc/shadow的帐号失效日期(第8字段)设为0即可,这样会保留该帐号的所有数据。如果想完全移除某个帐号,在下达userdel之前,最好先【find / -user username】找出系统中属于这个user的所有档案,再进行删除
finger [-s] username:查阅用户相关信息
-s:仅列出用户的帐号、全名、终端机代号与登录时间等
-m:列出与后面接的帐号相同这,而不是利用部分对比
不接参数的话会列出所有能查询到的账户以及相关信息
chfn:添加用户的联系方式等信息
chsh -s shell实际档案:修改当前用户使用的默认shell(注意使用实际档案,如/bin/bash)
id [username]:列出账户的UID、GID、支持群组等相关信息
groupadd [-g gid] [-r] 组名
-g:后接某个特定的GID,用来指定GID
-r:建立系统群组
群组GID的决定方式与UID相似(最大+1)
groupmod [-g gid] [-n 新组名] 群组名
-g:修改已有的GID数字
-n:修改已有的组名
groupdel:删除群组
当一个群组是某个帐号的initial group时,无法删除该群组。若一定要删除,要么修改这个帐号的GID(默认群组),要么删除这个帐号
群组管理员:可以管理帐号加入/移除群组
gpasswd:
1. root执行时:
gpasswd [-A user1,user2,..] [-M user1,user2,..] [-rR] groupname
-A:将后接的用户设为该群组的群组管理员
-M:将后接用户加入该群组
-r:将groupname的密码移除
-R:让groupname的密码栏失效
不接任何参数时,表示给予groupname一个密码
2. 群组管理员执行时:
gpasswd [-ad] user groupname
-a:将user加入groupname群组
-d:将user从groupname群组中移出
ACL(Access Control List):
目的在于提供除传统的owner,group,others的rwx权限之外的细部权限设定。ACL可以针对单一使用者,单一档案或目录进行rwx的权限设定。ACL需要文件系统的支持
通过【dumpe2fs -h /dev/sdb9】可以查看文件系统是否支持ACL,观察"Default mount options"一栏是否有"acl"字样。如果未支持,可以通过指令【mount -o remount,acl /】来开启ACL支持;如果想开机自动生效,修改/etc/fstab档案,在倒数第三栏加上【,acl】即可
setfacl:设定某个档案/目录的ACL权限
setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名
-m:将后接的acl参数设定给目标文件,不可与-x合用
-x:删除后接的acl参数
-b:移除该文件所有的ACL设定参数
-k:移除预设的ACL参数
-R:递归设定ACL,子文件都会被设定
-d:设定ACL预设参数,只对目录有效,在该目录新建的文件会引用此数值
针对特定使用者:u:[使用者帐号列表]:[rwx] 例:setfacl -m u:xero:rx test (当使用者列表为空时,表示设定档案的拥有者)
针对特定群组:g:[群组列表]:[rwx]
ACL属性默认不继承,即目录下的子文件不会被设定,若想使一个目录下一直拥有ACL设定需要:d:[ug]:使用者列表:[rwx]
注意"继承"与"递归"的区别,个人理解,"递归"是设定一个目录下当前存在的所有子文件,而"继承"是指该目录下以后建立的文件都会拥有该目录的属性
ACL权限设定后,ls档案会看到权限部分增加了一个"+"
getfacl:查看某个档案/目录的ACL设定项目
"mask"表示使用者或群组所设定的权限必须要在mask的权限范围内才能生效,此即"有效权限(effective permission)"
su [-lm] [-c 指令] [username]
-,-l:以login-shell的变量档案读取方式来登入系统
-m:表示使用当前的环境设定,而不读取新使用者的配置文件
-c:后接要运行的指令,仅进行一次指令(只是想要执行一个只有root才能进行的指令,且执行完就恢复原身份)
单纯使用"su"切换成root身份时,读取的表量设定方式为non-logcin shell,这种方式很多原来的变量不会改变(如PATH),由于没有变成root的环境,因此很多指令只能使用绝对路径来执行。要想完整的切换到新使用者的环境,必须要使用【su - username】或【su -l username】
su切换账户时需要切换到的账户的密码,而sudo的执行仅需要当前账户的密码,只有/etc/sudoers内设定的用户才能执行sudo指令
sudo [-b] [-u username] 指令
-b:将后续指令放到背景中让系统执行,不对当前的shell产生影响
-u:后接要切换到的用户,若无此项则代表切换为root
由于系统帐号的shell是nologin的,所以sudo的一个重要作用是以系统帐号的身份执行某些指令
可以通过【sh -c "指令1; 指令2; ..."】来执行一串指令
编辑/etc/sudoers要使用指令"visudo",档案内容为:
使用者帐号 登入者的来源主机名=(可切换的身份) 可下达的指令
root ALL=(ALL) ALL
使用者帐号:系统的哪个帐号可以使用sudo指令,可以是用户,也可以是群组(需要在群组名前加上%)
登入者的来源主机名:这个帐号可以由哪些主机连接到本Linux主机
可切换身份:这个帐号可以切换成什么身份来下达后续指令
可下达的指令:一定要使用绝对路径。如果想免除密码输入,可以在本栏前添加"NOPASSWD:",如"NOPASSWD:ALL"
例:如果只想让用户可下达passwd以修改其他帐号的密码,需要将"可下达指令"一栏设置为:
!/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
其中,"!"表示不可执行,以避免root的密码被更改
可以通过别名一次建立多个sudo支持帐号:
User_Alias AAA = user1, user2, ...
Cmnd_Alias AAACMD = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/urs/bin/passwd root
AAA ALL=(root) AAACMD
通过"User_Alias"建立一个别名,这个别名一定要使用大写字母,包括Cmnd_Alias(命令别名)、Host_Alias(来源主机别名)都要使用大写字母,这样一来所有AAA中的帐号都能执行AAACMD中的指令
只用当前用户的密码就将身份转换为root的方法:
User_Alias MYADMIN = user1, user2, ...
MYADMIN ALL=(root) /bin/su -
这样一来,只要MYADMIN中的用户输入【sudo su -】并且输入自己的密码,就可以切换成root身份,而不需要知道root的密码
系统帐号使用的是无法登录的shell,"无法登录"指使用者无法使用bash或其他shell来登入系统,而并不是说这个帐号无法使用其他的系统资源(Ubuntu下系统帐号也可以登录。。)
PAM:
PAM是一套应用程序编程接口(API),提供了一连串的验证机制,只要使用者将验证阶段的需求告知PAM,PAM就能够返回验证结果。因为是编程接口,所以其他程序也可以呼叫PAM,从而能够让帐号密码或者其他方式的验证结果具有一致性。
PAM用来进行验证的数据称为模块(module)。
PAM藉由一个与程序相同的配置文件来进行一连串的认证分析需求。例如,执行passwd后,程序呼叫PAM的流程是:
1. 用户开始执行/usr/bin/passwd这个程序,并输入密码
2. passwd呼叫PAM模块进行验证
3. PAM模块到/etc/pam.d/寻找与程序(passwd)同名的配置文件
4. 依据/etc/pam.d/passwd内的设定,引用相关的PAM模块逐步进行验证分析
5. 将验证结果(成功/失败及其他信息)传回程序passwd
6. 程序passwd根据PAM回传结果决定下一个动作(重新输入密码或通过验证)
/etc/pam.d/下程序同名配置文件的内容一般可以分为三个字段:
1. 验证类别(Type),分为四种:
a) auth:用来检验使用者的身份
b) account:大部分在进行授权(authorization),这种类别主要检验使用者是否具有正确的权限(如密码是否过期)
c) session:管理使用者在这次登录(或使用这个指令)期间,PAM所给予的环境设定,通常记录用户登录与注销时的信息
d) passwd:主要提供验证的修订工作,如修改密码
这四个类别通常是有顺序的,原因是总要先验证身份(auth),系统才能藉由用户的身份给予适当的授权与权限设定(account),然后登录与注销期间的环境才需要设定,才需要记录登录与注销的信息(session),如果在运作期间需要密码修订,才给予passwd的类并
2. 验证的控制标识(control flag):简单地说就是验证通过的标准,管理验证的放行方式,主要分为四种:
a) required:验证若成功则带有success标志,若失败则带有failure标志,但无论成功失败都会继续后续的验证流程
b) requisite:若验证失败立刻返回failure标志给源程序,并终止后续的验证流程;若成功则带有success的标志并继续后续验证流程
c) sufficient:若验证成功则立刻回传success给源程序并终止后续验证流程;若失败则带有failure标志闭关内继续后续验证流程
d) optional:这个模块大多在显示信息,并不是用在验证方面
/etc/pam.d/*:每个程序个别的PAM配置文件
/lib/security/*:PAM模块档案的实际放置位置
/etc/security/*:其他PAM环境的配置文件
一些PAM模块的介绍:
pam_securetty.so:限制root只能从安全的终端机登录。tty1、tty2等就是终端机装置名称,安全的终端机设定写在/etc/securetty中
pam_nologin.so:这个模块可以限制一般用户能否登入主机。当/etc/nologin档案存在时,所有的一般使用者均无法再登入系统,在登录时会显示该档案的内容(这个模块对root以及已经登入系统的一般帐号没有影响)
pam_selinux.so:SELinux是针对程序进行细部管理权限的功能
pam_console.so:当系统出现某些问题,或某些时刻需要使用特殊的终端接口(如RS232)登入主机时,这个模块可以帮助处理一些档案权限的问题,让使用者可以通过特殊终端接口(console)登入系统
pam_loginuid.so:验证使用者的UID是我们所需的数值,可以使用这个模块进行规范
pam_evn.so:设定环境变量的一个模块
pam_linux.so:这是一个复杂但重要的模块,可以用在auth阶段的认证功能,可以用在account阶段的帐号许可证管理,可以在session阶段的登录文件记录,也可以用在密码更新阶段的检验
pam_limits.so:提供ulimit指令
login的PAM验证机制流程:
1. 验证阶段(auth)
首先,a)经过pam_securetty.so判断,如果使用者是root,会参考/etc/securetty的设定;b)接下来经过pam_env.so设定额外的环境变量;c)再通过pam_unix.so检验密码,若通过则回报login程序;若不通过则d)继续往下以pam_succeed_if.so判断UID是否大于500(Ubutnu 1000),若小于500则回报失败,否则再往下e)以pam_deny.so拒绝联机
2. 授权阶段(account)
a)先以pam_nologin.so判断/etc/nologin是否存在,若存在则不允许一般使用者登录;b)接下来以pam_unix进行帐号管理,c)再以pam_succeed_if.so判断 UID是否小于500,若小于500则不记录登录信息;d)最后以pam_permit.so允许该帐号登录
3. 密码阶段(password)
a)先以pam_cracklib.so设定密码仅能尝试错误3次;b)接下来以pam_unix.so通过md5,shadow等功能进行密码检验,若能通过则回报login程序,若不通过则以c)pam_deny.so拒绝登录
4. 会议阶段(session)
a)先以pam_selinux.so暂时关闭SELinux;b)使用pam_limits.so设定用户能够操作的系统资源;c)登录成功后开始记录相关信息在登录文件中;d)以pam_loginuid.so规范不同的UID权限;e)开启pam_selinux.so的功能
总之,就是依据验证类别(type),先由login的设定值去查阅,如果出现"include system-auth"就转到system-auth档案中的相同类别,取货的额外的验证流程;然后再到下一个验证类别。当所有验证都跑完,就结束本次PAM验证
为什么root无法以telnet直接登入系统,但却能够使用ssh登入:
一般telnet会引用login的PAM模块,而login的验证阶段会有/etc/securetty的限制。由于远程联机属于pts/n的动态终端机接口装置名称,并没有写入/etc/securetty,因此root无法以telnet登入远程注意。ssh使用的是/etc/pam.d/sshd这个模块,该模块的验证阶段并没有加入pam_securetty,因此就没有/etc/pam_securetty的限制,故而可以直接从远程连接到服务器
limits.conf
改变ulimit除了可以通过修改使用者的~/.bashrc外,还可以通过设定/etc/security/limits.conf统一交由PAM来管理,档案中每行包括四栏:
1.帐号:用户或群组,若是群组前面需要加"@"
2.限制依据:是严格(hard)还是仅为警告(soft)
3.限制项目
4.限制值
这个档案设定完成就生效,不需要重启服务;修改完的数据对已登入的用户是无效的
w/who:
查询目前已登录的用户
lastlog:
查询每个帐号的最近登录时间
write:向用户发送信息
write使用者帐号[用户所在终端接口]
用户所在终端接口可以通过who查询
mesg[ny]
n:不接收信息(对root发送的信息无效)
y:接受信息
不接参数就是显示当前的设置状态
wall<档案名:广播档案内的信息
mail:
发送邮件:mail username@localhost -s "邮件标题"(也可以通过"<filename"将文件的内容作为邮件内容发送)
收信:直接下达mail就可以(提示字符是"&"),输入"?"可以显示帮助
>表示目前处理的信件
N表示未读
<messagelist>是每封邮件左边的数字
/var/spool/mail/username是username的新邮件,/home/username/mbox是收件箱,要阅读mbox使用指令
mail-f /home/username/mbox
手动新增使用者
检查工具:
pwck:检查/etc/passwd内的信息,还会检查实际的家目录是否存在,对比/etc/passwd与/etc/shadow信息是否一致等。如果/etc/passwd内的数据字段错误会进行提示。相应的群组检查使用grpck
pwconv:将/etc/passwd内的帐号与密码移动到/etc/shadow中
a)对比/etc/passwd及/etc/shadow,若/etc/passwd内存在的帐号没有对应的/etc/shadow密码,会去/etc/login.defs读取相关的密码设置,并建立该帐号的/etc/shadow数据
b)若/etc/passwd中存在加密后的密码数据,会将该栏移动到/etc/shadow中,并将/etc/passwd中对应的密码栏变成"x"
pwunconv:将/etc/shadow内的密码栏数据写回/etc/passwd中,并删除/etc/shadow
chpasswd:读入未加密的密码,加密后写入/etc/shadow(常用在大量创建帐号中)。可以通过stdin读入数据,格式为【uesrname:passwd】,例:echo"xiaoming:mingming" | chpasswd -m
不建议建立纯数字帐号,因为系统会无法辨别那是帐号还是UID
手动建立用户的方法(可以建立用户名任意的用户):
1.建立需要的群组(编辑/etc/group)
2.将/etc/group与/etc/gshadow同步(grpconv)
3.建立帐号及各个属性(编辑/etc/passwd)
4.将/etc/passwd与/etc/shadow同步(pwconv)
5.建立帐号密码(passwdusername)
6.建立用户家目录(cp-a /etc/skel /home/username)
7.更改家目录属性(chown-R)