在管理Linux主机的帐号时,我们必须先来了解一下Linux到底是如何辨别每一个使用者的。
虽然我们登陆Linux主机的时候,输入的是我们的帐号,但是其实Linux主机并不会直接认识你的“帐号名称”的,他仅认识ID(ID就是一组号码)。由于计算机仅认识0与1,所以主机对于数字比较有概念的;至于帐号只是为了让人们容易记忆而已。而你的ID与帐号的对应就在/etc/passwd当中。
那么到底有几种ID呢?在之前有提到过,每一个文件都具有“拥有人与拥有群组”的属性吗?没错~每个登陆的使用者至少都会取得两个ID,一个是使用者ID(UserID,简称UID)、一个是群组ID(GroupID,简称GID)。
每一个文件都会有所谓的拥有者ID与拥有群组ID,当有要显示文件属性的需求时,系统会依据/etc/passwd与/etc/group的内容,找到UID/GID对应的帐号与群组名称再显示出来。
可以作个小实验,可以用root的身份vim/etc/passwd,然后将你的一般身份的使用者的ID随便改一个号码,然后再到你的一般身份的目录下看看原先该帐号拥有的文件,你会发现该文件的拥有人变成了“数字了”。
Linux系统上面的使用者如果需要登陆主机以取得shell的环境来工作时,他需要如何进行呢?首先,他必须要在计算机前面利用tty1~tty6的终端机提供的login接口,并输入帐号与密码后才能够登陆。如果是通过网络的话,那至少使用者就得要学习ssh这个功能了。那么你输入帐号密码后,系统帮你处理了什么呢?
/etc/passwd文件结构
这个文件的构造是这样的:每一行都代表一个帐号,有几行就代表有几个帐号在你的系统中。不过需要特别留意的是,里面很多帐号本来就是系统正常运行所必须要的,我们可以简称他为系统帐号,例如bin,daemon,adm,nobody等等,这些帐号请不要随意的删掉,这个文件的内容有点像这样:
[root@study~]#head-n4/etc/passwdroot:x:0:0:root:/root:/bin/bash<==等一下做为下面说明用bin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologin每个Linux系统都会有的第一行,就是root这个系统管理员那一行,可以明显的看出来,每一行使用“:”分隔开,共有七个,分别是:
1.帐号名称就是帐号,用来提供给对数字不太敏感的人类使用来登陆系统的,需要用来对应UID。例如root的UID对应就是0(第三字段);
2.密码早期Unix系统的密码就是放在这字段上!但是因为这个文件的特性是所有的程序都能够读取,这样一来很容易造成密码数据被窃取,因此后来就将这个字段的密码数据改放到/etc/shadow中了,所以这里你会看到一个“x”。
3.UID这个就是使用者识别码,通常Linux对于UID有几个限制:
4.GID
这个与/etc/group有关,其实/etc/group与/etc/passwd差不多,只是他是用来规范群组名称与GID的对应而已。
5.使用者信息说明栏
这个字段基本上并没有什么重要用途,只是用来解释这个帐号的意义而已。不过,如果使用finger的功能时,这个字段可以提供很多的信息。
6.主文件夹
这是使用者的主文件夹,以上面为例,root的主文件夹在/root,所以当root登陆之后,就会立刻跑到/root目录。如果你有个帐号的使用空间特别的大,你想要将该帐号的主文件夹移动到其他的硬盘去该怎么作?可以在这个字段进行修改,默认的使用者主文件夹在/home/【yourIDname】。
7.Shell
我们在BASH这一章提到很多次,当使用者登陆系统后就会取得一个Shell来与系统的核心沟通以进行使用者的操作任务。那为何默认shell会使用bash呢?就是在这个字段指定的。这里比较需要注意的是,有一个shell可以用来替代成让帐号无法取得shell环境的登陆动作,那就是/sbin/nologin。
/etc/shadow文件结构
我们知道很多程序的运行都与权限有关,而权限与UID/GID有关。因此各程序当然需要读取/etc/passwd来了解不同帐号的权限。因此/etc/passwd的权限需设置为-rw-r--r--这样的情况,虽然早期的密码也有加密过,但却放置到/etc/passwd的第二个字段上,这样一来很容易被有心人士所窃取的,加密过的密码也能够通过暴力破解法去trialanderror(试误)找出来。
因为这样的关系,所以后来发展出将密码移动到/etc/shadow这个文件分隔开来的技术,而且还加入很多的密码限制参数在/etc/shadow里面。/etc/shadow文件有点像这样:
[root@study~]#head-n4/etc/shadowroot:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhO...:16559:0:99999:7:::<==下面说明用bin:*:16372:0:99999:7:::daemon:*:16372:0:99999:7:::adm:*:16372:0:99999:7:::基本上,shadow同样以“:”作为分隔符号,共有九个字段,这九个字段的用途是这样的:
1.帐号名称由于密码也需要与帐号对应~因此,这个文件的第一栏就是帐号,必须要与/etc/passwd相同才行。
2.密码
这个字段内的数据才是真正的密码,而且是经过编码的密码(加密)。只能看到有一些特殊符号的字母,需要特别留意的是,虽然这些加密过的密码很难被解出来,但是“很难”不等于“不会”,所以,这个文件的默认权限是“-rw-------”或者是“----------”,只有root才可以读写。你得随时注意,不要不小心更改了这个文件的权限。
另外,由于各种密码编码的技术不一样,因此不同的编码系统会造成这个字段的长度不相同。举例来说,旧式的DES,MD5编码系统产生的密码长度就与目前惯用的SHA不同。SHA的密码长度明显的比较长些。由于固定的编码系统产生的密码长度必须一致,因此“当你让这个字段的长度改变后,该密码就会失效(算不出来)”。很多软件通过这个功能,在此字段前加上!或*改变密码字段长度,就会让密码“暂时失效”了。
3.最近变更密码的日期
[root@study~]#echo$(($(date--date="2015/05/04"+%s)/86400+1))16559上述指令中,2015/05/04为你想要计算的日期,86400为每一天的秒数,%s为1970/01/01以来的累积总秒数。由于bash仅支持整数,因此最终需要加上1补齐1970/01/01当天。
4.密码不可被变更的天数(与第3字段相比)
第四个字段记录了:这个帐号的密码在最近一次被更改后需要经过几天才可以再被变更!如果是0的话,表示密码随时可以更动的意思。这的限制是为了怕密码被某些人一改再改而设计的。如果设置为20天的话,那么当你设置了密码之后,20天之内都无法改变这个密码。
5.密码需要重新变更的天数(与第3字段相比)
为了强制要求使用者变更密码,这个字段可以指定在最近一次更改密码后,在多少天数内需要再次的变更密码才行。你必须要在这个天数内重新设置你的密码,否则这个帐号的密码将会“变为过期特性”。而如果像上面的99999(计算为273年)的话,那就表示,密码的变更没有强制性之意。
6.密码需要变更期限前的警告天数:(与第5字段相比)
当帐号的密码有效期限快要到的时候,系统会依据这个字段的设置,发出“警告”给这个帐号,提醒他“再过n天你的密码就要过期了,请尽快重新设置你的密码!”,如上面的例子,则是密码到期之前的7天之内,系统会警告该用户。
密码有效日期为“更新日期(第3字段)”+“重新变更日期(第5字段)”,过了该期限后使用者依旧没有更新密码,那该密码就算过期了。虽然密码过期但是该帐号还是可以用来进行其他工作的,包括登陆系统取得bash。不过如果密码过期了,那当你登陆系统时,系统会强制要求你必须要重新设置密码才能登陆继续使用,这就是密码过期特性。
那这个字段的功能是什么呢?是在密码过期几天后,如果使用者还是没有登陆更改密码,那么这个帐号的密码将会“失效”,亦即该帐号再也无法使用该密码登陆了。要注意密码过期与密码失效并不相同。
8.帐号失效日期
这个日期跟第三个字段一样,都是使用1970年以来的总日数设置。这个字段表示:这个帐号在此字段规定的日期之后,将无法再使用。就是所谓的“帐号失效”,此时不论你的密码是否有过期,这个“帐号”都不能再被使用!这个字段会被使用通常应该是在“收费服务”的系统中,你可以规定一个日期让该帐号不能再使用。
9.保留
最后一个字段是保留的,看以后有没有新功能加入。
由于shadow有这样的重要性,因此可不能随意修改。但在某些情况下面你得要使用各种方法来处理这个文件的。举例来说,常常听到人家说:“我的密码忘记了”,或者是“我的密码不晓得被谁改过,跟原先的不一样了”,这个时候怎么办?
另外,由于Linux的新旧版本差异颇大,旧的版本(CentOS5.x以前)还活在很多服务器内。因此,如果你想要知道shadow是使用哪种加密的机制时,可以通过下面的方法去查询:
/etc/group文件结构
/etc/group内容有点像这样:
[root@study~]#head-n4/etc/grouproot:x:0:bin:x:1:daemon:x:2:sys:x:3:这个文件每一行代表一个群组,也是以冒号“:”作为字段的分隔符号,共分为四栏,每一字段的意义是:
1.群组名称就是群组名称,同样用来给人类使用的,基本上需要与第三字段的GID对应。
2.群组密码通常不需要设置,这个设置通常是给“群组管理员”使用的,目前很少有这个机会设置群组管理员。同样的,密码已经移动到/etc/gshadow去,因此这个字段只会存在一个“x”而已;
3.GID就是群组的ID,/etc/passwd第四个字段使用的GID对应的群组名,就是由这里对应出来的。
4.此群组支持的帐号名称:一个帐号可以加入多个群组,那某个帐号想要加入此群组时,将该帐号填入这个字段即可。举例来说,如果我想要让dmtsai与alex也加入root这个群组,那么在第一行的最后面加上“dmtsai,alex”,注意不要有空格,使成为“root:x:0:dmtsai,alex”就可以。
有效群组(effectivegroup)与初始群组(initialgroup)
[root@study~]#usermod-a-Gusersdmtsai<==先设置好次要群组[root@study~]#grepdmtsai/etc/passwd/etc/group/etc/gshadow/etc/passwd:dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash/etc/group:wheel:x:10:dmtsai<==次要群组的设置、安装时指定的/etc/group:users:x:100:dmtsai<==次要群组的设置/etc/group:dmtsai:x:1000:<==因为是初始群组,所以第四字段不需要填入帐号/etc/gshadow:wheel:::dmtsai<==次要群组的设置/etc/gshadow:users:::dmtsai<==次要群组的设置/etc/gshadow:dmtsai:!!::仔细看到上面,在/etc/passwd里面,dmtsai这个使用者所属的群组为GID=1000,搜索一下/etc/group得到1000是那个名为dmtsai的群组,这就是initialgroup。因为是初始群组,使用者一登陆就会主动取得,不需要在/etc/group的第四个字段写入该帐号。
但是非initialgroup的其他群组可就不同了。举上面这个例子来说,我将dmtsai加入users这个群组当中,由于users这个群组并非是dmtsai的初始群组,因此,我必须要在/etc/group这个文件中,找到users那一行,并且将dmtsai这个帐号加入第四栏,这样dmtsai才能够加入users这个群组。
在这个例子当中,因为dmtsai帐号同时支持dmtsai,wheel与users这三个群组,因此,在读取/写入/可执行文件时,针对群组部分,只要是users,wheel与dmtsai这三个群组拥有的功能,dmtsai这个使用者都能够拥有。不过,这是针对已经存在的文件而言,如果今天我要创建一个新的文件或者是新的目录,请问一下,新文件的群组是dmtsai,wheel还是users?这就得要检查一下当时的有效群组了(effectivegroup)。
groups:有效与支持群组的观察
如果以dmtsai这个使用者的身份登陆后,该如何知道所有支持的群组呢?很简单,直接输入groups就可以了。
[dmtsai@study~]$groupsdmtsaiwheelusers在这个输出的信息中,可知道dmtsai这个用户同时属于dmtsai,wheel及users这三个群组,而且,第一个输出的群组即为有效群组(effectivegroup)了。也就是说,有效群组为dmtsai~此时,如果以touch去创建一个新文件,例如:“touchtest”,那么这个文件的拥有者为dmtsai,而且群组也是dmtsai。
[dmtsai@study~]$touchtest[dmtsai@study~]$lltest-rw-rw-r--.1dmtsaidmtsai0Jul2019:54test这样是否可以了解什么是有效群组了?通常有效群组的作用是在新建文件。那么有效群组是否能够变更?
newgrp:有效群组的切换
那么如何变更有效群组呢?就使用newgrp,不过使用newgrp是有限制的,那就是你想要切换的群组必须是你已经有支持的群组。举例来说,dmtsai可以在dmtsai/wheel/users这三个群组间切换有效群组,但是dmtsai无法切换有效群组成为sshd。使用的方式如下:
[dmtsai@study~]$newgrpusers[dmtsai@study~]$groupsuserswheeldmtsai[dmtsai@study~]$touchtest2[dmtsai@study~]$lltest*-rw-rw-r--.1dmtsaidmtsai0Jul2019:54test-rw-r--r--.1dmtsaiusers0Jul2019:56test2[dmtsai@study~]$exit#注意!记得离开newgrp的环境!此时,dmtsai的有效群组就成为users了。我们额外的来讨论一下newgrp这个指令,这个指令可以变更目前使用者的有效群组,而且是另外以一个shell来提供这个功能,所以,以上面的例子来说,dmtsai这个使用者目前是以另一个shell登陆的,而且新的shell给予dmtsai有效GID为users。如下图所示:
newgrp的运行示意图
虽然使用者的环境设置(例如环境变量等等其他数据)不会有影响,但是使用者的“群组权限”将会重新被计算。但是需要注意,由于是新取得一个shell,因此如果你想要回到原本的环境中,请输入exit回到原本的shell。
那么如何让一个帐号加入不同的群组。你要加入一个群组有两个方式,一个是通过系统管理员(root)利用usermod帮你加入,如果root太忙了而且你的系统有设置群组管理员,那么你可以通过群组管理员以gpasswd帮你加入他所管理的群组中。
/etc/gshadow
刚刚讲了很多关于“有效群组”的概念,另外,也提到newgrp这个指令的用法,但是,如果/etc/gshadow这个设置没有搞懂得话,那么newgrp是无法动作的。/etc/gshadow的内容有点像这样:
[root@study~]#head-n4/etc/gshadowroot:::bin:::daemon:::sys:::这个文件内同样还是使用冒号“:”来作为字段的分隔字符,而且你会发现,这个文件几乎与/etc/group一模一样~不过,要注意的大概就是第二个字段~第二个字段是密码栏,如果密码栏上面是“!”或空的时,表示该群组不具有群组管理员!至于第四个字段也就是支持的帐号名称~这四个字段的意义为:
以系统管理员的角度来说,这个gshadow最大的功能就是创建群组管理员,群组管理员能够将帐号加入自己管理的群组中。
既然要管理帐号,当然要有新增与移除使用者的操作。
帐号可以使用useradd来新建使用者,密码的给予则使用passwd这个指令。这两个指令下达方法如下:
useradd
范例一:完全参考默认值创建一个使用者,名称为vbird1[root@study~]#useraddvbird1[root@study~]#ll-d/home/vbird1drwx------.3vbird1vbird174Jul2021:50/home/vbird1#默认会创建使用者主文件夹,且权限为700!这是重点![root@study~]#grepvbird1/etc/passwd/etc/shadow/etc/group/etc/passwd:vbird1:x:1003:1004::/home/vbird1:/bin/bash/etc/shadow:vbird1:!!:16636:0:99999:7:::/etc/group:vbird1:x:1004:<==默认会创建一个与帐号一模一样的群组名
其实系统已经帮我们规定好非常多的默认值了,所以我们可以简单的使用“useradd帐号”来创建使用者即可。CentOS这些默认值主要会帮我们处理几个项目:
范例二:假设我已知道我的系统当中有个群组名称为users,且UID1500并不存在,请用users为初始群组,以及uid为1500来创建一个名为vbird2的帐号[root@study~]#useradd-u1500-gusersvbird2[root@study~]#ll-d/home/vbird2drwx------.3vbird2users74Jul2021:52/home/vbird2[root@study~]#grepvbird2/etc/passwd/etc/shadow/etc/group/etc/passwd:vbird2:x:1500:100::/home/vbird2:/bin/bash/etc/shadow:vbird2:!!:16636:0:99999:7:::#看一下,UID与initialgroup确实改变成我们需要的了!在这个范例中,我们创建的是指定一个已经存在的群组作为使用者的初始群组,因为群组已经存在,所以在/etc/group里面就不会主动的创建与帐号同名的群组了!此外,我们也指定了特殊的UID来作为使用者的专属UID。
了解了一般帐号后,来看看系统帐号(systemaccount)。
范例三:创建一个系统帐号,名称为vbird3[root@study~]#useradd-rvbird3[root@study~]#ll-d/home/vbird3ls:cannotaccess/home/vbird3:Nosuchfileordirectorya<==不会主动创建主文件夹[root@study~]#grepvbird3/etc/passwd/etc/shadow/etc/group/etc/passwd:vbird3:x:699:699::/home/vbird3:/bin/bash/etc/shadow:vbird3:!!:16636::::::/etc/group:vbird3:x:699:我们在谈到UID的时候曾经说过一般帐号应该是1000号以后,那使用者自己创建的系统帐号则一般是小于1000号以下的。所以在这里我们加上-r这个选项以后,系统就会主动将帐号与帐号同名群组的UID/GID都指定小于1000以下,在本案例中则是使用699(UID)与699(GID)。此外,由于系统帐号主要是用来进行运行系统所需服务的权限设置,所以系统帐号默认都不会主动创建主文件夹的!
由这几个范例我们知道,使用useradd创建使用者帐号时,其实会更改不少地方,至少我们就知道下面几个文件:
你有没有想过,为何“useraddvbird1”会主动在/home/vbird1创建起使用者的主文件夹?主文件夹内有什么数据来自哪里?为何默认使用的是/bin/bash这个shell?为何密码字段已经都规范好了(0:99999:7那一串)?这就得要说明一下useradd所使用的参考文件。
useradd参考文件
useradd的默认值可以使用下面的方法调用出来:
[root@study~]#useradd-DGROUP=100<==默认的群组HOME=/home<==默认的主文件夹所在目录INACTIVE=-1<==密码失效日,在shadow内的第7栏EXPIRE=<==帐号失效日,在shadow内的第8栏SHELL=/bin/bash<==默认的shellSKEL=/etc/skel<==使用者主文件夹的内容数据参考目录CREATE_MAIL_SPOOL=yes<==是否主动帮使用者创建邮件信箱(mailbox)这个数据其实是由/etc/default/useradd调用出来的!你可以自行用vim去观察该文件的内容。搭配上面刚刚谈过的范例一的运行结果,上面这些设置项目所造成的行为分别是:
系统上面GID为100即是users这个群组,此设置项目指的就是让新设使用者帐号的初始群组为users这一个的意思。但是我们知道CentOS上面并不是这样的,在CentOS上面默认的群组为与帐号名相同的群组。举例来说,vbird1的初始群组为vbird1。怎么会这样啊?这是因为针对群组的角度有两种不同的机制所致,这两种机制分别是:
系统会创建一个与帐号一样的群组给使用者作为初始群组。这种群组的设置机制会比较有保密性,这是因为使用者都有自己的群组,而且主文件夹权限将会设置为700(仅有自己可进入自己的主文件夹)之故。使用这种机制将不会参考GROUP=100这个设置值。代表性的distributions有RHEL,Fedora,CentOS等;
由于我们的CentOS使用私有群组机制,因此这个设置项目是不会生效的。
使用者的主文件夹通常是与帐号同名的目录,这个目录将会摆放在此设置值的目录后。所以vbird1的主文件夹就会在/home/vbird1/。
就是shadow内的第八字段,你可以直接设置帐号在哪个日期后就直接失效,而不理会密码的问题。通常不会设置此项目,但如果是付费的会员制系统,或许这个字段可以设置。
系统默认的shell就写在这里。假如你的系统为mailserver,你希望每个帐号都只能使用email的收发信件功能,而不许使用者登陆系统取得shell,那么可以将这里设置为/sbin/nologin,如此一来,新建的使用者默认就无法登陆,也免去后续使用usermod进行修改的操作!
指定使用者主文件夹的参考基准目录。以我们的范例一为例,vbird1主文件夹/home/vbird1内的各项数据,都是由/etc/skel所复制过去的~所以呢,未来如果我想要让新增使用者时,该使用者的环境变量~/.bashrc就设置妥当的话,可以到/etc/skel/.bashrc去编辑一下,也可以创建/etc/skel/www这个目录,那么未来新增使用者后,在他的主文件夹下就会有www那个目录了。
你可以使用“ll/var/spool/mail/vbird1”看一下,会发现有这个文件的存在,这就是使用者的邮件信箱。
除了这些基本的帐号设置值之外,UID/GID还有密码参数又是在哪里参考的呢?那就得要看一下/etc/login.defs啦!这个文件的内容有点像下面这样:
MAIL_DIR/var/spool/mail<==使用者默认邮件信箱放置目录PASS_MAX_DAYS99999<==/etc/shadow内的第5栏,多久需变更密码日数PASS_MIN_DAYS0<==/etc/shadow内的第4栏,多久不可重新设置密码日数PASS_MIN_LEN5<==密码最短的字符长度,已被pam模块取代,失去效用!PASS_WARN_AGE7<==/etc/shadow内的第6栏,过期前会警告的日数UID_MIN1000<==使用者最小的UID,意即小于1000的UID为系统保留UID_MAX60000<==使用者能够用的最大UIDSYS_UID_MIN201<==保留给使用者自行设置的系统帐号最小值UIDSYS_UID_MAX999<==保留给使用者自行设置的系统帐号最大值UIDGID_MIN1000<==使用者自订群组的最小GID,小于1000为系统保留GID_MAX60000<==使用者自订群组的最大GIDSYS_GID_MIN201<==保留给使用者自行设置的系统帐号最小值GIDSYS_GID_MAX999<==保留给使用者自行设置的系统帐号最大值GIDCREATE_HOMEyes<==在不加-M及-m时,是否主动创建使用者主文件夹?UMASK077<==使用者主文件夹创建的umask,因此权限会是700USERGROUPS_ENAByes<==使用userdel删除时,是否会删除初始群组ENCRYPT_METHODSHA512<==密码加密的机制使用的是sha512这一个机制!这个文件规范的数据则是如下所示:
使用者的默认mailbox文件放置的目录在/var/spool/mail,所以vbird1的mailbox就是在/var/spool/mail/vbird1。
通过PASS_MAX_DAYS等等设置值来指定的!所以你知道为何默认的/etc/shadow内每一行都会有“0:99999:7”的存在了吗?^_^!不过要注意的是,由于目前我们登陆时改用PAM模块来进行密码检验,所以那个PASS_MIN_LEN是失效的。
虽然Linux核心支持的帐号可高达232这么多个,不过一部主机要作出这么多帐号在管理上也是很麻烦的!所以在这里就针对UID/GID的范围进行规范就是了。上表中的UID_MIN指的就是可登陆系统的一般帐号的最小UID,至于UID_MAX则是最大UID之意。
要注意的是,系统给予一个帐号UID时,他是(1)先参考UID_MIN设置值取得最小数值;(2)由/etc/passwd搜寻最大的UID数值,将(1)与(2)相比,找出最大的那个再加一就是新帐号的UID了。我们上面已经作出UID为1500的vbird2,如果再使用“useraddvbird4”时,你猜vbird4的UID会是多少?答案是:1501。所以中间的1004~1499的号码就空下来啦!
而如果想要创建系统用的帐号,所以使用useradd-rsysaccount这个-r的选项时,就会找“比201大但比1000小的最大的UID”。
为何我们系统默认会帮使用者创建主文件夹?就是这个“CREATE_HOME=yes”的设置值啦!这个设置值会让你在使用useradd时,主动加入“-m”这个产生主文件夹的选项。如果不想要创建使用者主文件夹,就只能强制加上“-M”的选项在useradd指令执行时。至于创建主文件夹的权限设置呢?就通过umask这个设置值。因为是077的默认设置,因此使用者主文件夹默认权限才会是“drwx------”
使用“USERGROUPS_ENAByes”这个设置值的功能是:如果使用userdel去删除一个帐号时,且该帐号所属的初始群组已经没有人隶属于该群组了,那么就删除掉该群组,举例来说,我们刚刚有创建vbird4这个帐号,他会主动创建vbird4这个群组。若vbird4这个群组并没有其他帐号将他加入支持的情况下,若使用userdelvbird4时,该群组也会被删除的意思。至于“ENCRYPT_METHODSHA512”则表示使用SHA512来加密密码明文,而不使用旧式的MD5。
现在我们知道,使用useradd这支程序在创建Linux上的帐号时,至少会参考:
这些文件,不过,最重要的其实是创建/etc/passwd,/etc/shadow,/etc/group,/etc/gshadow还有使用者主文件夹就是了~所以,如果你了解整个系统运行的状态,也是可以手动直接修改这几个文件。OK!帐号创建了,接下来处理一下使用者的密码。
passwd
刚刚我们讲到了,使用useradd创建了帐号之后,在默认的情况下,该帐号是暂时被封锁的,也就是说,该帐号是无法登陆的,你可以去看看/etc/shadow内的第二个字段就知道了~那该如何是好?直接给他设置新密码就好了,设置密码使用passwd。
范例二:用vbird2登陆后,修改vbird2自己的密码[vbird2@study~]$passwd<==后面没有加帐号,就是改自己的密码!Changingpasswordforuservbird2.Changingpasswordforvbird2(current)UNIXpassword:<==这里输入“原有的旧密码”NewUNIXpassword:<==这里输入新密码BADPASSWORD:Thepasswordisshorterthan8characters<==密码太短!不可以设置!重新想Newpassword:<==这里输入新想的密码BADPASSWORD:Thepasswordfailsthedictionarycheck-itisbasedonadictionaryword#同样的,密码设置在字典里面找的到该字串,所以也是不建议!无法通过,再想新的!NewUNIXpassword:<==这里再想个新的密码来输入吧RetypenewUNIXpassword:<==通过密码验证!所以重复这个密码的输入passwd:allauthenticationtokensupdatedsuccessfully.<==有无成功看关键字passwd的使用要注意,尤其是root,passwd后面没有跟账户名,是在修改自己当前账户的密码。
与root不同的是,一般帐号在更改密码时需要先输入自己的旧密码(亦即current那一行),然后再输入新密码(New那一行)。要注意的是,密码的规范是非常严格的,尤其新的distributions大多使用PAM模块来进行密码的检验,包括太短、密码与帐号相同、密码为字典常见字串等,都会被PAM模块检查出来而拒绝修改密码,此时会再重复出现“New”这个关键字!那时请再想个新密码!若出现“Retype”才是你的密码被接受了!重复输入新密码并且看到“successfully”这个关键字时才是修改密码成功。
与一般使用者不同的是,root并不需要知道旧密码就能够帮使用者或root自己创建新密码!
为了方便系统管理,新版的passwd还加入了很多创意选项,比如“--stdin”了!举例来说,你想要帮vbird2变更密码成为abc543CC,可以这样下达指令:
范例三:使用standardinput创建用户的密码[root@study~]#echo"abc543CC"|passwd--stdinvbird2Changingpasswordforuservbird2.passwd:allauthenticationtokensupdatedsuccessfully.这个动作会直接更新使用者的密码而不用再次的手动输入!好处是方便处理,缺点是这个密码会保留在指令中,未来若系统被攻破,人家可以在/root/.bash_history找到这个密码。所以这个动作通常仅用在shellscript的大量创建使用者帐号当中。要注意的是,这个选项并不存在所有distributions版本中,请使用manpasswd确认你的distribution是否有支持此选项。
如果你想要让vbird2的密码具有相当的规则,举例来说你要让vbird2每60天需要变更密码,密码过期后10天未使用就宣告帐号失效,那该如何处理?
范例五:让vbird2的帐号失效,观察完毕后再让它失效[root@study~]#passwd-lvbird2[root@study~]#passwd-Svbird2vbird2LK2015-07-20060710(Passwordlocked.)#嘿嘿!状态变成“LK,Lock”了啦!无法登陆喔![root@study~]#grepvbird2/etc/shadowvbird2:!!$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10::#其实只是在这里加上!!而已![root@study~]#passwd-uvbird2[root@study~]#grepvbird2/etc/shadowvbird2:$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10::#密码字段恢复正常!chage
除了使用passwd-S之外,有没有更详细的密码参数显示功能呢?有的!那就是chage了!他的用法如下:
[root@study~]#chage[-ldEImMW]帐号名选项与参数:-l:列出该帐号的详细密码参数;-d:后面接日期,修改shadow第三字段(最近一次更改密码的日期),格式YYYY-MM-DD-E:后面接日期,修改shadow第八字段(帐号失效日),格式YYYY-MM-DD-I:后面接天数,修改shadow第七字段(密码失效日期)-m:后面接天数,修改shadow第四字段(密码最短保留天数)-M:后面接天数,修改shadow第五字段(密码多久需要进行变更)-W:后面接天数,修改shadow第六字段(密码过期前警告日期)范例一:列出vbird2的详细密码参数[root@study~]#chage-lvbird2Lastpasswordchange:Jul20,2015Passwordexpires:Sep18,2015Passwordinactive:Sep28,2015Accountexpires:neverMinimumnumberofdaysbetweenpasswordchange:0Maximumnumberofdaysbetweenpasswordchange:60Numberofdaysofwarningbeforepasswordexpires:7chage有一个功能很不错,如果你想要让“使用者在第一次登陆时,强制她们一定要更改密码后才能够使用系统资源”,可以利用如下的方法来处理的:
[root@study~]#usermod[-cdegGlsuLU]username选项与参数:-c:后面接帐号的说明,即/etc/passwd第五栏的说明栏,可以加入一些帐号的说明。-d:后面接帐号的主文件夹,即修改/etc/passwd的第六栏;-e:后面接日期,格式是YYYY-MM-DD也就是在/etc/shadow内的第八个字段数据啦!-f:后面接天数,为shadow的第七字段。-g:后面接初始群组,修改/etc/passwd的第四个字段,亦即是GID的字段!-G:后面接次要群组,修改这个使用者能够支持的群组,修改的是/etc/group啰~-a:与-G合用,可“增加次要群组的支持”而非“设置”喔!-l:后面接帐号名称。亦即是修改帐号名称,/etc/passwd的第一栏!-s:后面接Shell的实际文件,例如/bin/bash或/bin/csh等等。-u:后面接UID数字啦!即/etc/passwd第三栏的数据;-L:暂时将使用者的密码冻结,让他无法登陆。其实仅改/etc/shadow的密码栏。-U:将/etc/shadow密码栏的!拿掉,解冻啦!如果你仔细的比对,会发现usermod的选项与useradd非常类似。
整个指令的语法非常简单:
另外,其实使用者如果在系统上面操作过一阵子了,那么该使用者其实在系统内可能会含有其他文件的。举例来说,他的邮件信箱(mailbox)或者是例行性工作调度(crontab)之类的文件。所以,如果想要完整的将某个帐号完整的移除,最好可以在下达userdel-rusername之前,先以“find/-userusername”查出整个系统内属于username的文件,然后再加以删除。
不论是useradd/usermod/userdel,那都是系统管理员所能够使用的指令,如果我是一般身份使用者,那么我是否除了密码之外,就无法更改其他的数据呢?当然不是啦!这里我们介绍几个一般身份使用者常用的帐号数据变更与查询指令。
id
不过是否能够查阅到Mail与Plan则与权限有关了!因为Mail/Plan都是与使用者自己的权限设置有关,root当然可以查阅到使用者的这些信息,但是vbird1就不见得能够查到vbird3的信息,因为/var/spool/mail/vbird3与/home/vbird3/的权限分别是660,700,那vbird1当然就无法查阅的到。
此外,我们可以创建自己想要执行的预定计划,当然,最多是给自己看的,可以这样做:
chfn
chfn有点像是:changefinger的意思!这玩意的使用方法如下:
chsh
这就是changeshell的简写,使用方法就更简单。
[vbird1@study~]$chsh[-ls]选项与参数:-l:列出目前系统上面可用的shell,其实就是/etc/shells的内容!-s:设置修改自己的Shell范例一:用vbird1的身份列出系统上所有合法的shell,并且指定csh为自己的shell[vbird1@study~]$chsh-l/bin/sh/bin/bash/sbin/nologin<==所谓:合法不可登陆的Shell就是这玩意!/usr/bin/sh/usr/bin/bash/usr/sbin/nologin/bin/tcsh/bin/csh<==这就是Cshell啦!#其实上面的信息就是我们在bash中谈到的/etc/shells啦![vbird1@study~]$chsh-s/bin/csh;grepvbird1/etc/passwdChangingshellforvbird1.Password:<==确认身份,请输入vbird1的密码Shellchanged.vbird1:x:1003:1004:VBirdTsaitest,DICinKSU,06-2727175#356,06-1234567:/home/vbird1:/bin/csh[vbird1@study~]$chsh-s/bin/bash#测试完毕后,立刻改回来![vbird1@study~]$ll$(whichchsh)-rws--x--x.1rootroot23856Mar613:59/bin/chsh不论是chfn与chsh,都是能够让一般使用者修改/etc/passwd这个系统文件的!所以你猜猜,这两个文件的权限是什么?一定是SUID的功能(临时具备root权限)。
groupadd
[root@study~]#groupadd[-ggid][-r]群组名称选项与参数:-g:后面接某个特定的GID,用来直接给予某个GID~-r:创建系统群组啦!与/etc/login.defs内的GID_MIN有关。范例一:新建一个群组,名称为group1[root@study~]#groupaddgroup1[root@study~]#grepgroup1/etc/group/etc/gshadow/etc/group:group1:x:1503:/etc/gshadow:group1:!::#群组的GID也是会由1000以上最大GID+1来决定!groupmod
[root@study~]#groupmod[-ggid][-ngroup_name]群组名选项与参数:-g:修改既有的GID数字;-n:修改既有的群组名称范例一:将刚刚上个指令创建的group1名称改为mygroup,GID为201[root@study~]#groupmod-g201-nmygroupgroup1[root@study~]#grepmygroup/etc/group/etc/gshadow/etc/group:mygroup:x:201:/etc/gshadow:mygroup:!::不过,不要随意的更动GID,容易造成系统资源的错乱。
groupdel
删除群组
[root@study~]#groupdel[groupname]范例一:将刚刚的mygroup删除![root@study~]#groupdelmygroup范例二:若要删除vbird1这个群组的话?[root@study~]#groupdelvbird1groupdel:cannotremovetheprimarygroupofuser'vbird1'为什么mygroup可以删除,但是vbird1就不能删除呢?原因很简单,“有某个帐号(/etc/passwd)的initialgroup使用该群组!”如果查阅一下,你会发现在/etc/passwd内的vbird1第四栏的GID就是/etc/group内的vbird1那个群组的GID,当然无法删除~否则vbird1这个使用者登陆系统后,就会找不到GID,那可是会造成很大的困扰的!那么如果硬要删除vbird1这个群组呢?你“必须要确认/etc/passwd内的帐号没有任何人使用该群组作为initialgroup”才行!所以,你可以:
gpasswd:群组管理员功能
创建一个群组管理员,这个群组管理员可以管理哪些帐号可以加入/移出该群组。
任务一:单纯的完成上头交代的任务,假设我们需要的帐号数据如下
处理的方法如下所示:
任务二:我的使用者pro1,pro2,pro3是同一个组的开发人员,我想要让这三个用户在同一个目录下面工作,但这三个用户还是拥有自己的主文件夹与基本的私有群组。假设我要让这个组在/srv/projecta目录下开发。
#1.假设这三个帐号都尚未创建,可先创建一个名为projecta的群组,#再让这三个用户加入其次要群组的支持即可:[root@study~]#groupaddprojecta[root@study~]#useradd-Gprojecta-c"projectauser"pro1[root@study~]#useradd-Gprojecta-c"projectauser"pro2[root@study~]#useradd-Gprojecta-c"projectauser"pro3[root@study~]#echo"password"|passwd--stdinpro1[root@study~]#echo"password"|passwd--stdinpro2[root@study~]#echo"password"|passwd--stdinpro3#2.开始创建此专案的开发目录:[root@study~]#mkdir/srv/projecta[root@study~]#chgrpprojecta/srv/projecta[root@study~]#chmod2770/srv/projecta[root@study~]#ll-d/srv/projectadrwxrws---.2rootprojecta6Jul2023:32/srv/projecta由于只能够给pro1,pro2,pro3三个人使用,所以/srv/projecta的权限设置一定要正确才行!所以该目录群组一定是projecta,但是权限怎么会是2770呢?还记得之前谈到的SGID,为了让三个使用者能够互相修改对方的文件,这个SGID是必须要存在的。
但接下来有个困扰的问题发生了!假如任务一的myuser1是projecta这个组的助理,他需要这个专案的内容,但是他“不可以修改”专案目录内的任何数据。那该如何是好?你或许可以这样做:
传统的Linux权限无法针对某个个人设置专属的权限吗?其实是可以啦!接下来我们就来谈谈ACL这个功能吧。
有时候,除了本机的帐号之外,可能还会使用到其他外部的身份验证服务器所提供的验证身份的功能。举例来说,windows下面有个很有名的身份验证系统,称为ActiveDirectory(AD)的东西,还有Linux为了提供不同主机使用同一组帐号密码,也会使用到LDAP,NIS等服务器提供的身份验证等等。
CentOS提供一只名为authconfig-tui的指令给我们参考,这个指令的执行结果如下:
Linux的权限概念很重要,但是传统的权限仅有三种身份(owner,group,others)搭配三种权限(r,w,x)而已,并没有办法单纯的针对某一个使用者或某一个群组来设置特定的权限需求,例如2.4最后的那个任务,此时就得要使用ACL这个机制。
ACL(AccessControlList),主要的目的是在提供传统的owner,group,others的read,write,execute权限之外的详细权限设置。ACL可以针对单一使用者,单一文件或目录来进行r,w,x的权限规范,对于需要特殊权限的使用状况非常有帮助。
那ACL主要针对几个项目:
也就是说,如果你有一个目录,需要给一堆人使用,每个人或每个群组所需要的权限并不相同时,在过去,传统的Linux三种身份的三种权限是无法达到的,因为基本上,传统的Linux权限只能针对一个用户、一个群组及非此群组的其他人设置权限而已,无法针对单一用户或个人来设计权限,而ACL就是为了要改变这个问题。
如何启动ACL
事实上,原本ACL是unix-like操作系统的额外支持项目,但因为近年以来Linux系统对权限细部设置的热切需求,因此目前ACL几乎已经默认加入在所有常见的Linux文件系统的挂载参数中(ext2/ext3/ext4/xfs等等)!所以你无须进行任何动作,ACL就可以被你使用。不过,如果你不放心系统是否真的有支持ACL的话,那么就来检查一下核心挂载时显示的信息:
[root@study~]#dmesg|grep-iacl[0.330377]systemd[1]:systemd208runninginsystemmode.(+PAM+LIBWRAP+AUDIT+SELINUX+IMA+SYSVINIT+LIBCRYPTSETUP+GCRYPT+ACL+XZ)[0.878265]SGIXFSwithACLs,securityattributes,largeblock/inodenumbers,nodebugenabledxfs已经支持这个ACL的功能。
filesystem有支持ACL之后,利用这两个指令就可以了:
setfacl指令用法介绍及最简单的“u:帐号:权限”设置
[root@study~]#setfacl[-bkRd][{-m|-x}acl参数]目标文件名选项与参数:-m:设置后续的acl参数给文件使用,不可与-x合用;-x:删除后续的acl参数,不可与-m合用;-b:移除“所有的”ACL设置参数;-k:移除“默认的”ACL参数,关于所谓的“默认”参数于后续范例中介绍;-R:递回设置acl,亦即包括次目录都会被设置起来;-d:设置“默认acl参数”的意思!只对目录有效,在该目录新建的数据会引用此默认值上面谈到的是acl的选项功能,那么如何设置ACL的特殊权限呢?特殊权限的设置方法有很多,我们先来谈谈最常见的,就是针对单一使用者的设置方式:
#1.针对特定使用者的方式:#设置规范:“u:[使用者帐号列表]:[rwx]”,例如针对vbird1的权限规范rx:[root@study~]#touchacl_test1[root@study~]#llacl_test1-rw-r--r--.1rootroot0Jul2117:33acl_test1[root@study~]#setfacl-mu:vbird1:rxacl_test1[root@study~]#llacl_test1-rw-r-xr--+1rootroot0Jul2117:33acl_test1#权限部分多了个+,且与原本的权限(644)看起来差异很大!但要如何查阅呢?[root@study~]#setfacl-mu::rwxacl_test1[root@study~]#llacl_test1-rwxr-xr--+1rootroot0Jul2117:33acl_test1#设置值中的u后面无使用者列表,代表设置该文件拥有者,所以上面显示root的权限成为rwx了上述动作为最简单的ACL设置,利用“u:使用者:权限”的方式来设置的啦!设置前请加上-m这个选项。如果一个文件设置了ACL参数后,他的权限部分就会多出一个+号了,但是此时你看到的权限与实际权限可能就会有点误差。那要如何观察呢?就通过getfacl。
getfacl
[root@study~]#getfaclfilename选项与参数:getfacl的选项几乎与setfacl相同,所以这里就免去选项的说明。#请列出刚刚我们设置的acl_test1的权限内容:[root@study~]#getfaclacl_test1#file:acl_test1<==说明文档名而已!#owner:root<==说明此文件的拥有者,亦即ls-l看到的第三使用者字段#group:root<==此文件的所属群组,亦即ls-l看到的第四群组字段user::rwx<==使用者列表栏是空的,代表文件拥有者的权限user:vbird1:r-x<==针对vbird1的权限设置为rx,与拥有者并不同!group::r--<==针对文件群组的权限设置仅有rmask::r-x<==此文件默认的有效权限(mask)other::r--<==其他人拥有的权限!特定的单一群组的权限设置:“g:群组名:权限”
#2.针对特定群组的方式:#设置规范:“g:[群组列表]:[rwx]”,例如针对mygroup1的权限规范rx:[root@study~]#setfacl-mg:mygroup1:rxacl_test1[root@study~]#getfaclacl_test1#file:acl_test1#owner:root#group:rootuser::rwxuser:vbird1:r-xgroup::r--group:mygroup1:r-x<==这里就是新增的部分!多了这个群组的权限设置!mask::r-xother::r--针对有效权限设置:“m:权限”
基本上,群组与使用者的设置并没有什么太大的差异。不过,奇怪的是,那个mask是什么东西?其实他有点像是“有效权限”的意思!他的意义是:使用者或群组所设置的权限必须要存在于mask的权限设置范围内才会生效,此即“有效权限(effectivepermission)”我们举个例子来看,如下所示:
#3.针对有效权限mask的设置方式:#设置规范:“m:[rwx]”,例如针对刚刚的文件规范为仅有r:[root@study~]#setfacl-mm:racl_test1[root@study~]#getfaclacl_test1#file:acl_test1#owner:root#group:rootuser::rwxuser:vbird1:r-x#effective:r--<==vbird1+mask均存在者,仅有r而已,x不会生效group::r--group:mygroup1:r-x#effective:r--mask::r--other::r--例题:将2.4中任务二中/srv/projecta这个目录,让myuser1可以进入查阅,但myuser1不具有修改的权力。答:由于myuser1是独立的使用者与群组,因此无法使用传统的Linux权限设置。此时使用ACL的设置如下:
#1.先测试看看,使用myuser1能否进入该目录?[myuser1@study~]$cd/srv/projecta-bash:cd:/srv/projecta:Permissiondenied<==确实不可进入!#2.开始用root的身份来设置一下该目录的权限吧![root@study~]#setfacl-mu:myuser1:rx/srv/projecta[root@study~]#getfacl/srv/projecta#file:srv/projecta#owner:root#group:projecta#flags:-s-user::rwxuser:myuser1:r-x<==还是要看看有没有设置成功喔!group::rwxmask::rwxother::---#3.还是得要使用myuser1去测试看看结果![myuser1@study~]$cd/srv/projecta[myuser1@studyprojecta]$ll-adrwxrws---+2rootprojecta4096Feb2711:29.<==确实可以查询文件名drwxr-xr-x4rootroot4096Feb2711:29..[myuser1@studyprojecta]$touchtestingtouch:cannottouch`testing':Permissiondenied<==确实不可以写入接下来让我们来测试一下,如果我用root或者是pro1的身份去/srv/projecta增加文件或目录时,该文件或目录是否能够具有ACL的设置?意思就是说,ACL的权限设置是否能够被次目录所“继承?”先试看看:
[root@study~]#cd/srv/projecta[root@study~]#touchabc1[root@study~]#mkdirabc2[root@study~]#ll-dabc*-rw-r--r--.1rootprojecta0Jul2117:49abc1drwxr-sr-x.2rootprojecta6Jul2117:49abc你可以明显的发现,权限后面都没有+,代表这个acl属性并没有继承喔!如果你想要让acl在目录下面的数据都有继承的功能,那就得如下这样做了。
使用默认权限设置目录未来文件的ACL权限继承“d:[u|g]:[user|group]:权限”
#4.针对默认权限的设置方式:#设置规范:“d:[ug]:使用者列表:[rwx]”#让myuser1在/srv/projecta下面一直具有rx的默认权限![root@study~]#setfacl-md:u:myuser1:rx/srv/projecta[root@study~]#getfacl/srv/projecta#file:srv/projecta#owner:root#group:projecta#flags:-s-user::rwxuser:myuser1:r-xgroup::rwxmask::rwxother::---default:user::rwxdefault:user:myuser1:r-xdefault:group::rwxdefault:mask::rwxdefault:other::---[root@study~]#cd/srv/projecta[root@studyprojecta]#touchzzz1[root@studyprojecta]#mkdirzzz2[root@studyprojecta]#ll-dzzz*-rw-rw----+1rootprojecta0Jul2117:50zzz1drwxrws---+2rootprojecta6Jul2117:51zzz2#看吧!确实有继承喔!然后我们使用getfacl再次确认看看![root@studyprojecta]#getfaclzzz2#file:zzz2#owner:root#group:projecta#flags:-s-user::rwxuser:myuser1:r-xgroup::rwxmask::rwxother::---default:user::rwxdefault:user:myuser1:r-xdefault:group::rwxdefault:mask::rwxdefault:other::---通过这个“针对目录来设置的默认ACL权限设置值”的项目,我们可以让这些属性继承到次目录下面。
那如果想要让ACL的属性全部消失又要如何处理?通过“setfacl-b文件名”即可。
问:针对刚刚的/srv/projecta目录的权限设置中,我需要1.取消myuser1的设置(连同默认值),以及2.我不能让pro3这个用户使用该目录,亦即pro3在该目录下无任何权限,该如何设置?答:取消全部的ACL设置可以使用-b来处理,但单一设置值的取消,就得要通过-x才行。所以你应该这样作:
#1.1找到针对myuser1的设置值[root@study~]#getfacl/srv/projecta|grepmyuser1user:myuser1:r-xdefault:user:myuser1:r-x#1.2针对每个设置值来处理,注意,取消某个帐号的ACL时,不需要加上权限项目![root@study~]#setfacl-xu:myuser1/srv/projecta[root@study~]#setfacl-xd:u:myuser1/srv/projecta#2.1开始让pro3这个用户无法使用该目录[root@study~]#setfacl-mu:pro3:-/srv/projecta只需要留意,当设置一个用户/群组没有任何权限的ACL语法中,在权限的字段不可留白,而是应该加上一个减号(-)才是正确的作法。
我们都是使用一般帐号登陆系统的,等有需要进行系统维护或软件更新时才转为root的身份来动作。那如何让一般使用者转变身份成为root呢?主要有两种方式:
su是最简单的身份切换指令了,他可以进行任何身份的切换。
[root@study~]#su[-lm][-c指令][username]选项与参数:-:单纯使用-如“su-”代表使用login-shell的变量文件读取方式来登陆系统;若使用者名称没有加上去,则代表切换为root的身份。-l:与-类似,但后面需要加欲切换的使用者帐号!也是login-shell的方式。-m:-m与-p是一样的,表示“使用目前的环境设置,而不读取新使用者的配置文件”-c:仅进行一次指令,所以-c后面可以加上指令这个su的用法当中,有没有加上那个减号“-”差很多,因为涉及login-shell与non-loginshell的变量读取方法。这里让我们以一个小例子来说明:
范例二:使用loginshell的方式切换为root的身份并观察变量[dmtsai@study~]$su-Password:<==这里输入root的密码喔![root@study~]#env|greprootUSER=rootMAIL=/var/spool/mail/rootPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/binPWD=/rootHOME=/rootLOGNAME=root#了解差异了吧?下次变换成为root时,记得最好使用su-[root@study~]#exit<==这样可以离开su的环境!那我如果只是想要执行“一个只有root才能进行的指令,且执行完毕就恢复原本的身份”呢?那就可以加上-c这个选项。
范例三:dmtsai想要执行“head-n3/etc/shadow”一次,且已知root密码[dmtsai@study~]$head-n3/etc/shadowhead:cannotopen`/etc/shadow'forreading:Permissiondenied[dmtsai@study~]$su--c"head-n3/etc/shadow"Password:<==这里输入root的密码喔!root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhOYO62vDnqfLw85...:16559:0:99999:7:::bin:*:16372:0:99999:7:::daemon:*:16372:0:99999:7:::[dmtsai@study~]$<==注意看,身份还是dmtsai如果我是root或者是其他人,想要变更成为某些特殊帐号,可以使用如下的方法来切换:
范例四:原本是dmtsai这个使用者,想要变换身份成为vbird1时?[dmtsai@study~]$su-lvbird1Password:<==这里输入vbird1的密码[vbird1@study~]$su-Password:<==这里输入root的密码[root@study~]#idsshduid=74(sshd)gid=74(sshd)groups=74(sshd)...<==确实有存在此人[root@study~]#su-lsshdThisaccountiscurrentlynotavailable.<==竟然说此人无法切换?[root@study~]#fingersshdLogin:sshdName:Privilege-separatedSSHDirectory:/var/empty/sshdShell:/sbin/nologin[root@study~]#exit<==离开第二次的su[vbird1@study~]$exit<==离开第一次的su[dmtsai@study~]$exit<==这才是最初的环境总结一下su的用法是这样的:
对于su需要了解新切换的使用者密码(常常是需要root的密码),sudo的执行则仅需要自己的密码即可。甚至可以设置不需要密码即可执行sudo,由于sudo可以让你以其他用户的身份执行指令(通常是使用root的身份来执行指令),因此并非所有人都能够执行sudo,而是仅有规范到/etc/sudoers内的用户才能够执行sudo这个指令。
事实上,一般用户能够具有sudo的使用权,就是管理员事先审核通过后,才开放sudo的使用权的。因此,除非是信任用户,否则一般用户默认是不能操作sudo的。
但是平时明明创建账户后能用sudo,这是因为创建帐号的时候,默认将此用户加入sudo的支持中了。
sudo的指令用法
由于一开始系统默认仅有root可以执行sudo,因此下面的范例我们先以root的身份来执行,等到谈到visudo时,再以一般使用者来讨论其他sudo的用法吧。sudo的语法如下:
[root@study~]#sudo[-b][-u新使用者帐号]选项与参数:-b:将后续的指令放到背景中让系统自行执行,而不与目前的shell产生影响-u:后面可以接欲切换的使用者,若无此项则代表切换身份为root。范例一:你想要以sshd的身份在/tmp下面创建一个名为mysshd的文件[root@study~]#sudo-usshdtouch/tmp/mysshd[root@study~]#ll/tmp/mysshd-rw-r--r--.1sshdsshd0Jul2123:37/tmp/mysshd#特别留意,这个文件的权限是由sshd所创建的情况喔!范例二:你想要以vbird1的身份创建~vbird1/www并于其中创建index.html文件[root@study~]#sudo-uvbird1sh-c"mkdir~vbird1/www;cd~vbird1/www;\>echo'Thisisindex.htmlfile'>index.html"[root@study~]#ll-a~vbird1/wwwdrwxr-xr-x.2vbird1vbird123Jul2123:38.drwx------.6vbird1vbird14096Jul2123:38..-rw-r--r--.1vbird1vbird124Jul2123:38index.html#要注意,创建者的身份是vbird1,且我们使用sh-c"一串指令"来执行的sudo可以让你切换身份来进行某项任务,例如上面的两个范例。范例一中,我们的root使用sshd的权限去进行某项任务!要注意,因为我们无法使用“su-sshd”去切换系统帐号(因为系统帐号的shell是/sbin/nologin)。
但是sudo默认仅有root能使用,为什么呢?因为sudo的执行是这样的流程:
由于能否使用与/etc/sudoers有关,所以我们当然要去编辑sudoers文件。不过,因为该文件的内容是有一定的规范的,因此直接使用vi去编辑是不好的。此时,我们得要通过visudo去修改这个文件。
visudo与/etc/sudoers
从上面的说明我们可以知道,除了root之外的其他帐号,若想要使用sudo执行属于root的权限指令,则root需要先使用visudo去修改/etc/sudoers,让该帐号能够使用全部或部分的root指令功能。为什么要使用visudo呢?这是因为/etc/sudoers是有设置语法的,如果设置错误那会造成无法使用sudo指令的不良后果。因此才会使用visudo去修改,并在结束离开修改画面时,系统会去检验/etc/sudoers的语法
一般来说,visudo的设置方式有几种简单的方法,下面我们以几个简单的例子来分别说明:
1.单一使用者可进行root所有指令,与sudoers文件语法:
假如我们要让vbird1这个帐号可以使用root的任何指令,基本上有两种作法,第一种是直接通过修改/etc/sudoers,方法如下:
[root@study~]#visudo....(前面省略)....rootALL=(ALL)ALL<==找到这一行,大约在98行左右vbird1ALL=(ALL)ALL<==这一行是你要新增的!....(下面省略)....其实visudo只是利用vi将/etc/sudoers文件调用出来进行修改而已,如上面所示,如果你找到98行(有root设置的那行)左右,看到的数据就是:
那个ALL是特殊的关键字,代表任何身份、主机或指令的意思。所以,我想让vbird1可以进行任何身份的任何指令,就如同上表特殊字体写的那样,其实就是复制上述默认值那一行,再将root改成vbird1即可。此时“vbird1不论来自哪部主机登陆,他可以变换身份成为任何人,且可以进行系统上面的任何指令”之意。
2.利用wheel群组以及免密码的功能处理visudo
我们在本章前面曾经创建过pro1,pro2,pro3,这三个用户能否通过群组的功能让这三个人可以管理系统?可以的,同样我们使用实际案例来说明:
[root@study~]#visudo<==同样的,请使用root先设置....(前面省略)....%wheelALL=(ALL)ALL<==大约在106行左右,请将这行的#拿掉!#在最左边加上%,代表后面接的是一个“群组”之意!改完请储存后离开[root@study~]#usermod-a-Gwheelpro1<==将pro1加入wheel的支持上面的设置值会造成“任何加入wheel这个群组的使用者,就能够使用sudo切换任何身份来操作任何指令”的意思。你当然可以将wheel换成你自己想要的群组名。
从CentOS7开始,在sudoers文件中,默认已经开放%wheel那一行。
不过,既然我们都信任这些sudo的用户了,能否提供“不需要密码即可使用sudo”呢?就通过如下的方式:
[root@study~]#visudo<==同样的,请使用root先设置....(前面省略)....%wheelALL=(ALL)NOPASSWD:ALL<==大约在109行左右,请将#拿掉!#在最左边加上%,代表后面接的是一个“群组”之意!改完请储存后离开那个NOPASSWD,该关键字是免除密码输入的意思。
3.有限制的指令操作
上面两点都会让使用者能够利用root的身份进行任何事情,这样总是不太好~如果我想要让使用者仅能够进行部分系统任务,比方说,系统上面的myuser1仅能够帮root修改其他使用者的密码时,亦即“当使用者仅能使用passwd这个指令帮忙root修改其他用户的密码”时,可以这样做:
[root@study~]#visudo<==注意是root身份myuser1ALL=(root)/usr/bin/passwd<==最后指令务必用绝对路径上面的设置值指的是“myuser1可以切换成为root使用passwd这个指令”的意思。其中要注意的是:指令字段必须要填写绝对路径才行,否则visudo会出现语法错误的状况发生。此外,上面的设置是有问题的!我们使用下面的指令操作来了解:
[myuser1@study~]$sudopasswdmyuser3<==注意,身份是myuser1[sudo]passwordformyuser1:<==输入myuser1的密码Changingpasswordforusermyuser3.<==下面改的是myuser3的密码喔!这样是正确的Newpassword:Retypenewpassword:passwd:allauthenticationtokensupdatedsuccessfully.[myuser1@study~]$sudopasswdChangingpasswordforuserroot.<==见鬼!怎么会去改root的密码?竟然root的密码被myuser1给改变了!所以我们必须要限制使用者的指令参数,修改的方法为:
[root@study~]#visudo<==注意是root身份myuser1ALL=(root)!/usr/bin/passwd,/usr/bin/passwd[A-Za-z]*,!/usr/bin/passwdroot在设置值中加上惊叹号“!”代表“不可执行”的意思。因此上面这一行会变成:可以执行“passwd任意字符”,但是“passwd”与“passwdroot”这两个指令例外。如此一来myuser1就无法改变root的密码了,这样这位使用者可以具有root的能力帮助你修改其他用户的密码,而且也不能随意改变root的密码。
4.通过别名创建visudo
如果我有多个用户需要加入刚刚的管理员行列,那么我要将上述那长长的设置写入很多,而且如果想要修改命令或者是新增命令时,那我每行都需要重新设置,很麻烦!有没有更简单的方式?通过别名即可!visudo的别名可以是“指令别名、帐号别名、主机别名”等。不过这里我们仅介绍帐号别名,其他的设置值有兴趣的话,可以自行玩玩。
假设我的pro1,pro2,pro3与myuser1,myuser2要加入上述的密码管理员的sudo列表中,那我可以创立一个帐号别名称为ADMPW的名称,然后将这个名称处理一下即可。处理的方式如下:
两次执行sudo的间隔在五分钟内,那么再次执行sudo时就不需要再次输入密码了,这是因为系统相信你在五分钟内不会离开你的作业,所以执行sudo的是同一个人。
6.sudo搭配su的使用方式
很多时候我们需要大量执行很多root的工作,所以一直使用sudo觉得很烦。那有没有办法使用sudo搭配su,一口气将身份转为root,而且还用使用者自己的密码来变成root呢?是有的!而且方法简单的会让你想笑!我们创建一个ADMINS帐号别名,然后这样做:
[root@study~]#visudoUser_AliasADMINS=pro1,pro2,pro3,myuser1ADMINSALL=(root)/bin/su-接下来,上述的pro1,pro2,pro3,myuser1这四个人,只要输入“sudosu-”并且输入“自己的密码”后,立刻变成root的身份。不但root密码不会外流,使用者的管理也变的非常方便。
另外,在本章之前谈到过/etc/login.defs文件中,关于密码长度应该默认是5个字串长度,但是我们上面也谈到,该设置值已经被PAM模块所取代了,那么PAM是什么?为什么他可以影响我们使用者的登陆呢?
系统帐号是不需要登陆的,它在passwd文件中显示shell使用的是/sbin/nologin,所以我们就给他这个无法登陆的合法shell。使用了这个shell的用户即使有了密码,你想要登陆时也无法登陆,因为会出现如下的信息:
Thisaccountiscurrentlynotavailable.
所谓的“无法登陆”指的仅是:“这个使用者无法使用bash或其他shell来登陆系统”,并不是说这个帐号就无法使用其他的系统资源。
另外,如果我想要让某个具有/sbin/nologin的使用者知道,他们不能登陆主机时,其实可以创建“/etc/nologin.txt”这个文件,并且在这个文件内说明不能登陆的原因,那么下次当这个使用者想要登陆系统时,屏幕上出现的就会是/etc/nologin.txt这个文件的内容,而不是默认的内容了。
[root@study~]#vim/etc/nologin.txtThisaccountissystemaccountormailaccount.PleaseDONOTusethisaccounttologinmyLinuxserver.[root@study~]#su-myuser3Thisaccountissystemaccountormailaccount.PleaseDONOTusethisaccounttologinmyLinuxserver.5.2PAM模块简介在过去,我们想要对一个使用者进行认证(authentication),得要求使用者输入帐号密码,然后通过自行编写的程序来判断该帐号密码是否正确。也因为如此,我们常常得使用不同的机制来判断帐号密码,所以搞的一部主机上面拥有多个各别的认证系统,也造成帐号密码可能不同步的验证问题。为了解决这个问题因此有了PAM(PluggableAuthenticationModules,嵌入式模块)的机制。
PAM是一套应用程序接口(ApplicationProgrammingInterface,API),他提供了一连串的验证机制,只要使用者将验证阶段的需求告知PAM后,PAM就能够回报使用者验证的结果(成功或失败)。由于PAM仅是一套验证的机制,又可以提供给其他程序所调用引用,因此不论你使用什么程序,都可以使用PAM来进行验证,如此一来,就能够让帐号密码或者是其他方式的验证具有一致的结果。
PAM用来进行验证的数据称为模块(Modules),每个PAM模块的功能都不太相同。
PAM借助一个与程序相同文件名的配置文件来进行一连串的认证分析需求。以passwd这个指令的调用PAM来说明好了。当你执行passwd后,这支程序调用PAM的流程是:
重点其实是/etc/pam.d/里面的配置文件,以及配置文件所调用的PAM模块进行的验证工作。既然一直谈到passwd这个密码修改指令,那我们就来看看/etc/pam.d/passwd这个配置文件的内容。
[root@study~]#cat/etc/pam.d/passwd#%PAM-1.0<==PAM版本的说明而已!authincludesystem-auth<==每一行都是一个验证的过程accountincludesystem-authpasswordsubstacksystem-auth-passwordoptionalpam_gnome_keyring.souse_authtokpasswordsubstackpostlogin验证类别控制标准PAM模块与该模块的参数上面出现的“include”这个关键字,他代表的是“请调用后面的文件来作为这个类别的验证”,所以,上述的每一行都要重复调用/etc/pam.d/system-auth那个文件来进行验证的意思。
第一个字段:验证类别(Type)
验证类别主要分为四种,分别说明如下:
authentication(认证)的缩写,所以这种类别主要用来检验使用者的身份验证,这种类别通常是需要密码来检验的,所以后续接的模块是用来检验使用者的身份。
session(会话期间),所以session管理的就是使用者在这次登陆(或使用这个指令)期间,PAM所给予的环境设置。这个类别通常用在记录使用者登陆与登出时的信息。
password就主要在提供密码的验证修改工作。
这四个验证的类型通常是有顺序的。
第二个字段:验证的控制标识(controlflag)
验证通过的标准,这个字段在管控该验证的放行方式,主要也分为四种控制方式:
若验证失败则立刻回报原程序failure的标志,并终止后续的验证流程。若验证成功则带有success的标志并继续后续的验证流程。这个项目与required最大的差异,就在于失败就终止。
若验证成功则立刻回传success给原程序,并终止后续的验证流程;若验证失败则带有failure标志并继续后续的验证流程,与requisits刚好相反。
这个模块控制项目大多是在显示信息而已,并不是用在验证方面的。
登陆所需要的PAM流程为何:
cat/etc/pam.d/login
可以看到,其实login也调用多次的system-auth
cat/etc/pam.d/system-auth
详细的模块情报可以在你的系统中找到:
CentOS7,pam_nologin说明文档在:/usr/share/doc/pam-1.1.8/txts/README.pam_nologin
limits.conf
之前说过的ulimit功能中,除了修改使用者的~/.bashrc配置文件之外,其实系统管理员可以统一借由PAM来管理的,那就是/etc/security/limits.conf这个文件的设置了。
/var/log/secure,/var/log/messages
如果发生任何无法登陆或者是产生一些你无法预期的错误时,由于PAM模块都会将数据记载在/var/log/secure当中。
在多人使用同一Linux下的情况。
那如果想要知道目前已登陆在系统上面的使用者呢?可以通过w或who来查询。
[root@study~]#lastlogUsernamePortFromLatestrootpts/0WedJul2200:26:08+08002015bin**Neverloggedin**....(中间省略)....dmtsaipts/1192.168.1.100WedJul2201:08:07+08002015vbird1pts/0WedJul2201:32:17+08002015pro3**Neverloggedin**....(以下省略)....6.2用户对谈:write,mesg,wallwrite可以直接将讯息传给接收者。
举例来说,Linux目前有vbird1与root两个人在线上,我的root要跟vbird1讲话,可以这样做:
[root@study~]#write使用者帐号[使用者所在终端接口][root@study~]#whovbird1tty32015-07-2201:55<==有看到vbird1在线上roottty42015-07-2201:56[root@study~]#writevbird1pts/2Hello,there:Pleasedon'tdoanythingwrong...<==这两行是root写的信息!#结束时,请按下[crtl]-d来结束输入。此时在vbird1的画面中,会出现:Messagefromroot@study.centos.vbirdontty4at01:57...Hello,there:Pleasedon'tdoanythingwrong...EOF立刻会将信息传给vbird1,不过如果当vbird1正在查数据,这些信息会立刻打断vbird1原本的工作。所以,如果vbird1这个人不想要接受任何讯息,直接下达这个动作:
[vbird1@study~]$mesgn[vbird1@study~]$mesgisn不过,这个mesg的功能对root传送来的信息无效,所以如果是root传送讯息,vbird1还是得要收下。
但是如果root的mesg是n的,那么vbird1写给root的信息会变这样:
[vbird1@study~]$writerootwrite:roothasmessagesdisabled如果想要解开的话,再次下达“mesgy”就好啦!想要知道目前的mesg状态,直接下达“mesg”即可。
如果对所有系统上面的用户传送简讯(广播)”,用wall即可啊!他的语法也是很简单:
[root@study~]#wall"Iwillshutdownmylinuxserver..."所有的人都会收到这个简讯,连发送者自己也会收到。
使用wall,write毕竟要等到使用者在线上才能够进行,有没有其他方式来联络?不是说每个Linux主机上面的使用者都具有一个mailbox吗?我们可以寄、收mailbox内的信件。一般来说,mailbox都会放置在/var/spool/mail里面,一个帐号一个mailbox(文件)。
寄信可以这么写mail-s"邮件标题"username@localhost一般来说,如果是寄给本机上的使用者,基本上,连“@localhost”都不用写。
[root@study~]#mail-s"nicetomeetyou"vbird1Hello,D.M.TsaiNicetomeetyouinthenetwork.Youaresonice.byebye!.<==这里很重要喔,结束时,最后一行输入小数点.即可!EOT[root@study~]#<==出现提示字符,表示输入完毕了!还可以使用数据量重导向来完成。
mail-s"nicetomeetyou"vbird1 收信的话,输入mail [vbird1@study~]$mailHeirloomMailversion12.57/5/10.Typeforhelp."/var/spool/mail/vbird1":1message1new>N1rootWedJul2202:0920/671"nicetomeetyou"&<==这里可以输入很多的指令,如果要查阅,输入即可!在mail当中的提示字符是&符号,这封信件的前面那个>代表目前处理的信件,而在大于符号的右边那个N代表该封信件尚未读过。 如果我想要知道这个mail内部的指令有哪些,可以在&之后输入“”,就可以看到如下的画面: &mailcommandstype 先来检查看看使用者的主文件夹、密码等数据有没有问题?这时会使用到的主要有pwck以及pwconv/pwuconv等。 pwck pwck这个指令会检查/etc/passwd这个帐号配置文件内的信息,与实际的主文件夹是否存在等信息,还可以比对/etc/passwd与/etc/shadow的信息是否一致,另外,如果/etc/passwd内的数据字段错误时,会提示使用者修改。一般来说,只利用这个来检查输入是否正确。 [root@study~]#pwckuser'ftp':directory'/var/ftp'doesnotexistuser'avahi-autoipd':directory'/var/lib/avahi-autoipd'doesnotexistuser'pulse':directory'/var/run/pulse'doesnotexistpwck:nochanges上面仅是告知我,这些帐号并没有主文件夹,由于那些帐号绝大部分都是系统帐号,确实也不需要主文件夹的,所以,那是“正常的错误!”。 相对应的群组检查可以使用grpck这个指令。 pwconv 这个指令主要的目的是在“将/etc/passwd内的帐号与密码,移动到/etc/shadow当中。早期的Unix系统当中并没有/etc/shadow。 使用pwconv后,可以: 一般来说,如果正常使用useradd增加使用者时,使用pwconv并不会有任何的动作。不过,如果手动设置帐号,这个pwconv就很重要。 pwunconv 相对于pwconv,pwunconv则是将/etc/shadow内的密码栏数据写回/etc/passwd当中,并且删除/etc/shadow文件。 最好不要使用! chpasswd chpasswd可以“读入未加密前的密码,并且经过加密后,将加密后的密码写入/etc/shadow当中。”这个指令很常被使用在大量创建帐号的情况中。他可以由Standardinput读入数据,每笔数据的格式是“username:password”。 举例来说,我的系统当中有个使用者帐号为vbird3,我想要更新他的密码(update),假如他的密码是abcdefg的话,那么我可以这样做: echo"vbird3:abcdefg"|chpasswd 简单的script来执行新增用户。 [root@study~]#vimaccountadd.txtstd01std02std03std04std05[root@study~]#shaccountadd.shcreateChangingpasswordforuserstd01.passwd:allauthenticationtokensupdatedsuccessfully.....(后面省略)....