写在前面:
原本想从创建、修改、删除用户和组的相关工具与配置文件来记录这部分内容,但是我认为这种应用层面的东西,没有什么理论的东西值得记录,无非就是工具的使用。若要写起来,也只能是以各种例子来说明各种选项的作用,就像那谁的私房里的菜一样,而再怎么写,都还不如info页上的清晰明了。我觉得工具的学习,该是看过info页和--help上的信息后,了解到这个命令是干什么工作的,等到要实现相关功能的时候,知道用什么命令就行了,细节上的选项,到时候再查help却也不迟。所以这篇我重点记录sudo的配置文件的内容说明,而其它用户管理相关的工具,我偏向一笔带过。
出于管理与安全的需要,有时候需要切换到root账号或其它账号以进行相关的工作。有两个命令可以实现用户的切换,su与sudo。
su的使用很简单:
su [OPTION]... [USER [ARG]...]
没有指定用户则是?认切换到root。su?认是非no-login shell方式执行的,若让它以login shell方式执行,则要带上-l或-(dash)选项执行。我现在的理解这两种shell的区别就是login shell能得到目标用户环境。
如果以su切换到root,需要用户输入root的密码,这显然是不合理的。而sudo允许一个在/etc/sudoers被授权的用户以root或其它用户的身份来执行命令,只需要自己的密码或者不用密码。
如果简单的要让一个用户能使用sudo来执行命令,只需要在/etc/sudoers里添加这样一行就行,建议的是用visudo命令来编辑这个文件,说是为了语法的正确:
ALL ALL = (ALL) ALL
或者更简单写成这样:
ALL ALL = ALL
你可以用sudo -v来测试你是否已经在/etc/sudoers被授权。sudo为了安全,?认15分钟之后本次的授权就会超时,若要继续就要重新验证身份。这条命令的作用就是更新用户的时间戳,而不执行命令。
$ sudo -v
Sorry, user Guin may not run sudo. <==Guin未被授权
$ sudo -v
[sudo] password for Guin: <==待我‘su -’到root添加上述语句之后可用
sudoers里用户授权规则的语法形式就是上面这条语句这个样子的。ALL是sudoers里的一个关键字,它匹配一切。sudoers里授权规则的基本结构可以描述为:
谁 在哪 = (代表谁) 干什么 <== who where = (as_whom) what
上面这个括号是语法里的一部分,如果要这部分,就是要加上括号的。可以知道,ALL ALL = ALL 的意思是任何人可以在任何主机上执行任何命令。显然这非常的BUG,对于个人也许无所谓,但对于Linux这个中央集权的世界,这种让普通人拥有无限权利的语句是让人非常不安的。
下面是关于sudoers这个文件内容的简单说明。一些概念的描述会用到EBNF符号集,它的规则类似于层层剥离的来解释东西。事实上用EBNF解释似乎使问题更复杂,我只是觉得多了解一新事物没什么不好。EBNF的语法规则很简单,是这样的:
symbol ::= definition | alternate1 | alternate2...
‘::=’ 这个符号的意思可以翻译为“就是”,‘|’ 的意思是“或者”。这个语句解释为:symbol这个东西就是definition,或者也可以是 alternate1, 或者也可以是 alternate2 等等。EBNF会用到一些算符,规则与正则表达式一样:
? 前面的符号可以出现0次或1次
* 前面的符号可以出现0次以上
+ 前面的符号可以出现1次以上
() 里面的是符号组
‘’ 单引号里面的是字面引用
sudoers里的内容可以概括为主要由两部分内容组成:别名与授权规则。
授权规则里的who where as_whom what都可以定义别名。就像定义变量那样,用User_Alias, Host_Alias, Runas_Alias,Cmnd_Alias这四个别名类型关键字分别定义用户、主机、对象、命令的别名。用EBNF表示别名如下:
别名 ::= 'User_Alias' 用户别名 (':' 用户别名)* |
'Runas_Alias' 对象别名 (':' 对象别名)* |
'Host_Alias' 主机别名 (':' 主机别名)* |
'Cmnd_Alias' 命令别名 (':' 命令别名)*
用户别名 ::= 大写名字 '=' 用户表
对象别名 ::= 大写名字 '=' 对象表
主机别名 ::= 大写名字 '=' 主机表
命令别名 ::= 大写名字 '=' 命令表
大写名字 ::= [A-Z]([A-Z][0-9]_)*
之上也不好解释,理解了EBNF就自然懂了,可以解释为:别名就是‘某别名类型 某别名‘这种形式的,有四种情况。某别名就是’大写名字 = 某‘这种形式的。大写名字要大写字母或大写字母加上数字或加上下划线。
每个别名用这种形式定义:
别名类型 大写名字 = 项目1, 项目2, ...
可以把同类型的别名定义放在同一行,用冒号隔开:
别名类型 大写名字 = 项目1, 项目2, 项目3 :大写名字 = 项目4, 项目5
在用户别名中的用户表,可以直接是一个或多个用户名。还可以是#uid,或者是%组名,+网络组,%:非unix组。也可以是另一个用户别名。用户表中的项目可以在其前面加上奇数个!来表示否定它,偶数个就好像没有叹号一样。这些项目还可以带上双引号来避免特殊字符的转义。对象别名与用户别名本质上是一样的,都表达的是一些用户。
用户表 ::= 用户 | 用户 ',' 用户表
用户 ::= '!'* 用户名 | '!'* '#'uid | '!'* '%'组名 |
'!'* '+'网络组 | '!'* '%:'非unix组 |'!'* 用户别名
针对上面的内容,作一些示例:
# User alias specification
User_Alias FULLTIMERS = millert, mikef, dowdy
User_Alias PARTTIMERS = bostley, jwfox, crawl
# Runas alias specification
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, sybase
了解了这些可以对原来的3ALL语句通过定义用户别名来改写一下:
User_Alias GUIN = Guin
Runas_Alias OP = root
GUIN ALL = (OP) ALL
这条语句指别名GUIN里指定的用户可以在任何主机上代表OP里指定的用户执行任何命令,也就是说,Guin可以在在任何主机上代表root执行任何命令。下面这样也是正确的:
User_Alias GUIN = Guin
User_Alias GUIN1 = GUIN
Runas_Alias OP = root
GUIN1 ALL = (OP) ALL
各种别名的定义形式上是一样的,不用的是各自的表中所能带的内容不同而已。主机别名中的主机可以主机名、IP地址、网络组等;命令别名中的命令可以是文件,也可以是目录。EBNF表示如下:
主机表 ::= 主机 |
主机 ',' 主机表
主机 ::= '!'* 主机名 |
'!'* IP地址 |
'!'* network(/netmask)? |
'!'* '+'网络组 |
'!'* 主机别名
命令表 ::= 命令 | 命令 ',' 命令表
命令 ::= '!'* 命令名 |'!'* 目录 | '!'* "sudoedit" | '!'* 命令别名
命令名 ::= 文件名 | 文件名 参数 | 文件名 '""'
命令表中只有文件名就表示可以带任何参数执行;文件名 “” 表示这个命令不可以带参数执行;目录名要以/结尾,指定了目录用户就可以执行这个目录下的所有文件,但不包括子目录里的。主机名、路径名和命令参数允许使用通配符。/usr/bin/* 匹配/usr/bin/who 但不匹配/usr/bin/X11/xterm 也就是说,/(slash)不会被匹配。如下对原来的sudoers文件继续改写:
User_Alias GUIN = Guin
Host_Alias GN = host_name <==host_name代表主机名
Runas_Alias OP = root
Cmnd_Alias RV06 = /sbin/halt, /sbin/shutdown, /sbin/reboot
Cmnd_Alias SU01 = /bin/su ""
GUIN GN = (OP) RV06 <==GUIN里的用户可以在GN上代表OP执行RV06里的命令
GUIN GN = (OP) SU01 <==只能不带参数执行su
%Guin GN = !/usr/bin/passwd root <==Guin这组的人将不能修改root的密码,Guin这里是个组名
上面的最后三条就是授权规则,由它决定什么用户可以在哪台主机执行什么命令。它的EBNF表示为:
授权规则 ::= 用户表 主机表 '=' 特定命令表 (':' 主机表 '=' 特定命令表)*
比如如上其中两条可以写成这样 Guin GN = RV06 : GN = SU01
特定命令表 ::= 特定命令 | 特定命令 ',' 特定命令表
特定命令 ::= 特定对象? 特定标志* 命令
特定对象 ::= '(' 对象表? (':' 对象表)? ')'
特定标志 ::= ('NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' |
'SETENV:' | 'NOSETENV:' | 'LOG_INPUT:' |
'NOLOG_INPUT:' |'LOG_OUTPUT:' | 'NOLOG_OUTPUT:')
特定对象可以是(对象表:对象表)这种形式的,最多只能两个对象表。第一个指定的是运行sudo带上-u选项时代表的对象,第二个指定的带上-g选项时代表的对象。如果两条都指定了,用户就可以以任意形式代表对象表里用户和组来执行命令。如果没有指定对象,那就是代表拥有高度权利的root。
特定对象指定了其后面命令的?认行为,例子:
dbg boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
用户dbg可以以operator的身份(代表operator)执行/bin/ls, /bin/kill, /usr/bin/lprm这些命令。就需要这样执行命令
$ sudo -u operator /bin/ls
还可以在一条目的后面无视前面的特定对象。如:
dbg boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
用户dbg现在可以代表operatr执行/bin/ls,代表root执行之后的命令。
让用户可以代表用户或代表组去执行命令:
dbg boulder = (operator : operator) /bin/ls
特定标志有8个:NOPASSWD,PASSWD,NOEXEC,EXEC,NOSETENV,SETENV,NOLOG_INPUT,LOG_INPUT,NOLOG_OUTPUT,LOG_OUPUT。它们在使用的时候后面都要接上冒号。
?认下,sudo需要用户验证自己的身份,带上NOPASSWD其后的命令就可以不需要密码执行了。
ray rushmore = NOPASSWD: /bin/kill, bin/ls, /usr/bin/lprm
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm 这样就只有/bin/kill不需要密码。
了解了上面的授权规则,如果想sudo的时候不输入密码,原本的授权规则就可以改写为:
GUIN GN = (root) NOPASSWD: RV06, SU01,!/usr/bin/passwd root
以上内容是info页的整理翻译,并且省略了Defaults和sudoers option部分的内容。当我了解到一些内容让我能正式理解某项内容是怎么回事之后,我便不再深入。下面简单记录下其它用户管理相关的内容,从添加用户开始说起吧。
添加用户工具:adduser。添加用户还有另一个工具useradd。Debian系统推荐使用前者,我也发现adduser更简单些,用它可以实现添加新用户、添加用户组、将一个已存在的用户添加到另一个已存在的用户组,可以用--help查看相关选项。与这个工具本身相关的配置文件是/etc/adduser.conf。里边指定了创建新用户时用什么shell,家目录放哪,用户的UID/GID范围,系统用户的UID/GID范围,新建用户时要不要建立一个同名的组等相关信息。里面有一个变量SKEL,这个变量为用户提供一个统一、标准的、默认的用户环境。这个变量指定的目录中的内容将会被复制到新建用户的家目录中。?认一般是SKEL=/etc/skel。
# adduser guin
正在添加用户"guin"...
正在添加新组"guin" (1001)...
正在添加新用户"guin" (1001) 到组"guin"...
创建主目录"/home/guin"...
正在从"/etc/skel"复制文件...
输入新的 UNIX 密码:
重新输入新的 UNIX 密码:
passwd:已成功更新密码
#
添加用户时发生了这许多事情,实际上只是在几个配置文件写进几条记录而已。先看/etc/passwd这个文件,这里面被添加了这样一条:
# cat /etc/passwd | grep 'guin'
guin:x:1001:1001:,,,:/home/guin:/bin/bash
passwd文件是帐户列表,给出每个帐户一些有用的信息,比如UID,GID,家目录,shell,等.
每行一条记录,并且每行有这样的格式:
account:password:UID:GID:GECOS:directory:shell
(帐号:密码:UID:GID:一般的信息:目录:shell)
为了安全,这个文件有一个影象文件/etc/shadow,里面存放一些与密码相关的信息:
# cat /etc/shadow | grep 'guin'
guin:$6$PYE7/ADe$OESsb512byQi6291bqTpACCNMIoQkh0:15100:0:99999:7:::
(login:password:last:minimum:maxmum:warning:inactivity:expiration: )
(账号:加密密码:上次密码修改时间:最短密码时效:最长密码时效:密码到期警告:到期延续时间:账号终止时间:保留域)
第三字段的上次修改密码时间和第八字段是从1970-1-1开始算的。第四字段最短密码时效表达的是在这个时间内密码不得被再次修改,第五字段则表达这个时间之后密码必须修改一下。第七字段指密码到期之后,用户必须在这个时间里修改密码,过期不候。
修改密码用passwd命令,用passwd -S user_name可以查看与密码相关的信息:
# passwd -S guin
guin P 05/06/2011 0 99999 7 -1
也可以使用chage命令(change age)来查看,chage -l user_name。
由于配置文件起的作用,新建用户时建立了一个同名的组,与组相关的文件/etc/group, /etc/gshadow就被写入了一条目:
# cat /etc/group | grep 'guin'
guin:x:1001:
这个文件是组列表文件,每行都有这样的格式:
group_name:password:GID:user_list
(组名:密码:GID:用户列表)
# cat /etc/gshadow | grep 'guin'
guin:!::
这个文件是/etc/group的影像文件,每行都有这样的格式:
(groupname:password:admin,admin_list:member_list)
(组名:密码:组管理员:成员列表)
了解了上面的内容,就可以手工在/etc/passwd, /etc/group里添加用户与组的数据。然后用pwconv命令将/etc/passwd数据同步到/etc/shadow。grpconv命令同步/etc/group到/etc/gshadow。也可以用pwck,grpck检验对应文件的完整性。
如果需要将已存在的用户添加到其它组中,使一个用户被多个组支持,上面提过,也可以用adduser命令,添加新组也可以用它也可以用addgroup, groupadd这两个命令。
# adduser guin users
正在添加用户"guin"到"users"组...
正在将用户“guin”加入到“users”组中
完成。
如上就使guin得到了users组的支持。用groups查看用户属于哪些群组,第一个便是有效群组。用id命令也可以用户的各种信息。
# groups guin
guin : guin users <==当前的有效群组是guin
# id guin
uid=1001(guin) gid=1001(guin) 组=1001(guin),100(users)
有效群组的意思就是用户现在的行为代表着那个群组,比如用户现在创建一个文件,文件的所属群组是属于有效群组的。用newgrp改变有效群组。newgrp的用途是?陆到新的用户组中。如果没指定组,则进入/etc/passwd里指定的那个真实群组。
# su guin
$ newgrp users
$ groups
users guin <==users组排到了前面。
usermod修改一个用户账号,包括初始群组、属组、?陆名、shell、家目录、各种密码日期等。被修改的用户必须当前不在线。用deluser删除用户,命令详细参考--help 和 info 档。这个工具还受文件/etc/deluser.conf支配。w 查看当前?陆用户和他们的进程。/var/run/utmp这个文件是已?陆系统用户的信息。who查看?陆用户的信息。?认它查看/var/run/utmp。可以提供/var/log/wtmp以查看先前?陆的用户。lastlog报告最近?陆的所有用户,它查看/var/log/lastlog的内容并打印。
总结起来与用户管理相关的内容就是对soduers, passwd, shadow, group, gshadow 这5个文件的认识。理解了它们,便完成了对用户管理内容的初识。更进阶的内容就是PAM,一个可插拔认证模块。PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制。它涉及的内容太深,暂不了解也罢。
晚安,童鞋们。


open_shift 于 2015-03-04 22:29:11发表:
:0)1
hanes1005 于 2013-11-05 16:59:03发表:
学习下!
夜光杯lyx 于 2013-08-27 12:44:18发表:
:0)1
Feyiz 于 2013-04-20 23:14:20发表:
遇到再看吧,太多
gky2009514 于 2012-12-07 13:25:59发表:
新手完成任务,求下书籍~
dcapjj 于 2012-12-06 11:01:10发表:
很有用,挺你~
tlhchts 于 2012-11-02 10:11:54发表:
楼主的分享非常不错!!谢谢!!!!
jjx0223 于 2012-10-30 00:38:59发表:
感谢楼主的分享!!
INlinux初学ing 于 2012-07-30 20:45:42发表:
不知版主可知道安装好centos后,怎用硬盘样进图形界面,因为我进 的是文字界面,不知道怎么做了,我是用硬盘安装的,启动后,选择centos这个操作系统后就进文字命令界面了,不知怎操作?求解
小鹿乱撞 于 2011-09-23 17:28:25发表:
还是先看看再说啊吧……
dj15621 于 2011-09-23 16:08:14发表:
ding.....
gwssgc 于 2011-09-23 10:08:42发表:
这个真的是基础么......
小鹿乱撞 于 2011-09-22 23:20:41发表:
我还是看书去吧……
小鹿乱撞 于 2011-09-22 23:20:29发表:
什么啊……
小鹿乱撞 于 2011-09-22 23:20:21发表:
(so):)
sliy58 于 2011-08-08 17:49:34发表:
非常不错的讲解
wq413732076 于 2011-08-03 21:12:44发表:
感谢楼主分享我要学linux
D调漫步 于 2011-08-02 09:29:03发表:
先赞个
micai 于 2011-07-06 11:39:33发表:
挺详细的,顶上。。。。
guohaike 于 2011-06-07 11:56:39发表:
留着慢慢看!
zswojj 于 2011-06-05 10:14:45发表:
这个很详细啊,很有用啊
634632257 于 2011-05-27 23:04:05发表:
好多东西要学啊!
wudalang1981 于 2011-05-27 15:46:06发表:
先顶了再说,感谢楼主哦,太感谢了
谢俊杰 于 2011-05-25 22:50:17发表:
求基础,太高深了
your180 于 2011-05-25 10:04:40发表:
不太懂
hiluyao 于 2011-05-17 19:48:21发表:
:0wl;l1
Liuzl 于 2011-05-13 11:41:12发表:
q):-s
kingtigerhu 于 2011-05-09 16:01:09发表:
貌似以前学过,但是现在忘了,不行,要回去看看去
xsqk 于 2011-05-08 11:22:54发表:
还是有很多不明白,留待以后回头看!
Growth兆 于 2011-05-07 09:39:21发表:
感谢Guin的分享,本贴加入到论坛顶置的Linux应用索引贴中
batue 于 2011-05-07 08:52:08发表:
好多先留着
dupontjoy 于 2011-05-07 07:27:53发表:
先看基础去