第十三章 Linux帐号管理与ACL权限设定

发布时间 2023-07-31 11:08:03作者: Evan-whc

第十三章 Linux帐号管理与ACL权限设定

13.1 Linux的帐号与群组

13.1.1 使用者标识符:UID与GID

  每个登入的使用者至少都会取得两个ID,一个是使用者ID(User ID,简称UID),一个是群组ID(Group ID,简称GID)。那么文件如何判断他的拥有者与群组呢?其实就是利用UID与GID啦!

13.1.2 使用者帐号

  • /etc/passwd文件结构
    这个文件的构造是这样的:每一行都代表一个帐号,有几行就代表有几个帐号在你的系统中!不过需要特别留意的是,里头很多帐号本来就是系统正常运作所必须要的,我们可以简称他为系统帐号,例如bin,daemon,adm,nobody等等,这些帐号请不要随意的杀掉他呢!
    每一行使用【:】分隔开,共有七个咚咚,分别是:

    1. 帐号名称
    2. 密码
    3. UID
    4. GID
    5. 用户信息说明栏
    6. 家目录
    7. Shell
  • /etc/shadow文件结构
    基本上,shadow同样以【:】作为分隔符,如果数一数,会发现共有九个字段啊,这九个字段的用途是这样的:

    1. 帐号名称
    2. 密码
    3. 最近更动密码的日期
    4. 密码不可被更动的天数
    5. 密码需要重新变更的天数
    6. 密码需要变更期限前的警告天数
    7. 密码过期后的帐号宽限时间(密码失效日)
    8. 帐号失效日期
    9. 保留

13.1.3 关于群组:有效与初始群组、groups,newgrp

  群组的配置文件有/etc/group与/etc/gshadow啰~

  • /etc/group文件结构

    1. 组名
    2. 群组密码
    3. GID
    4. 此群组支持的帐号名称
  • 有效群组(effective group)与初始群组(initial group)

  • groups: 有效与支持群组的观察
      该如何知道我所有支持的群组呢?很简单啊,直接输入groups就可以了!而且,第一个输出的群组即为有效群组了。

  • newgrp: 有效群组的切换
      如何变更有效群组呢?就使用newgrp啊!

  • /etc/gshadow

13.2 帐号管理

13.2.1 新增与移除使用者:useradd,相关配置文件,passwd,usermod,userdel

  • useradd

    useradd [-u UID] [-g 初始群组] [-G 次要群组] [-mM] [-c 说明栏] [-d 家目录绝对路径] [-s shell] 账号名
    选项与参数:
    -u: UID,是一组数字。
    -g: initial group初始群组。
    -G:这个帐号还可以加入的群组。
    -M: 强制!不要建立用户家目录!(系统帐号默认值)
    -m: 强制!建立用户家目录!(一般帐号默认值)
    -c: 说明内容
    -d: 自定义家目录位置
    -r: 建立一个系统的帐号,这个帐号的UID会有限制
    -s: 后面接一个shell,若没有则预设是/bin/bash
    -e: 日期,格式为【YYYY-MM-DD】,可写入shadow第八字段。
    -f: 后接shadow第七字段,指定密码是否会失效。0为立刻失效,-l为永远不失效。
    
  • passwd

    passwd [--stdin] [账号名称] # 所有人均可使用来改自己的密码
    passwd [-l] [-u] [--stdin] [-S] [-n 天数][-x 天数][-w 天数][-i 日期] 帐号  # root功能
    选项与参数:
    --stdin: 可以透过来自前一个管线的数据,作为密码输入,对shell script有帮助!
    -l:是lock的意思,会将/etc/shadow第二栏最前面加上!使密码失效。
    -u: 与-l相对,是unlock的意思!
    -S:列出密码相关参数,亦即shadow文件内容的大部分信息。
    -n: 天数,shadow的第4字段,多久不可修改密码天数。
    -x: 天数,shadow的第5字段,多久内必须要更动密码
    -w: 天数,shadow的第6字段,密码过期前的警告天数
    -i: 日期,shadow的第7字段,密码失效日期
    
  • usermod

    usermod [-cdegGlsuLU] username
    选项与参数:
    -c: 帐号的说明,即/etc/passwd每五栏的说明栏,可以加入一些帐号的说明。
    -d: 家目录,即修改/etc/passwd的第六栏
    -e: 日期,格式是YYYY-MM-DD也就是在/etc/shadow内的第八个字段数据!
    -f:天数,为shadow的第7字段。
    -g: 初始群组,/etc/shadow的第4字段
    -G:次要群组
    -a: 与-G合用,可【增加次要群组的支持】而非【设定】喔!
    -l: 后接帐号名称,亦即是修改帐号名称
    -s:后接Shell的实际文件,例如/bin/bash或/bin/csh等等
    -u: 后面接UID数字啦!即/etc/passwd第三栏的资料;
    -L: 暂时将用户的密码冻结,让他无法登录。其实仅修改/etc/shadow的密码栏
    -U:将/etc/shadow密码栏的!拿掉,解冻啦!
    
  • userdel

    userdel [-r] username
    选项与参数:
    -r: 连同用户的家目录也一起删除
    

13.2.2 用户功能

  • id
    id这个指令则可以查询某人或自己的相关UID/GID等等的信息。

  • finger
    finger的中文字面意思是:【手指】或者是【指纹】的意思。这个finger可以查阅很多用户相关的信息喔!大部分都是在/etc/passwd这个文件里面的信息啦!不过,这个指令有点危险,所以新的版本中已经默认不安装这个软件!

    finger [-s] username
    选项与参数:
    -s: 仅列出用户的帐号、全名、终端机代号与登入时间等等;
    -m: 列出与后面接的帐号相同者,而不是利用部分比对(包括全名部分)
    

13.2.3 新增与删除群组

  • groupadd

    groupadd [-g gid] [-r] 组名
    选项与参数:
    -g: 后面接某个特定的GID,用来直接给予某个GID~
    -r: 建立系统群组啦!与/etc/login.defs内的GID_MIN有关。
    
  • groupmod

    groupmod [-g gid] [-n group_name] 群组名
    选项与参数:
    -g: 修改既有的GID数字
    -n: 修改既有的组名
    
  • groupdel
    删除群组

  • gppasswd: 群组管理员功能

13.2.5 使用外部身份认证系统

  为了简化用户的操作流程,CentOS提供一只名为authconfig-tui的指令给我们参考。

13.3 主机的细部权限规划:ACL的使用

13.3.1 什么是ACL与如何支持启动 ACL

  ACL是Access Control List的缩写,主要的目的是在提供传统的owner,group,others的read,write,execute权限之外的细部权限设定。ACL可以针对单一使用者,单一文件或目录来进行r,w,x的权限规范,对于需要特殊权限的使用状况非常有帮助。
  那ACL主要可以针对哪些方面来控制权限呢?他主要可以针对几个项目:

  • 使用者(user):可以针对使用者来设定权限;
  • 群组(group):可以针对群组为对象来设定其权限;
  • 默认属性(mask):还可以针对在该目录下在建立新文件/目录时,规范新数据的默认权限;
  • 如何启动ACL
    事实上,原本ACL是unix-like操作系统的额外支持项目,但因为近年以来Linux系统对权限细部设定的热切需求,因此目前ACL几乎已经预设加入在所有常见的Linux文件系统的挂载参数中!所以你无须进行任何运作,ACL就可以被你使用啰!不过,如果你不放心系统是否真的支持ACL的话,那么就来检查一下核心挂载时显示的信息吧!

    dmesg | grep -i acl
    

13.3.2 ACL的设定技巧:getfacl,setfacl

  1. getfacl: 取得某个文件/目录的ACL设定项目;

  2. setfacl: 设定某个目录/文件的ACL规范。

  • setfacl 指令用法介绍及最简单的【u:帐号:权限】设定

    setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名
    选项与参数:
    -m: 设定后续的acl参数给文件使用,不可与-x合用
    -x: 删除后续的acl参数,不可与-m合用
    -b: 移除【所有的】ACL设定参数
    -k: 移除【预设的】ACL参数,关于所谓的【预设】参数于后续范例中介绍
    -R: 递归设定acl参数,亦即包括次目录都会被设定起来
    -d: 设定【预设acl参数】意思!只对目录有效,在该目录新建的数据会引用此默认值。
    

    范例:

    #1. 针对特定使用者的方式:
    #设定规范:"u:[使用者帐号列表]:[rwx]",例如针对vbird1的权限规范rx:
    touch acl_test1
    ll acl_test1
    setfacl -m u:vbird1:rx acl_test1
    ll acl_test1
    -rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
    #权限部分多了个+,且与原本的权限(644)看起来差异很大!但要如何查阅呢?
    setfacl -m u::rwx acl_test1
    ll acl_test1
    -rwxr-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
    \#设定值中的u后面无使用者列表,代表设定该文件拥有者,所以上面显示root的权限为rwx了!
    
  • getfacl filename

    getfacl filename
    选项与参数:
    getfacl的选项几乎与setfacl相同!所以这里就省略了。
    

    范例:

    getfacl acl_test1
    # file: acl_test1    #文件名
    # owner: root    # 此文件的拥有者
    # group: root    # 所属群组
    user::rwx    #文件拥有者的权限
    user:vbird1:r-x        #针对vbird1的权限设定为rx,与拥有者并不同!
    group::r--         # 文件群组的权限设定仅有r
    mask::r-x        #此文件预设的有效权限(mask)
    other::r--         # 其他人拥有的权限啰!
    
  • 特定的单一群组的权限设定:"g:群组名:权限"

    #2. 针对特定群组的方式:
    # 设定规范:"g:[群组列表]:[rwx]",例如针对mygroup1的权限规范rx:
    setfacl -m g:mygroup1:rx acl_test1
    getfacl acl_test1
    
  • 针对有效权限设定:"m:权限"

    # 3. 针对有效权限mask的设定方式:
    # 设定规范:"m:[rwx]",例如针对刚刚的文件规范为仅有r:
    setfacl -m m:r acl_test1
    getfacl acl_test1
    

    mask(有效权限)的意义是:使用者或群组所设定的权限必须要存在于mask的权限设定范围内都会生效,此即【有效权限】。

  • 使用默认权限设定目录未来文件的ACL权限继承"d:[u|g]:[user|group]:权限"

    # 4. 针对预设权限的设定方式:
    # 设定规范: "d:[ug]:使用者列表:[rwx]"
    setfacl -m d:u:myuser1:rx /srv/projecta
    getfacl /srv/projecta
    

13.4 使用者身份切换

13.4.1 su

  su是最简单的身份切换指令了,他可以进行任何身份的切换唷!方法如下:

su [-lm] [-c 指令] [username]
选项与参数:
-: 单纯使用-代表使用login-shell的变量文件读取方式来登入系统;若使用者名称没有加上去,则代表切换为root的身份。
-l: 与-类似,但后面需要加欲切换的使用者帐号!也是login-shell的方式。
-m: -m与-p是一样的,表示“使用目前的环境设定,而不读取新使用者的配置文件”
-c: 仅进行一次指令。

su就这样简单的介绍完毕,总结一下他的用法是这样的:

  • 若要完整的切换到新使用者的环境,必须要使用"su - username"或"su -l username",才会连同PATH/USER/MAIL等变量都转成新用户的环境;
  • 如果仅想要执行一次root的指令,可以利用【su - -c "指令串" 】的方式来处理
  • 使用root切换成为任何使用者时,并不需要输入新用户的密码

13.4.2 sudo

  sudo的执行仅需要自己的密码即可!甚至可以设定不需要密码即可执行sudo呢!由于sudo可以让你以其他用户的身份执行指令(通常是使用root的身份来执行指令),因此并非所有人都能够执行sudo,而是仅有规范到/etc/sudoers内的用户才能够执行sudo这个指令喔!

  • sudo的指令用法
    系统默认仅有root可以执行sudo。

    sudo [-b] [-u 新使用者帐号]
    选项与参数:
    -b: 将后续的指令放到背景中让系统自行执行,而不与目前的shell产生影响
    -u: 后面可以接欲切换的使用者,若无此项则代表切换身份为root。
    

    能否使用sudo必须要看/etc/sudoers的设定值,而可使用sudo者是透过输入用户自己的密码来执行后续的指令串。

  • visudo与/etc/sudoers
    除了root之外的其他帐号,若想要使用sudo执行属于root的权限指令,则root需要先使用visudo去修改/etc/sudoers,让该帐号能够使用全部或部分的root指令功能。为什么要使用visudo呢?这是因为/etc/sudoers是有设定语法的,如果设定错误那会造成无法使用sudo指令的不良后果。使用visudo去修改,并在结束离开修改画面时,系统会去检验/etc/sudoers的语法就是了。
    一般来说,visudo的设定方式有几种简单的方法喔,底下我们以几个简单的例子来分别说明:

    1. 单一用户可进行root所有指令,与sudoers文件语法:
    visudo
    ...(前面省略)...
    root    ALL=(ALL)    #这是原有的
    vbird1    ALL=(ALL)    #这一行是你要新增的
    ...(底下省略)...
    
    1. 利用wheel群组以及免密码的功能处理visudo
    visudo
    ...(前面省略)...
    %wheel    ALL=(ALL)    ALL     #大约在106行左右,请将这行的#拿掉,并在最左边加上%,代表一个群组之意,改完保存。
    # 然后将pro1加入wheel的支持
    usermod -a -G whell pro1 
    
    1. 有限制的指令操作
    visudo
    myuser1        ALL=(ALL)    !/usr/bin/passwd,/usr/bin[A-Za-z]*,!/usr/bin/passwd root
    ## 不能执行'passwd'和'passwd root'这两个指令,意思是不能修改root密码,但可以帮助修改其他用户的密码
    
    1. 透过别名建置visudo:
      如果我有15个用户需要加入刚刚的管理员行列,那么我是否要将上述那长长的设定写入15行啊?而且如果想要修改命令或者是新增命令时,那我每行都需要重新设定,很麻烦!有没有更简单的方式?是有的!透过别名即可!我们visudo的别名可以是【指令别名、帐户别名、主机别名】等。不过这里我们仅介绍帐户别名。
      假设我的pro1,pro2,pro3与myuser1,myuser2要加入上述的密码管理员的sudo列表中,那我可以创立一个帐户名称为ADMPW的名称,然后将这个名称处理一下即可。处理的方式如下:
    visudo
    User_Alias ADMPW = pro1,pro2,pro3,myuser1,myuser2
    Cmnd_Alias ADMPWCOM = !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root
    ADMPW    ALL=(root)    ADMPWCOM
    

    我透过User_Alias建立出一个新帐号,这个帐号名称一定要使用大写字符来处理,包括Cmnd_Alias(命令别名)、Host_Alias(来源主机名别名)都需要使用大写字符的!这个ADMPW代表后面接的那些实际帐号。而该帐号能够进行的指令就如同ADMPWCOM后面所指定的那样!上表最后一行则写入这两个别名(帐号与指令别名),未来要修改时,我只要修改User_Alias以及Cmnd_Alias这两行即可!

    1. sudo搭配su的使用方式
      很多时候我们需要大量执行很多root的工作,所以一直使用sudo觉得很烦人!那有没有办法使用sudo搭配su,一口气将身份转为root,而且还是用用户自己的密码来变成root呢?是有的!而且方法简单的会让你想笑!我们建立一个ADMINS帐户别名,然后这样做:
    visudo
    User_Alias    ADMINS = pro1,pro2,pro3,myuser1
    ADMINS    ALL=(root)    /bin/su -
    

    接下来,上述的【pro1,pro2,pro3,myuser1】这4个人,只要输入sudo su - 并且输入自己的密码后,立刻变成root的身份!

13.6 Linux主机上的用户讯息传递

13.6.1 查询使用者:w,who,last,lastlog

  如果你想要知道目前已登入在系统上面的用户呢?可以透过w或who来查询喔!
如果你想要知道每个帐号的最近登入的时间,则可以使用lastlog这个指令喔!lastlog会去读取/etc/lastlog文件。

13.6.2 使用者对谈:write,mesg,wall

write 使用者帐号 [用户所在终端接口]
范例:
write vbird1 pts/2

13.6.3 使用者邮件信箱:mail

  这个指令用法很简单的,直接这样下达mail -s "邮件标题" username@localhsot即可。

mail -s "nice to meet you" vbrid1
Hello. D.M. Tsai
Nice to meet you in the network.
You are so nice.byebye!
.    #这里很重要哦,结束时,最后一行输入小数点即可!

  那么要如何收信呢?同样用mail即可。

13.7 CentOS 7环境下大量建置帐号的方法

13.7.1 一些帐号相关的检查工具

  先来检查看看用户的家目录、密码等数据有没有问题?这时会使用到的主要有pwck以及pwconv/pwunconv等,让我们来了解一下先!

  • pwck
    pwck这个指令在检查/etc/passwd这个帐号配置文件内的信息,与实际的家目录是否存在等信息,还可以比对/etc/passwd、/etc/shadow的信息是否一致,另外,如果/etc/passwd内的数据字段错误时,会提示使用者修订。一般来说,我只是利用这个玩意儿来检查我的输入是否正确就是了。
  • pwconv
    这个指令主要的目的是在将/etc/passwd内的帐号与密码,移到到/etc/shadow当中。
  • pwunconv
    将/etc/shadow内的密码栏数据写回/etc/passwd当中,并且删除/etc/shadow文件。一般不使用这个指令。
  • chpasswd
    chpasswd是个挺有趣的指令,他可以【读入未加密前的密码,并且经过加密后,将加密的密码写入/etc/shadow当中。这个指令很常用在大量建置帐号的情况中喔!

13.7.2 大量建置帐号模板(适用passwd --stdin选项)

vim accountadd.sh
#!/bin/bash
#This shell script will create amount of linux login accounts for you.
# 1. check the "accountadd.txt" file exist? you must create that file manually.
# 2. use openssl to create users password.
# 3. User must change his password in his first login.
#4. more options check the following url:
#http://linux.vbird.org/linux_basic/0410accountmanager.php#manual_amount
#2015/07/22  VBird
export PATH=/bin/:/sbin:/usr/bin:/usr/sbin

#0. userinput
usergroup=""    #if your account need secondary group,add here.
pwmech="openssl"    #"openssl" or "account" is needed
homeperm="no"     #if "yes" then I will modify home dir permission to 711

#1. check the accountadd.txt file
action="${1}"    #"create" is useradd and "delete" is userdel.
if [ ! -f accountadd.txt ]; then
    echo "There is no accountadd.txt file.stop here."
    exit 1
fi

[ "${usergroup}" != "" ] && groupadd -r ${usergroup}
rm -f outputpw.txt
usernames=$(cat accountadd.txt)

for username in ${usernames}
do
    case ${action} in
        "create")
            [ "${usergroup}" != "" ] && usegrp=" -G ${usergroup} " || usegrp=""
            useradd ${usegrp} ${username}  #新增帐号
            [ "${pwmech}" == "openssl" ] && usepw=$(openssl rand -base64 6) || usepw=${username}
            echo ${usepw} | passwd --stdin ${username} #建立密码
            chage -d 0 ${username} #强制登入修改密码
            [ "${homeperm}" == "yes" ] && chomd 711 /home/${username}
            echo "username=${username}, password=${usepw}" >> outputpw.txt
            ;;
        "delete)
            echo "deleting ${username}"
            userdel -r ${username}
            ;;
        *)
        echo "Usage:$0 [create|delete]"
        ;;
    esac
done