• Linux 用户管理与文件权限详解


    一、Linux用户和用户组

    (1)用户和用户组简介

    与windows类似,Linux也有用户和用户组的概念。在Linux系统中,每次登录系统都必须以一个用户的身份登录,并且登录后的权限也会根据用户身份来确定。 每一个进程在执行时,也会有其用户,该用户也和进程所能控制的资源有关。Linux系统下的每一个目录、文件,都会有其属于的用户和用户组,我们称其为属主和属组。由此课件,用户和用户组与Linux系统的运行息息相关。在实际操作使用系统时,我们往往关注用户较多与关注用户组。

    在Linux系统中,每个用户都有自己的用户ID,称为UID,每个用户组也有自己的用户组ID,称为GID,UID和GID在Linux系统中是不可重复的。Linux系统就是通过UID和GID来对用户和组进行管理的,而对于管理员来说,往往会设置用户名和组名,这样使得用户和用户组的使用管理更人性化。

    在Linux系统中,一共有三种类型的用户组:

    1. root用户

    root用户时UID和GID都等于0的用户,是Linux系统中的“上帝”,拥有最大的权限。如果深入了解Linux系统,会发现root用户真的拥有很多特权,比如:无视Linux对权限的设置而强行读、写、执行文件,切换其他用户登录不需要密码,可以强行切换到已经所用的用户,只有root可以为普通用户修改密码等等。

    2. 系统用户

    系统用户通常用于运行服务,但是此用户无家目录,也不能用于登录系统。例如,在yum安装apache、nginx等服务后,就会自动创建apache和nginx的用户和同名用户组。在CentOS6系统中,系统用户的UID范围是1-499,在CentOS7系统中,系统用户的ID是1-999。

    3. 普通用户

    普通用户只能由root用户创建,该用户拥有家目录,并且可以登录,该用户的权限由root分配。普通用户拥有指定的shell环境。

    用户和用户组关系

    在Linux系统中,每个用户必定属于一个主组,默认情况下属于与其同名的用户组,最多可以有31个附属组,从用户权限的角度看,主组和附属组其实差别不大,用户也会拥有其附属组的组相关权限。

    (2)用户和用户组配置文件

    Linux系统下用户和用户组相关的配置文件主要有以下个:

    1、/etc/passwd

    该配置文件内保存有所有的用户信息,如下所示:

    1. # cat /etc/passwd
    2. root:x:0:0:Superuser:/:
    3. daemon:x:1:1:System daemons:/etc:
    4. bin:x:2:2:Owner of system commands:/bin:
    5. sys:x:3:3:Owner of system files:/usr/sys:
    6. adm:x:4:4:System accounting:/usr/adm:
    7. uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
    8. auth:x:7:21:Authentication administrator:/tcb/files/auth:
    9. cron:x:9:16:Cron daemon:/usr/spool/cron:
    10. listen:x:37:4:Network daemon:/usr/net/nls:
    11. lp:x:71:18:Printer administrator:/usr/spool/lp:
    12. sam:x:200:50:Sam san:/home/sam:/bin/sh

    从上面的例子我们可以看到,/etc/passwd中一行记录对应着一个用户,每行记录又被冒号(:)分隔为7个字段,其格式和具体含义如下:

    用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell

    1) "用户名"是代表用户账号的字符串

    通常长度不超过8个字符,并且由大小写字母和/或数字组成。登录名中不能有冒号(:),因为冒号在这里是分隔符。

    为了兼容起见,登录名中最好不要包含点字符(.),并且不使用连字符(-)和加号(+)打头。

    2) “口令”一些系统中,存放着加密后的用户口令字

    虽然这个字段存放的只是用户口令的加密串,不是明文,但是由于/etc/passwd文件对所有用户都可读,所以这仍是一个安全隐患。因此,现在许多Linux 系统(如SVR4)都使用了shadow技术,把真正的加密后的用户口令字存放到/etc/shadow文件中,而在/etc/passwd文件的口令字段中只存放一个特殊的字符,例如“x”或者“*”。

    3) “用户标识号”是一个整数,系统内部用它来标识用户

    一般情况下它与用户名是一一对应的。如果几个用户名对应的用户标识号是一样的,系统内部将把它们视为同一个用户,但是它们可以有不同的口令、不同的主目录以及不同的登录Shell等。

    通常用户标识号的取值范围是0~65 535。0是超级用户root的标识号,1~99由系统保留,作为管理账号,普通用户的标识号从100开始。在Linux系统中,这个界限是500。

    4) “组标识号”字段记录的是用户所属的用户组

    它对应着/etc/group文件中的一条记录。

    5) “注释性描述”字段记录着用户的一些个人情况

    例如用户的真实姓名、电话、地址等,这个字段并没有什么实际的用途。在不同的Linux 系统中,这个字段的格式并没有统一。在许多Linux系统中,这个字段存放的是一段任意的注释性描述文字,用做finger命令的输出。

    6) “主目录”,也就是用户的起始工作目录

    它是用户在登录到系统之后所处的目录。在大多数系统中,各用户的主目录都被组织在同一个特定的目录下,而用户主目录的名称就是该用户的登录名。各用户对自己的主目录有读、写、执行(搜索)权限,其他用户对此目录的访问权限则根据具体情况设置。

    7) 用户登录后,要启动一个进程,负责将用户的操作传给内核,这个进程是用户登录到系统后运行的命令解释器或某个特定的程序,即Shell

    Shell是用户与Linux系统之间的接口。Linux的Shell有许多种,每种都有不同的特点。常用的有sh(Bourne Shell), csh(C Shell), ksh(Korn Shell), tcsh(TENEX/TOPS-20 type C Shell), bash(Bourne Again Shell)等。

    系统管理员可以根据系统情况和用户习惯为用户指定某个Shell。如果不指定Shell,那么系统使用sh为默认的登录Shell,即这个字段的值为/bin/sh。

    用户的登录Shell也可以指定为某个特定的程序(此程序不是一个命令解释器)。

    利用这一特点,我们可以限制用户只能运行指定的应用程序,在该应用程序运行结束后,用户就自动退出了系统。有些Linux 系统要求只有那些在系统中登记了的程序才能出现在这个字段中。

    系统中有一类用户称为伪用户(pseudo users)

    这些用户在/etc/passwd文件中也占有一条记录,但是不能登录,因为它们的登录Shell为空。它们的存在主要是方便系统管理,满足相应的系统进程对文件属主的要求。

    常见的伪用户如下所示:

    1. 伪 用 户 含 义
    2. bin 拥有可执行的用户命令文件
    3. sys 拥有系统文件
    4. adm 拥有帐户文件
    5. uucp UUCP使用
    6. lp lp或lpd子系统使用
    7. nobody NFS使用

    2、/etc/shadow

    除了上面列出的伪用户外,还有许多标准的伪用户,例如:audit, cron, mail, usenet等,它们也都各自为相关的进程和文件所需要。

    由于/etc/passwd文件是所有用户都可读的,如果用户的密码太简单或规律比较明显的话,一台普通的计算机就能够很容易地将它破解,因此对安全性要求较高的Linux系统都把加密后的口令字分离出来,单独存放在一个文件中,这个文件是/etc/shadow文件。 有超级用户才拥有该文件读权限,这就保证了用户密码的安全性。

    该配置文件保存了用户的密码信息,如下所示:

    1. # cat /etc/shadow
    2. root:Dnakfw28zf38w:8764:0:168:7:::
    3. daemon:*::0:0::::
    4. bin:*::0:0::::
    5. sys:*::0:0::::
    6. adm:*::0:0::::
    7. uucp:*::0:0::::
    8. nuucp:*::0:0::::
    9. auth:*::0:0::::
    10. cron:*::0:0::::
    11. listen:*::0:0::::
    12. lp:*::0:0::::
    13. sam:EkdiSECLWPdSa:9740:0:0::::

    /etc/shadow中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/passwd中的数据自动产生。

    它的文件格式与/etc/passwd类似,由若干个字段组成,字段之间用":"隔开。这些字段是:

    登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志
    1. "登录名"是与/etc/passwd文件中的登录名相一致的用户账号
    2. "口令"字段存放的是加密后的用户口令字,长度为13个字符。如果为空,则对应用户没有口令,登录时不需要口令;如果含有不属于集合 { ./0-9A-Za-z }中的字符,则对应的用户不能登录。
    3. "最后一次修改时间"表示的是从某个时刻起,到用户最后一次修改口令时的天数。时间起点对不同的系统可能不一样。例如在SCO Linux 中,这个时间起点是1970年1月1日。
    4. "最小时间间隔"指的是两次修改口令之间所需的最小天数。
    5. "最大时间间隔"指的是口令保持有效的最大天数。
    6. "警告时间"字段表示的是从系统开始警告用户到用户密码正式失效之间的天数。
    7. "不活动时间"表示的是用户没有登录活动但账号仍能保持有效的最大天数。
    8. "失效时间"字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。

    3、/etc/group

    用户组的所有信息都存放在/etc/group文件中:

    1. root::0:root
    2. bin::2:root,bin
    3. sys::3:root,uucp
    4. adm::4:root,adm
    5. daemon::5:root,daemon
    6. lp::7:root,lp
    7. users::20:root,sam

    将用户分组是Linux 系统中对用户进行管理及控制访问权限的一种手段。

    每个用户都属于某个用户组;一个组中可以有多个用户,一个用户也可以属于不同的组。

    当一个用户同时是多个组中的成员时,在/etc/passwd文件中记录的是用户所属的主组,也就是登录时所属的默认组,而其他组称为附加组。

    用户要访问属于附加组的文件时,必须首先使用newgrp命令使自己成为所要访问的组中的成员。

    用户组的所有信息都存放在/etc/group文件中。此文件的格式也类似于/etc/passwd文件,由冒号(:)隔开若干个字段,这些字段有:

    组名:口令:组标识号:组内用户列表
    1. "组名"是用户组的名称,由字母或数字构成。与/etc/passwd中的登录名一样,组名不应重复。
    2. "口令"字段存放的是用户组加密后的口令字。一般Linux 系统的用户组都没有口令,即这个字段一般为空,或者是*。
    3. "组标识号"与用户标识号类似,也是一个整数,被系统内部用来标识组。
    4. "组内用户列表"是属于这个组的所有用户的列表,不同用户之间用逗号(,)分隔。这个用户组可能是用户的主组,也可能是附加组。

    4、/etc/gshadow

    该文件保存了用户组的密码(其实用户组也没有密码)信息:

    1. [root@localhost ~]#cat /etc/gshadow
    2. root:::
    3. bin:::bin, daemon
    4. daemon:::bin, daemon
    5. ...省略部分输出...
    6. lamp:!::

    文件中,每行代表一个组用户的密码信息,各行信息用 ":" 作为分隔符分为 4 个字段,每个字段的含义如下:

    组名:加密密码:组管理员:组附加用户列表
    1. "组名"同 /etc/group 文件中的组名相对应。
    2. "组密码"字段对于大多数用户来说,通常不设置组密码,因此该字段常为空,但有时为 "!",指的是该群组没有组密码,也不设有群组管理员。
    3. "组管理员"从系统管理员的角度来说,该文件最大的功能就是创建群组管理员。那么,什么是群组管理员呢?

      考虑到 Linux 系统中账号太多,而超级管理员 root 可能比较忙碌,因此当有用户想要加入某群组时,root 或许不能及时作出回应。这种情况下,如果有群组管理员,那么他就能将用户加入自己管理的群组中,也就免去麻烦 root 了。

      不过,由于目前有 sudo 之类的工具,因此群组管理员的这个功能已经很少使用了。
    4. "组中的附加用户"该字段显示这个用户组中有哪些附加用户,和 /etc/group 文件中附加组显示内容相同。

    添加用户到组:

    gpasswd -M user1 mygroup

    5、/etc/login.defs

    /etc/login.defs 文件是用来定义创建用户时,对用户的一些基本属性做默认设置。如创建用户时,是否需要家目录,UID和GID的范围,用户及密码的有效期限,家目录的权限,密码加密方式等等。

    该文件里的配置对root用户无效,优先级低于/etc/shadow里面的配置。并且当此文件中的配置与 /etc/passwd 和 /etc/shadow 文件中的用户信息有冲突时,系统会以/etc/passwd 和 /etc/shadow 为准。

    1. cat /etc/login.defs
    2. #创建用户时,要在目录/var/spool/mail中创建一个用户mail文件
    3. MAIL_DIR /var/spool/mail
    4. #密码最大有效期99999
    5. PASS_MAX_DAYS 99999
    6. #两次修改密码的最小间隔时间0
    7. PASS_MIN_DAYS 0
    8. #密码最小长度,对于root无效
    9. PASS_MIN_LEN 5
    10. #密码过期前多少天开始提示
    11. PASS_WARN_AGE 7
    12. #创建用户时不指定UID的话自动UID的范围
    13. UID_MIN 1000
    14. #用户ID的最小值
    15. UID_MAX 60000
    16. #系统uid的最小值
    17. SYS_UID_MIN 201
    18. #系统uid的最大值
    19. SYS_UID_MAX 999
    20. #用户组GID的最小值
    21. GID_MIN 1000
    22. #用户组GID的最大值
    23. GID_MAX 60000
    24. #系统用户组GID的最小值
    25. SYS_GID_MIN 201
    26. #系统用户组GID的最大值
    27. SYS_GID_MAX 999
    28. #允许使用useradd的时候创建用户家目录
    29. CREATE_HOME yes
    30. #权限掩码设置为077(默认为022,注释里面有这方面介绍)
    31. UMASK 077
    32. #使用命令 userdel 删除用户时,是否删除用户的初始组,默认是删除
    33. USERGROUPS_ENAB yes
    34. #指定 Linux 用户的密码使用 SHA512 散列模式加密,这是新的密码加密模式,原先的 Linux只能用 DES 或 MD5 方式加密
    35. ENCRYPT_METHOD SHA512
    设置项含义
    MAIL_DIR /var/spool/mail 创建用户时,系统会在目录 /var/spool/mail 中创建一个用户邮箱,比如 lamp 用户的邮箱是 /var/spool/mail/lamp。
    PASS_MAX_DAYS 99999密码有效期,99999 是自 1970 年 1 月 1 日起密码有效的天数,相当于 273 年,可理解为密码始终有效。
    PASS_MIN_DAYS 0表示自上次修改密码以来,最少隔多少天后用户才能再次修改密码,默认值是 0。
    PASS_MIN_LEN 5指定密码的最小长度,默认不小于 5 位,但是现在用户登录时验证已经被 PAM 模块取代,所以这个选项并不生效。
    PASS_WARN_AGE 7指定在密码到期前多少天,系统就开始通过用户密码即将到期,默认为 7 天。
    UID_MIN 500 指定最小 UID 为 500,也就是说,添加用户时,默认 UID 从 500 开始。注意,如果手工指定了一个用户的 UID 是 550,那么下一个创建的用户的 UID 就会从 551 开始,哪怕 500~549 之间的 UID 没有使用。
    UID_MAX 60000指定用户最大的 UID 为 60000。
    GID_MIN 500指定最小 GID 为 500,也就是在添加组时,组的 GID 从 500 开始。
    GID_MAX 60000用户 GID 最大为 60000。
    CREATE_HOME yes指定在创建用户时,是否同时创建用户主目录,yes 表示创建,no 则不创建,默认是 yes。
    UMASK 077用户主目录的权限默认设置为 077。
    USERGROUPS_ENAB yes指定删除用户的时候是否同时删除用户组,准备地说,这里指的是删除用户的初始组,此项的默认值为 yes。
    ENCRYPT_METHOD SHA512指定用户密码采用的加密规则,默认采用 SHA512,这是新的密码加密模式,原先的 Linux 只能用 DES 或 MD5 加密。

    6、添加批量用户

    添加和删除用户对每位Linux系统管理员都是轻而易举的事,比较棘手的是如果要添加几十个、上百个甚至上千个用户时,我们不太可能还使用useradd一个一个地添加,必然要找一种简便的创建大量用户的方法。Linux系统提供了创建大量用户的工具,可以让您立即创建大量用户,方法如下:

    1 先编辑一个文本用户文件

    每一列按照/etc/passwd密码文件的格式书写,要注意每个用户的用户名、UID、宿主目录都不可以相同,其中密码栏可以留做空白或输入x号。一个范例文件user.txt内容如下:

    1. user001::600:100:user:/home/user001:/bin/bash
    2. user002::601:100:user:/home/user002:/bin/bash
    3. user003::602:100:user:/home/user003:/bin/bash
    4. user004::603:100:user:/home/user004:/bin/bash
    5. user005::604:100:user:/home/user005:/bin/bash
    6. user006::605:100:user:/home/user006:/bin/bash

    2 以root身份执行命令 /usr/sbin/newusers,从刚创建的用户文件user.txt中导入数据,创建用户:

    # newusers < user.txt

    然后可以执行命令 vipw 或 vi /etc/passwd 检查 /etc/passwd 文件是否已经出现这些用户的数据,并且用户的宿主目录是否已经创建。

    3 执行命令/usr/sbin/pwunconv

    将 /etc/shadow 产生的 shadow 密码解码,然后回写到 /etc/passwd 中,并将/etc/shadowshadow密码栏删掉。这是为了方便下一步的密码转换工作,即先取消 shadow password 功能。

    # pwunconv

    4 编辑每个用户的密码对照文件

    格式为:

    用户名:密码

    实例文件 passwd.txt 内容如下:

    1. user001:123456
    2. user002:123456
    3. user003:123456
    4. user004:123456
    5. user005:123456
    6. user006:123456

    5 以 root 身份执行命令 /usr/sbin/chpasswd

    创建用户密码,chpasswd 会将经过 /usr/bin/passwd 命令编码过的密码写入 /etc/passwd 的密码栏。

    # chpasswd < passwd.txt

    6 确定密码经编码写入/etc/passwd的密码栏后

    执行命令 /usr/sbin/pwconv 将密码编码为 shadow password,并将结果写入 /etc/shadow

    # pwconv

    这样就完成了大量用户的创建了,之后您可以到/home下检查这些用户宿主目录的权限设置是否都正确,并登录验证用户密码是否正确。

    (3)Linux用户管理相关命令

    我们通常通过以下命令对Linux的用户和用户组进行管理。

    1. useradd添加用户

    useradd命令一般用于添加用户,该命令常见参数如下:

    1. -M 表示不创建家目录
    2. -s 表示指定用户的shell环境
    3. -u 表示指定用户的uid
    4. -g 表示指定用户的gid(需要指定的gid存在)
    5. -p 指定用户的密码(必须以密文的方式指定)
    6. -G 表示指定用户的附属组(需要指定的gid存在)

    useradd命令使用示例:

    1. useradd Linux
    2. useradd apache -M -s /sbin/nologin

    上面第一条命令表示创建Linux的普通用户,第二条命令表示创建apache的系统用户。

    # useradd –d  /home/sam -m sam

    此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录 /home/sam(/home为默认的用户主目录所在的父目录)。

    # useradd -s /bin/sh -g group –G adm,root gem

    此命令新建了一个用户gem,该用户的登录Shell是 /bin/sh,它属于group用户组,同时又属于adm和root用户组,其中group用户组是其主组。

    这里可能新建组:#groupadd group及groupadd adm

    增加用户账号就是在/etc/passwd文件中为新用户增加一条记录,同时更新其他系统文件如/etc/shadow, /etc/group等。

    Linux提供了集成的系统管理工具userconf,它可以用来对用户账号进行统一管理。

    2. userdel删除用户

    userdel命令可以删除用户,后面直接跟用户名可以直接删除该用户。但是,我们一般在删除用户时都会添加-r参数,表示连同该用户的家目录一起删除。

    userdel命令执行示例如下:

    userdel -r linux

    常用的选项是 -r,它的作用是把用户的主目录一起删除。此命令删除用户linux在系统文件中(主要是/etc/passwd, /etc/shadow, /etc/group等)的记录,同时删除用户的主目录。

    在不删除家目录的情况下,删除该用户后如果想要再创建同名用户时则会失败,如下所示:

    并且删除家目录也会被拒绝,如下所示:

    删除用户还需要注意一个问题,就是删除该用户后,该用户创建的文件的属主和属组就会变成UID和GID显示,如下所示:

    3.  usermod修改用户

    usermod命令常用于修改用户的信息,常用参数如下:

    1. -d 表示重新指定用户的家目录
    2. -g 表示重新指定用户的(主)组
    3. -G 表示给用户添加附属组
    4. -L 表示锁定用户,被锁定的用户无法登录
    5. -U 表示解除对用户的锁定
    6. 注意:如果在锁定用户后使用passwd命令修改该锁定用户的口令,则该用户会被自动解锁。

    另外,有些系统可以使用选项:-l 新用户名

    这个选项指定一个新的账号,即将原来的用户名改为新的用户名。

    usermod命令给用户增加附属组如下所示:

    注意,在上述操作中,必须首先存在一个GID为1001的组。

    # usermod -s /bin/ksh -d /home/z –g developer sam

    此命令将用户sam的登录Shell修改为ksh,主目录改为/home/z,用户组改为developer。

    usermod -G wheel zhaoke

    将zhaoke添加到组wheel中。

    usermod -a -G groupA user

    将一个用户添加到用户组中,千万不能直接用: 

    usermod -G groupA 

    这样做会使你离开其他用户组,仅仅做为这个用户组 groupA 的成员。 

    应该加上 -a 选项: -a 代表 append, 也就将自己添加到用户组groupA 中,而不必离开其他用户组。

    # usermod -l newuser1 newuser

    修改 newuser 的用户名为 newuser1。

    1. # usermod -L newuser1
    2. # usermod -U newuser1

    锁定/解除锁定账号newuser1

    1. [lm@eccs_web font]$ groups lm
    2. lm : lm root

    备注:用户lm属于lm 和 root组。

    4. passwd用户口令管理

    用户管理的一项重要内容是用户口令的管理。用户账号刚创建时没有口令,但是被系统锁定,无法使用,必须为其指定口令后才可以使用,即使是指定空口令。

    指定和修改用户口令的Shell命令是passwd。超级用户可以为自己和其他用户指定口令,普通用户只能用它修改自己的口令。命令的格式为:

    passwd 选项 用户名

    可使用的选项:

    1. -l 锁定口令,即禁用账号。
    2. -u 口令解锁。
    3. -d 使账号无口令。
    4. -f 强迫用户下次登录时修改口令。

    如果默认用户名,则修改当前用户的口令。

    例如,假设当前用户是sam,则下面的命令修改该用户自己的口令:

    1. $ passwd
    2. Old password:******
    3. New password:*******
    4. Re-enter new password:*******

    如果是超级用户,可以用下列形式指定任何用户的口令:

    1. # passwd sam
    2. New password:*******
    3. Re-enter new password:*******

    普通用户修改自己的口令时,passwd命令会先询问原口令,验证后再要求用户输入两遍新口令,如果两次输入的口令一致,则将这个口令指定给用户;而超级用户为用户指定口令时,就不需要知道原口令。

    为了系统安全起见,用户应该选择比较复杂的口令,例如最好使用8位长的口令,口令中包含有大写、小写字母和数字,并且应该与姓名、生日等不相同。

    为用户指定空口令时,执行下列形式的命令:

    # passwd -d sam

    此命令将用户 sam 的口令删除,这样用户 sam 下一次登录时,系统就不再允许该用户登录了。

    passwd 命令还可以用 -l(lock) 选项锁定某一用户,使其不能登录,例如:

    # passwd -l sam

    5. id命令

    id命令可以显示用户的信息,包括UID、GID等信息,id命令后面如果不加其他的命令参数表示查看的是当前登录用户的信息,如果加上其他用户的用户名则查询的是该用户的用户信息。

    id [-gGnru][--help][--version][用户名称]

    选项:

    1. -g或--group   显示用户所属群组的ID。
    2. -G或--groups 显示用户所属附加群组的ID。
    3. -n或--name   显示用户,所属群组或附加群组的名称。
    4. -r或--real   显示实际ID。
    5. -u或--user   显示用户ID。
    6. -help   显示帮助。
    7. -version   显示版本信息。

    示例:

    1. [root@localhost ~]# id
    2. uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)

    打印用户名、UID 和该用户所属的所有组,要这么做,我们可以使用 -a 选项:

    1. [root@localhost ~]# id -a
    2. uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)

    只输出有效的组ID,通过使用 -g 选项来只输出有效组ID:

    1. [root@localhost ~]# id -g
    2. 0

    输出特定用户信息,我们可以输出特定的用户信息相关的UID和GID。只需要在id命令后跟上用户名:

    1. [root@localhost ~]# id www
    2. uid=500(www) gid=500(www) groups=500(www)

    输出所有不同的组ID ,有效的,真实的和补充的,我们可以使用 -G 选项来实现:

    1. [root@localhost ~]# id -G
    2. 0 1 2 3 4 6 10

    (4)Linux用户组管理相关命令

    每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同,如Linux下的用户属于与它同名的用户组,这个用户组在创建用户时同时创建。

    用户组的管理涉及用户组的添加、删除和修改。组的增加、删除和修改实际上就是对/etc/group文件的更新。

    1. 增加一个新的用户组使用groupadd命令。其格式如下:

    groupadd 选项 用户组

    可以使用的选项有:

    1. -g GID 指定新用户组的组标识号(GID)。
    2. -o 一般与-g选项同时使用,表示新用户组的GID可以与系统已有用户组的GID相同。
    # groupadd group1

    此命令向系统中增加了一个新组group1,新组的组标识号是在当前已有的最大组标识号的基础上加1。

    # groupadd -g 101 group2

    此命令向系统中增加了一个新组group2,同时指定新组的组标识号是101。

    2. 如果要删除一个已有的用户组,使用groupdel命令,其格式如下:

    groupdel 用户组
    # groupdel group1

    此命令从系统中删除组group1。

    3. 修改用户组的属性使用groupmod命令。其语法如下:

    groupmod 选项 用户组

    常用的选项有:

    1. -g GID 为用户组指定新的组标识号。
    2. -o 与-g选项同时使用,用户组的新GID可以与系统已有用户组的GID相同。
    3. -n新用户组 将用户组的名字改为新名字
    # groupmod -g 102 group2

    此命令将组group2的组标识号修改为102。

    # groupmod –g 10000 -n group3 group2

    此命令将组group2的标识号改为10000,组名修改为group3。

    4. 如果一个用户同时属于多个用户组,那么用户可以在用户组之间切换,以便具有其他用户组的权限

    用户可以在登录后,使用命令newgrp切换到其他用户组,这个命令的参数就是目的用户组。

    $ newgrp root

    这条命令将当前用户切换到root用户组,前提条件是root用户组确实是该用户的主组或附加组。类似于用户账号的管理,用户组的管理也可以通过集成的系统管理工具来完成。

    Linux用户和用户组总结:

    ​ 添加用户:adduser命令,adduser 用户名;

    ​ 用户查询:finger命令,finger 用户名;

    ​ 修改用户密码:passwd命令,passwd 用户名;

    ​ 删除用户:deluser命令,deluser 用户名;

    ​ 添加用户组:addgroup命令,addgroup 用户组名;

    ​ 显示组内用户名:groups命令,groups 用户组名;

    ​ 删除用户组:delgroup命令,delgroup用户组名;

    二、Linux sudo相关命令 

    (1)su命令

    su命令用于切换用户和重新登录,直接执行命令su可以重新登录,在Linux系统中,一些配置文件生效需要执行该命令。用户的重登录过程非常快,执行后立马可以完成。

    Linux su命令用于变更为其他使用者的身份,除 root 外,需要键入该使用者的密码。

    使用权限:所有使用者。

    语法:

    su [-fmp] [-c command] [-s shell] [--help] [--version] [-] [USER [ARG]]

    选项:

    选项说明
    -c<指令>或--command=<指令>执行完指定的指令后,即恢复原来的身份;
    -f或——fast适用于csh与tsch,使shell不用去读取启动文件;
    -l或——login改变身份时,也同时变更工作目录,以及HOME,SHELL,USER,logname。此外,也会变更PATH变量;
    -m,-p或--preserve-environment变更身份时,不要变更环境变量;
    -s或--shell=指定要执行的shell;
    --help显示帮助;
    --version显示版本信息。

    示例:

    su -c ls root

    变更帐号为 root 并在执行 ls 指令后退出变回原使用者。

    su root -f

    变更帐号为 root 并传入 -f 参数给新执行的 shell。

    su - clsung

    变更帐号为 clsung 并改变工作目录至 clsung 的家目录(home dir)。

    使用su命令切换用户,可以有两种方式:

    1. su newuser
    2. su - newuser

    这两条命令都可以切换新用户,但是区别在于采用上一条命令切换后当前目录不会发生改变,下一条命令切换后当前目录会切换成该用户的家目录。

    切换用户:

    1. hnlinux@ylg:~$ whoami //显示当前用户
    2. hnlinux
    3. hnlinux@wylg:~$ pwd //显示当前目录
    4. /home/hnlinux
    5. hnlinux@ylg:~$ su root //切换到root用户
    6. 密码:
    7. root@ylg:/home/hnlinux# whoami
    8. root
    9. root@ylg:/home/hnlinux# pwd
    10. /home/hnlinux

    切换用户,改变环境变量:

    1. hnlinux@ylg:~$ whoami //显示当前用户
    2. hnlinux
    3. hnlinux@ylg:~$ pwd //显示当前目录
    4. /home/hnlinux
    5. hnlinux@ylg:~$ su - root //切换到root用户
    6. 密码:
    7. root@ylg:/home/hnlinux# whoami
    8. root
    9. root@ylg:/home/hnlinux# pwd //显示当前目录
    10. /root

    (2)sudo

    我们可以想到,Linux是多用户多权限控制多任务的系统,其中一个超级权限用户为root,剩下的为普通用户,超级用户想干什么就可以干什么,可以理解为当前系统的神。可以想象,如果一直使用root这个超级用户,如果操作有误,密码造成了泄露,或者误删了什么重要的只有root可操作的文件,那么系统是不安全的,因此有低权限用户临时提权的方法就可以了,提权的时候验证一下root的密码不就安全了吗?sudo命令就是这个方法。

    sudo只用作提升普通用户权限到root用户,也就是说该命令只有权限修改的功能,和su这个命令切换用户是不同的,su是双向的,并且su是永久的,而sudo是临时的,命令执行完了,还是原来的用户和环境变量。

    Linux sudo命令用来以其他身份来执行命令,预设的身份为root。在/etc/sudoers中设置了可执行sudo指令的用户。若其未经授权的用户企图使用sudo,则会发出警告的邮件给管理员。用户使用sudo时,必须先输入密码,之后有5分钟的有效期限,超过期限则必须重新输入密码。

    语法:

    sudo(选项)(参数)

    选项:

    选项说明
    -b在后台执行指令;
    -h显示帮助;
    -H将HOME环境变量设为新身份的HOME环境变量;
    -k结束密码的有效期限,也就是下次再执行sudo时便需要输入密码;。
    -l列出目前用户可执行与无法执行的指令;
    -p改变询问密码的提示符号;
    -s执行指定的shell;
    -u<用户>以指定的用户作为新的身份。若不加上此参数,则预设以root作为新的身份;
    -v延长密码有效期限5分钟;
    -V显示版本信息。

    如何使用sudo呢?三种常见的方法:

    第一:usermod -G wheel 用户名,或者 usermod -g wheel 用户名    #超级组wheel,该组内的所有用户可以使用sudo命令,将需要提权的用户加入该组就可以使用sudo命令了。

    第二:/etc/sudoers文件添加一行: %组名 ALL(ALL) ALL。  需要提权的用户加入该组即可: usermod -G 组名  用户名。

    也就是说,不用默认的wheel组名了,自己定义一个组名。

    第三:命令visudo,添加 用户名    ALL=(ALL)       ALL 或者   用户名  ALL=NOPASSWD: ALL,然后保存即可。NOPASSWD:

    可以免密码验证使用sudo命令。

    sudo命令的配置文件/etc/sudoers

    修改 /etc/sudoers,不建议直接使用 vim,而是使用 visudo。因为修改 /etc/sudoers 文件需遵循一定的语法规则,使用 visudo 的好处就在于,当修改完毕 /etc/sudoers 文件,离开修改页面时,系统会自行检验 /etc/sudoers 文件的语法。

    因此,修改 /etc/sudoers 文件的命令如下:

    1. [root@localhost ~]# visudo
    2. …省略部分输出…
    3. root ALL=(ALL) ALL <--大约 76 行的位置
    4. \# %wheel ALL=(ALL) ALL <--大约84行的位置
    5. \#这两行是系统为我们提供的模板,我们参照它写自己的就可以了
    6. …省略部分输出…

    通过 visudo 命令,我们就打开了 /etc/sudoers 文件,可以看到如上显示的 2 行信息,这是系统给我们提供的 2 个模板,分别用于添加用户和群组,使其能够使用 sudo 命令。

    这两行模板的含义分为是:

    1. root ALL=(ALL) ALL
    2. \#用户名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
    3. \#%wheel ALL=(ALL) ALL
    4. \#%组名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
    模块含义
    用户名或群组名表示系统中的那个用户或群组,可以使用 sudo 这个命令。
    被管理主机的地址用户可以管理指定 IP 地址的服务器。这里如果写 ALL,则代表用户可以管理任何主机;如果写固定 IP,则代表用户可以管理指定的服务器。如果我们在这里写本机的 IP 地址,不代表只允许本机的用户使用指定命令,而是代表指定的用户可以从任何 IP 地址来管理当前服务器。
    可使用的身份就是把来源用户切换成什么身份使用,(ALL)代表可以切换成任意身份。这个字段可以省略。
    授权命令表示 root 把什么命令命令授权给用户,换句话说,可以用切换的身份执行什么命令。需要注意的是,此命令必须使用绝对路径写。默认值是 ALL,表示可以执行任何命令。
    1. # 允许 sudo 组执行所有命令
    2. %sudo ALL=(ALL:ALL) ALL
    3. # 允许用户执行所有命令,且无需输入密码
    4. escape ALL =(ALL) NOPASSWD: ALL
    5. # 仅允许用户执行 echo, ls 命令
    6. escape ALL =(ALL) NOPASSWD: /bin/echo /bin/ls
    7. # 运行本机的用户执行关机命令
    8. escape localhost=/sbin/shutdown -h now
    9. # 允许 users 用户组中的用户像 root 用户一样使用 mount、unmount、chrom 命令
    10. %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

    不推荐直接给/etc/sudoers这个文件修改权限,那样不是安全的行为,强烈推荐使用visudo命令。

    示例:

    1. [root@localhost ~]# grep sshd /etc/passwd
    2. sshd:x:74:74:privilege-separated SSH:/var/empty/sshd:/sbin.nologin
    3. [root@localhost ~]# sudo -u sshd touch /tmp/mysshd
    4. [root@localhost ~]# ll /tmp/mysshd
    5. -rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd

    本例中,无法使用 su - sshd 的方式成功切换到 sshd 账户中,因为此用户的默认 Shell 是 /sbin/nologin。这时就显现出 sudo 的优势,我们可以使用 sudo 以 sshd 的身份在 /tmp 目录下创建 mysshd 文件,可以看到,新创建的 mysshd 文件的所有者确实是 sshd。

    1. [root@localhost ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
    2. \> echo 'This is index.html file' > index.html"
    3. [root@localhost ~]# ll -a ~vbird1/www
    4. drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
    5. drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
    6. -rw-r--r-- 1 vbird1 vbird1 24 Feb 28 17:51 index.html

    这个例子中,使用 sudo 命令切换至 vbird1 身份,并运行 sh -c 的方式来运行一连串的命令。

    前面说过,默认情况下 sudo 命令只有 root 身份可以使用,那么,如何让普通用户也能使用它呢?

    解决这个问题之前,先给大家分析一下 sudo 命令的执行过程。sudo命令的运行,需经历如下几步:

    • 当用户运行 sudo 命令时,系统会先通过 /etc/sudoers 文件,验证该用户是否有运行 sudo 的权限;
    • 确定用户具有使用 sudo 命令的权限后,还要让用户输入自己的密码进行确认。出于对系统安全性的考虑,如果用户在默认时间内(默认是 5 分钟)不使用 sudo 命令,此后使用时需要再次输入密码;
    • 密码输入成功后,才会执行 sudo 命令后接的命令。

    显然,能否使用 sudo 命令,取决于对 /etc/sudoers 文件的配置(默认情况下,此文件中只配置有 root 用户)。所以接下来,我们学习对 /etc/sudoers 文件进行合理的修改。

    授权用户 lamp 可以重启服务器,由 root 用户添加,可以在 /etc/sudoers 模板下添加如下语句:

    1. [root@localhost ~]# visudo
    2. lamp ALL=/sbin/shutdown -r now

    注意,这里也可以写多个授权命令,之间用逗号分隔。用户 lamp 可以使用 sudo -l 查看授权的命令列表:

    1. [root@localhost ~]# su - lamp
    2. \#切换成lamp用户
    3. [lamp@localhost ~]$ sudo -l
    4. [sudo] password for lamp:
    5. \#需要输入lamp用户的密码
    6. User lamp may run the following commands on this host:
    7. (root) /sbin/shutdown -r now

    可以看到,lamp 用户拥有了 shutdown -r now 的权限。这时,lamp 用户就可以使用 sudo 执行如下命令重启服务器:

    [lamp@localhost ~]$ sudo /sbin/shutdown -r now

    再次强调,授权命令要使用绝对路径(或者把 /sbin 路径导入普通用户 PATH 路径中,不推荐使用此方式),否则无法执行。

    假设现在有 pro1,pro2,pro3 这 3 个用户,还有一个 group 群组,我们可以通过在 /etc/sudoers 文件配置 wheel 群组信息,令这 3 个用户同时拥有管理系统的权限。

    首先,向 /etc/sudoers 文件中添加群组配置信息:

    1. [root@localhost ~]# visudo
    2. ....(前面省略)....
    3. %group ALL=(ALL) ALL
    4. \#在 84 行#wheel这一行后面写入

    此配置信息表示,group 这个群组中的所有用户都能够使用 sudo 切换任何身份,执行任何命令。接下来,我们使用 usermod 命令将 pro1 加入 group 群组,看看有什么效果:

    1. [root@localhost ~]# usermod -a -G group pro1
    2. [pro1@localhost ~]# sudo tail -n 1 /etc/shadow <==注意身份是 pro1
    3. ....(前面省略)....
    4. Password: <==输入 pro1 的口令喔!
    5. pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7:::
    6. [pro2@localhost ~]# sudo tail -n 1 /etc/shadow <==注意身份是 pro2
    7. Password:
    8. pro2 is not in the sudoers file. This incident will be reported.
    9. \#此错误信息表示 pro2 不在 /etc/sudoers 的配置中。

    可以看到,由于 pro1 加入到了 group 群组,因此 pro1 就可以使用 sudo 命令,而 pro2 不行。同样的道理,如果我们想让 pro3 也可以使用 sudo 命令,不用再修改 /etc/sudoers 文件,只需要将 pro3 加入 group 群组即可。

    (3)配置 Defaults 选项

    如何让 sudo 会话时间随心所欲?

    其中 sudo 命令是权限委派的命令,在生产环境中是非常常用的,默认情况下 sudo 命令会话时间是在 15 分钟。要设置 sudo 密码超时的值,需要使用 passwd_timeout 参数进行设置。

    可以以分钟设置为你所需的任何时间,它会在超时之前一直等待。如果要为每个执行的 sudo 命令弹出密码提示,你也可以将时间设置为 0,或者通过设置值 -1 永久禁用密码提示。

    1. # 设置timeout时间
    2. # 意味着sudo密码提示将会在用户使用20分钟后过期
    3. Defaults env_reset,timestamp_timeout=20

    更多Defaults默认参数:

    1. # 指定用户尝试输入密码的次数,默认值为3
    2. Defaults passwd_tries=5
    3. # 设置密码超时时间,默认为 5 分钟
    4. Defaults passwd_timeout=2
    5. 默认 sudo 询问用户自己的密码,添加 targetpw 或 rootpw 配置可以让 sudo 询问 root 密码
    6. Defaults targetpw
    7. # 指定自定义日志文件
    8. Defaults logfile="/var/log/sudo.log"
    9. # 要在自定义日志文件中记录主机名和四位数年份,可以加上 log_host 和 log_year 参数
    10. Defaults log_host, log_year, logfile="/var/log/sudo.log"
    11. # 保持当前用户的环境变量
    12. Defaults env_keep += "LANG LC_ADDRESS LC_CTYPE COLORS DISPLAY HOSTNAME EDITOR"
    13. Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
    14. # 安置一个安全的 PATH 环境变量
    15. Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

    (4)sudoers.d代替直接编辑suders文件

    系统文档推荐的做法,不是直接修改/etc/sudoers文件,而是将修改写在/etc/sudoers.d/目录下的文件中。如果使用这种方式修改sudoers,需要在/etc/sudoers文件的最后行,加上#includedir /etc/sudoers.d一行(默认已有):

    #includedir /etc/sudoers.d

    注意了,这里的指令#includedir是一个整体, 前面的#号不能丢,并非注释,也不能在#号后有空格。任何在/etc/sudoers.d/目录下,不以~号结尾的文件和不包含.号的文件,都会被解析成/etc/sudoers的内容。

    我们只需要到/etc/sudoers.d目录下写入一个配置文件即可。

    给jerry增加sudo less命令:

    直接使用vi在/etc/sudoers.d目录下创建一个test文件。

    1. vi /etc/sudoers.d/test
    2. jerry ALL =(root) NOPASSWD: /usr/bin/less

    使用which less可知less的绝对路径为/usr/bin/less。

    切换为jerry,测试sudo less命令,添加成功:

    如何更加安全的授权服务器权限?

    如何我们管理的服务器,开发或者其他人员需要登录该服务器,进行环境调试或者问题复现等情况。这时,就需要我们给对应的用户开通登录的访问权限。但是如果我们直接编辑 /etc/sudoers 文件的话,之后当对方使用完成之后我就还需要手动进行清理。如果我们忘记的话,该开发或者其他人员将一直可以登录该服务器,会有一定程度的安全问题。

    不幸的是,对应临时授权的话,/etc/sudoers 文件中没有对应的配置,可以对某个用户或者用户组进行指定范围的时间授权。当用户到达指定时间点之后,将拒绝该用户再次进行登录了。对应此种情况,我们可以通过 crontab 定时任务与 /etc/sudoers.d 目录的机制可以完美的解决上述问题。

    我们通过定时任务的定时执行目录,来定时刷掉 /etc/sudoers.d/ 目录下的用户或者用户组的授权配置文件。比如,我们需要定时每日刷掉今日临时授权的用户或者用户,可以在 /etc/cron.daily 目录下面创建用于删除 /etc/sudoers.d/ 目录的 rm -rf 命令,之后在固定的时间会自动删除。对应授权用户,我们使用在 /etc/sudoers.d/ 目录下创建单独的配置文件,而不是直接修改 /etc/sudoers 文件。

    1. # Crontab有多种定时机制
    2. # 下述分别表示每天、每时、每月、每周定时执行
    3. $ ls -dl /etc/cron.* | grep -v cron.d$
    4. drwxr-xr-x 2 root root 4096 May 15 06:18 /etc/cron.daily
    5. drwxr-xr-x 2 root root 4096 Feb 14 2019 /etc/cron.hourly
    6. drwxr-xr-x 2 root root 4096 Feb 14 2019 /etc/cron.monthly
    7. drwxr-xr-x 2 root root 4096 Jun 18 09:57 /etc/cron.weekly
    8. # 创建单独的授权配置文件
    9. $ ls -lh /etc/sudoers.d/
    10. -r--r----- 1 root root 666 Oct 6 2017 lisi
    11. -r--r----- 1 root root 958 Jan 18 2018 zhangsan
    12. # 查看授权配置文件的内容
    13. $ cat /etc/sudoers.d/zhangsan
    14. ALL ALL = (root) NOPASSWD: zhangsan

    (5)shell 内置命令使用 sudo

    shell 是一个交互式的应用程序,在执行外部命令时通过 fork 来创建一个子进程,再通过 exec 来加载外部命令的程序来执行,但是如果一个命令是 shell 内置命令,那么只能直接由 shell 来运行。sudo 的意思是,以别的用户(如root)的权限来 fork 一个进程,加载程序并运行,因此 sudo 后面不能跟 shell 的内置命令,如:

    在这种情况,我们又没有 root 账户的密码,我们怎样执行该命令呢?有种办法就是使用 sudo 获得root shell 的权限,然后在root shell 中执行该命令。进入root shell 很简单,输入sudo bash 确认本用户的密码即可,此时你会发现命令提示符显示当前是 root。一旦获得root shell,你可以执行任何命令而不需要在每条命令前输入sudo了。

    另外,常用的shell 内置命令在这里 有简单介绍,我们可以使用 type 命令来查看命令的类型,如:

    在这种情况,我们又没有 root 账户的密码,我们怎样执行该命令呢?有种办法就是使用 sudo 获得root shell 的权限,然后在root shell 中执行该命令。进入root shell 很简单,输入sudo bash 确认本用户的密码即可,此时你会发现命令提示符显示当前是 root。一旦获得root shell,你可以执行任何命令而不需要在每条命令前输入sudo了。

    另外,常用的shell 内置命令在这里 有简单介绍,我们可以使用 type 命令来查看命令的类型,如:

    (6)sudo 操作记录日志

    作为一个 Linux 系统的管理员,不仅可以让指定的用户或用户组作为root用户或其它用户来运行某些命令,还能将指定的用户所输入的命令和参数作详细的记录。而sudo的日志功能就可以用户跟踪用户输入的命令,这不仅能增进系统的安全性,还能用来进行故障检修。但是要记录sudo的日志还要一些简单的配置。

    1 创建sudo日志文件:

    touch  /var/log/sudo .log

    2 编辑/etc/rsyslog.conf文件:

    1. vim /etc/rsyslog .conf
    2. #添加一行
    3. local2.debug /var/log/sudo .log

    注意空白不能用空格,用tab。

    3 编辑 visudo:

    1. #添加3行
    2. Defaults logfile= /var/log/sudo .log
    3. Defaults loglinelen=0
    4. Defaults !syslog

    4 重启服务:

    systemctl restart rsyslog
    1. $ sudo cd /root/
    2. [ sudo ] password for dev:
    3. dev is not in the sudoers file . This incident will be reported.
    4. $cat /var/log/sudo .log
    5. Aug 23 10:48:16 : dev : user NOT in sudoers ; TTY=pts /1 ; PWD= /home/dev ; USER=root ; COMMAND= /bin/cd /root/

    Linux sudo相关命令总结:

    su 用户名和su - 用户名  是永久切换用户,加 - ,环境变量也跟着切换。切换时需要验证密码,低等切高等权限验证高等用户密码。

    sudo 需要修改 /etc/sudoers文件,但为了安全一般使用visudo命令,或者将低权限用户加入wheel组内。sudo仅仅是临时提权的作用,记住,是临时。

    当然,两个命令都有一些参数,可以配合使用,但实际用处不是很大,可以忽略。

    三、Linux文件基本属性

    (1)ls

    在 Linux 中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组,如:

    1. [root@www /]# ls -l
    2. total 64
    3. dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
    4. dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
    5. ……

    实例中,bin 文件的第一个属性用 d 表示。d 在 Linux 中代表该文件是一个目录文件。

    在 Linux 中第一个字符代表这个文件是目录、文件或链接文件等等。

    • 当为 d 则是目录
    • 当为 - 则是文件;
    • 若是 l 则表示为链接文档(link file);
    • 若是 b 则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
    • 若是 c 则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。

    接下来的字符中,以三个为一组,且均为 rwx 的三个参数的组合。其中, r 代表可读(read)、 w 代表可写(write)、 x 代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号 - 而已。

    点开头是隐藏文件、深蓝色目录、浅蓝色链接、红色压缩文件、绿色可执行文件。

    每个文件的属性由左边第一部分的 10 个字符来确定(如下图)。

     

    从左至右用 0-9 这些数字来表示。

    第 0 位确定文件类型,第 1-3 位确定属主(该文件的所有者)拥有该文件的权限。

    第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。

    其中,第 1、4、7 位表示读权限,如果用 r 字符表示,则有读权限,如果用 - 字符表示,则没有读权限;

    第 2、5、8 位表示写权限,如果用 w 字符表示,则有写权限,如果用 - 字符表示没有写权限;第 3、6、9 位表示可执行权限,如果用 x 字符表示,则有执行权限,如果用 - 字符表示,则没有执行权限。

    Linux文件属主和属组

    1. [root@www /]# ls -l
    2. total 64
    3. drwxr-xr-x 2 root root 4096 Feb 15 14:46 cron
    4. drwxr-xr-x 3 mysql mysql 4096 Apr 21 2014 mysql
    5. ……

    对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。

    同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。

    文件所有者以外的用户又可以分为文件所属组的同组用户和其他用户。

    因此,Linux系统按文件所有者、文件所有者同组用户和其他用户来规定了不同的文件访问权限。

    在以上实例中,mysql 文件是一个目录文件,属主和属组都为 mysql,属主有可读、可写、可执行的权限;与属主同组的其他用户有可读和可执行的权限;其他用户也有可读和可执行的权限。

    对于 root 用户来说,一般情况下,文件的权限对其不起作用。

    ls命令相关参数:

    单纯使用ls命令,显示的内容有限。在实际使用的时候,经常需要搭配一些选项来显示更加丰富的内容,ls常用的附加选项如下表所示:

    选项作用
    -a显示指定路径中的所有文件,包括隐藏文件
    -l显示文件的详细信息,包括文件类型,权限,所属用户,所属用户组,文件大小,上一次修改时间等
    -h文件大小以KBytes为单位显示
    -S按照文件大小顺序显示,默认从大到小;若要从小到大,可使用-Sr

    ls -al

    -a选项的作用是显示出路径中的所有文件,-l选项的作用是显示文件的详细信息,二者叠加使用就会显示路径中所有文件的详细信息,同样以Home路径为例,运行ls -al命令,结果如下图所示:

    显示的关键信息以及使用红色框标记出来。其中,第一行的total 72:表示当前目录下的所有内容大小为72Kbytes。除去第一行,剩余的信息可以分为6大块:

    2: 共10个字母,第1个字母表示文件类型(-表示普通文件,d表示目录文件,b表示块设备文件,c表示字符设备文件,l表示链接文件,p表示管道文件,s表示socket文件)。剩余的9个字母可以分为3组,分表表示所属用户,所属用户组,其他用户对该文件的读写权限(R表示可读,W表示可写,X表示可执行,-表示不具备相应权限)
    3: 紧跟在权限之后的1个数字,表示目录文件里面包含的目录文件数(包括普通目录文件和隐藏目录文件);如果是文件,则表示该文件的链接数
    4: 所属用户
    5: 所属用户组
    6: 文件大小,以字节为单位
    7: 文件的mtime

    ls -alh

    上图中各文件的大小均是以字节为单位,不符合正常使用习惯,可以使用-h选项,使文件大小以KBytes为单位。同样以Home路径为例,运行ls -alh命令,结果如下:

    从上图可见,所有文件的大小均已经以KBytes为单位(部分大小不足1KBytes的文件除外)

    ls -alhS

    默认的文件显示顺序是按照首字母的顺序进行排列的,有时可能需要按照文件大小进行排序,这时可以使用-S选项。同样在Home目录下,运行ls -alhS命令,结果如下图所示:

    默认顺序是按照文件大小由大到小排列,如想要有效达到排列,则可以使用-Sr选项。运行ls -alhSr的效果如下:

    (2)chown

    chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID;组可以是组名或者组ID;文件是以空格分开的要改变权限的文件列表,支持通配符。

    系统管理员经常使用chown命令,在将文件拷贝到另一个用户的名录下之后,让用户拥有使用该文件的权限。 

    • chown (change owner) : 修改所属用户与组。

    命令格式:

    chown [选项]... [所有者][:[组]] 文件...

    命令功能:

    通过chown改变文件的拥有者和群组。在更改文件的所有者或所属群组时,可以使用用户名称和用户识别码设置。普通用户不能将自己的文件改变成其他的拥有者。其操作权限一般为管理员。

    命令参数:

    1. 必要参数:
    2. -c 显示更改的部分的信息
    3. -f 忽略错误信息
    4. -h 修复符号链接
    5. -R 处理指定目录以及其子目录下的所有文件
    6. -v 显示详细的处理信息
    7. -deference 作用于符号链接的指向,而不是链接文件本身
    8. 选择参数:
    9. --reference=<目录或文件> 把指定的目录/文件作为参考,把操作的文件/目录设置成参考文件/目录相同拥有者和群组
    10. --from=<当前用户:当前群组> 只有当前用户和群组跟指定的用户和群组相同时才进行改变
    11. --help 显示帮助信息
    12. --version 显示版本信息

    改变拥有者和群组:

    1. chown mail:mail log2012.log
    2. [root@localhost test6]# ll
    3. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    4. ---xr--r-- 1 root users 302108 11-30 08:39 log2012.log
    5. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    6. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    7. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    8. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    9. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log
    10. [root@localhost test6]# chown mail:mail log2012.log
    11. [root@localhost test6]# ll
    12. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    13. ---xr--r-- 1 mail mail 302108 11-30 08:39 log2012.log
    14. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    15. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    16. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    17. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    18. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log
    19. [root@localhost test6]#
    1. chown root: log2012.log
    2. [root@localhost test6]# ll
    3. 总计 604
    4. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    5. ---xr--r-- 1 mail mail 302108 11-30 08:39 log2012.log
    6. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    7. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    8. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    9. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    10. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log
    11. [root@localhost test6]# chown root: log2012.log
    12. [root@localhost test6]# ll
    13. 总计 604
    14. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    15. ---xr--r-- 1 root root 302108 11-30 08:39 log2012.log
    16. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    17. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    18. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    19. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    20. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log
    21. [root@localhost test6]#

    改变文件群组:

    1. chown :mail log2012.log
    2. 复制代码
    3. [root@localhost test6]# ll
    4. 总计 604
    5. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    6. ---xr--r-- 1 root root 302108 11-30 08:39 log2012.log
    7. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    8. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    9. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    10. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    11. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log
    12. [root@localhost test6]# chown :mail log2012.log
    13. [root@localhost test6]# ll
    14. 总计 604
    15. ---xr--r-- 1 root users 302108 11-30 08:39 linklog.log
    16. ---xr--r-- 1 root mail 302108 11-30 08:39 log2012.log
    17. -rw-r--r-- 1 root users 61 11-30 08:39 log2013.log
    18. -rw-r--r-- 1 root users 0 11-30 08:39 log2014.log
    19. -rw-r--r-- 1 root users 0 11-30 08:39 log2015.log
    20. -rw-r--r-- 1 root users 0 11-30 08:39 log2016.log
    21. -rw-r--r-- 1 root users 0 11-30 08:39 log2017.log

    改变指定目录以及其子目录下的所有文件的拥有者和群组: 

    1. chown -R -v root:mail test6
    2. [root@localhost test]# ll
    3. drwxr-xr-x 2 root users 4096 11-30 08:39 test6
    4. [root@localhost test]# chown -R -v root:mail test6
    5. “test6/log2014.log” 的所有者已更改为 root:mail
    6. “test6/linklog.log” 的所有者已更改为 root:mail
    7. “test6/log2015.log” 的所有者已更改为 root:mail
    8. “test6/log2013.log” 的所有者已更改为 root:mail
    9. “test6/log2012.log” 的所有者已保留为 root:mail
    10. “test6/log2017.log” 的所有者已更改为 root:mail
    11. “test6/log2016.log” 的所有者已更改为 root:mail
    12. “test6” 的所有者已更改为 root:mail
    13. [root@localhost test]# ll
    14. drwxr-xr-x 2 root mail 4096 11-30 08:39 test6
    15. [root@localhost test]# cd test6
    16. [root@localhost test6]# ll
    17. 总计 604
    18. ---xr--r-- 1 root mail 302108 11-30 08:39 linklog.log
    19. ---xr--r-- 1 root mail 302108 11-30 08:39 log2012.log
    20. -rw-r--r-- 1 root mail 61 11-30 08:39 log2013.log
    21. -rw-r--r-- 1 root mail 0 11-30 08:39 log2014.log
    22. -rw-r--r-- 1 root mail 0 11-30 08:39 log2015.log
    23. -rw-r--r-- 1 root mail 0 11-30 08:39 log2016.log
    24. -rw-r--r-- 1 root mail 0 11-30 08:39 log2017.log

    chgrp:更改文件属组

    语法:

    chgrp [-R] 属组名 文件名

    参数选项

    • -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。

    (3)chmod

    权限简介

    Linux系统上对文件的权限有着严格的控制,如果想对某个文件执行某种操作,必须具有对应的权限方可执行成功。

    Linux下文件的权限类型一般包括读,写,执行。对应字母为 r、w、x。

    Linux下权限的粒度有 拥有者 、群组 、其它组 三种。每个文件都可以针对三个粒度,设置不同的rwx(读写执行)权限。通常情况下,一个文件只能归属于一个用户和组, 如果其它的用户想有这个文件的权限,则可以将该用户加入具备权限的群组,一个用户可以同时归属于多个组。

    权限标志通过三个“位”来定义,分别是:

    setuid:设置使文件在执行阶段具有文件所有者的权限。比如/usr/bin/passwd,如果一般用户执行该文件,则在执行过程中,该文件可以获得root权限,从而可以更改用户的密码。

    setgid:该权限只对目录有效。目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组。

    sticky bit:该位可以理解为防删除位。 一个文件是否可以被某用户删除,主要取决于该文件所属的组是否对该用户具有写权限。如果没有写权限,则这个目录下的所有文件都不能被删除,同时也不能添加新的文件。 如果希望用户能够添加文件但同时不能删除文件,则可以对文件使用sticky bit位。设置该位后,就算用户对目录具有写权限也不能删除该文件。

    三个权限的特点:

    Sticky(范例:/tmp目录)

    ①sticky只能应用在目录上,并且是应用在其它人上。

    ②只有root和文件的拥有人才能删除该文件。

    ③小写表示能执行,大写表示不能执行

    Suid(范例:/usr/bin/passwd目录)

    ①suid只能应用在二进制文件中

    ②当一个文件应用了suid,那么任何人在执行该命令的时候他就临时拥有该文件拥有人的权限

    ③suid只能应用在文件的拥有人上

    ④小写表示能执行,大写表示不能执行

    Sgid(应用环境为用于一组开发人员共用资源,保证安全)

    ①sgid既可以应用在文件上,也可以应用在目录上

    ②当sgid应用在目录上时,任何人在该目录中建立健全的文件和目录的拥有者属于目录所属组

    ③应用在拥有组上

    ④sgid应用在文件上时,任何人在执行该文件时,临时拥有该文件所属组权限

    ⑤小写表示可执行,大写反之。

    如何操作这些标志,操作这些标志与操作文件权限的命令是一样的, 都是 chmod。

    chmod格式:

    chmod [可选项] <mode> <file...>
    1. 参数说明:
    2. [可选项]
    3. -c, --changes like verbose but report only when a change is made (若该档案权限确实已经更改,才显示其更改动作)
    4. -f, --silent, --quiet suppress most error messages (若该档案权限无法被更改也不要显示错误讯息)
    5. -v, --verbose output a diagnostic for every file processed(显示权限变更的详细资料)
    6. --no-preserve-root do not treat '/' specially (the default)
    7. --preserve-root fail to operate recursively on '/'
    8. --reference=RFILE use RFILE's mode instead of MODE values
    9. -R, --recursive change files and directories recursively (以递归的方式对目前目录下的所有档案与子目录进行相同的权限变更)
    10. --help 显示此帮助信息
    11. --version 显示版本信息
    12. [mode]
    13. 权限设定字串,详细格式如下 :
    14. [ugoa...][[+-=][rwxX]...][,...],
    15. 其中
    16. [ugoa...]
    17. u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示所有(包含上面三者)。
    18. [+-=]
    19. + 表示增加权限,- 表示取消权限,= 表示唯一设定权限。
    20. [rwxX]
    21. r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
    22. [file...]
    23. 文件列表(单个或者多个文件、文件夹)

    有两种方法来操作:

    1、suid、sgid方式

    chmod u+s temp -- 为temp文件加上setuid标志。 (setuid 只对文件有效)

    chmod g+s tempdir -- 为tempdir目录加上setgid标志 (setgid 对目录和文件有效)

    chmod o+t temp -- 为temp文件加上sticky标志 (sticky只对文件有效)

    设置所有用户可读取文件 a.conf:

    1. chmod ugo+r a.conf
    2. chmod a+r a.conf

    设置 c.sh 只有 拥有者可以读写及执行:

    chmod u+rwx c.sh
    

    设置文件 a.conf 与 b.xml 权限为拥有者与其所属同一个群组 可读写,其它组可读不可写:

    chmod a+r,ug+w,o-w a.conf b.xml
    

    设置当前目录下的所有档案与子目录皆设为任何人可读写:

    chmod -R a+rw *
    

    2、采用八进制,数字权限方式

    对一般文件通过三组八进制数字来置标志,如 666,777,644等。如果设置这些特殊标志,则在这组数字之外外加一组八进制数字,如4666,2777等。

    在这种使用方式中,首先我们需要了解数字如何表示权限。 首先,我们规定 数字 4 、2 和 1表示读、写、执行权限(具体原因可见下节权限详解内容),即 r=4,w=2,x=1 。此时其他的权限组合也可以用其他的八进制数字表示出来。

    这一组八进制数字三位的意义如下:

    rwx = 4 + 2 + 1 = 7

    rw = 4 + 2 = 6

    rx = 4 +1 = 5

    若要同时设置 rwx (可读写运行) 权限则将该权限位 设置 为 4 + 2 + 1 = 7

    若要同时设置 rw- (可读写不可运行)权限则将该权限位 设置 为 4 + 2 = 6

    若要同时设置 r-x (可读可运行不可写)权限则将该权限位 设置 为 4 +1 = 5

    上面我们提到,每个文件都可以针对三个粒度,设置不同的rwx(读写执行)权限。即我们可以用用三个8进制数字分别表示 拥有者 、群组 、其它组( u、 g 、o)的权限详情,并用chmod直接加三个8进制数字的方式直接改变文件权限。

    语法格式为 :

    1. chmod <abc> file...
    2. 其中
    3. a,b,c各为一个数字,分别代表UserGroup、及Other的权限。
    4. 相当于简化版的
    5. chmod u=权限,g=权限,o=权限 file...
    6. 而此处的权限将用8进制的数字来表示UserGroup、及Other的读、写、执行权限

    设置所有人可以读写及执行:

    chmod 777 file  (等价于  chmod u=rwx,g=rwx,o=rwx file 或  chmod a=rwx file)
    

    设置拥有者可读写,其他人不可读写执行:

    chmod 600 file (等价于  chmod u=rw,g=---,o=--- file 或 chmod u=rw,go-rwx file )
    

    (4)Linux附加权限

    十位权限表示

    常见的权限表示形式有:

    1. -rw------- (600) 只有拥有者有读写权限。
    2. -rw-r--r-- (644) 只有拥有者有读写权限;而属组用户和其他用户只有读权限。
    3. -rwx------ (700) 只有拥有者有读、写、执行权限。
    4. -rwxr-xr-x (755) 拥有者有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
    5. -rwx--x--x (711) 拥有者有读、写、执行权限;而属组用户和其他用户只有执行权限。
    6. -rw-rw-rw- (666) 所有用户都有文件读、写权限。
    7. -rwxrwxrwx (777) 所有用户都有读、写、执行权限。

    后九位解析: 我们知道Linux权限总共有三个属组,这里我们给每个属组使用三个位置来定义三种操作(读、写、执行)权限,合起来则是权限的后九位。 上面我们用字符表示权限,其中 -代表无权限,r代表读权限,w代表写权限,x代表执行权限。(后九位的前3位对应拥有者权限、4-6位对应群组权限、7-9对应其他组权限)

    关于第一位最高位的解释: 上面我们说到了权限表示中后九位的含义,剩下的第一位代表的是文件的类型,类型可以是下面几个中的一个:

    1. d代表的是目录(directroy)
    2. -代表的是文件(regular file)
    3. s代表的是套字文件(socket)
    4. p代表的管道文件(pipe)或命名管道文件(named pipe)
    5. l代表的是符号链接文件(symbolic link)
    6. b代表的是该文件是面向块的设备文件(block-oriented device file)
    7. c代表的是该文件是面向字符的设备文件(charcter-oriented device file)

    十二位权限(Linux附加权限)

    linux除了设置正常的读写操作权限外,还有关于一类设置也是涉及到权限,叫做Linxu附加权限。包括 SET位权限(suid,sgid)和粘滞位权限(sticky)。

    SET位权限:

    suid/sgid是为了使“没有取得特权用户要完成一项必须要有特权才可以执行的任务”而产生的。

    一般用于给可执行的程序或脚本文件进行设置,其中SUID表示对属主用户增加SET位权限,SGID表示对属组内用户增加SET位权限。

    执行文件被设置了SUID、SGID权限后,任何用户执行该文件时,将获得该文件属主、属组账号对应的身份。

    1、suid(set User ID,set UID)的意思是进程执行一个文件时通常保持进程拥有者的UID。然而,如果设置了可执行文件的suid位,进程就获得了该文件拥有者的UID。

    2、sgid(set Group ID,set GID)意思也是一样,只是把上面的进程拥有者改成了文件拥有组(group)。

    在许多场景下,使用suid 和 sgid 非常实用,但是不恰当地使用这些权限可能为系统带来安全风险。所以应该尽量避免使用SET位权限程序。(passwd 命令是为数不多的必须要使用“suid”的命令之一)。

    SET位权限表示形式(10位权限):

    如果一个文件被设置了suid或sgid位,会分别表现在所有者或同组用户的权限的可执行位上;如果文件设置了suid还设置了x(执行)位,则相应的执行位表示为s(小写)。但是,如果没有设置x位,它将表示为S(大写)。如:

    1. 1-rwsr-xr-x 表示设置了suid,且拥有者有可执行权限
    2. 2-rwSr--r-- 表示suid被设置,但拥有者没有可执行权限
    3. 3-rwxr-sr-x 表示sgid被设置,且群组用户有可执行权限
    4. 4-rw-r-Sr-- 表示sgid被设置,但群组用户没有可执行权限

    设置方式:

    SET位权限可以通过chmod命令设置,给文件加suid和sgid的命令如下(类似于上面chmod赋予一般权限的命令):

    1. chmod u+s filename 设置suid位
    2. chmod u-s filename 去掉suid设置
    3. chmod g+s filename 设置sgid位
    4. chmod g-s filename 去掉sgid设置

    粘滞位权限:

    粘滞位权限即sticky。一般用于为目录设置特殊的附加权限,当目录被设置了粘滞位权限后,即便用户对该目录有写的权限,也不能删除该目录中其他用户的文件数据。设置了粘滞位权限的目录,是用ls查看其属性时,其他用户权限处的x将变为t。 使用chmod命令设置目录权限时,+t、-t权限模式可分别用于添加、移除粘滞位权限。

    粘滞位权限表示形式(10位权限):

    一个文件或目录被设置了粘滞位权限,会表现在其他组用户的权限的可执行位上。如果文件设置了sticky还设置了x(执行)位,其他组用户的权限的可执行位为t(小写)。但是,如果没有设置x位,它将表示为T(大写)。如:

    1. 1-rwsr-xr-t 表示设置了粘滞位且其他用户组有可执行权限
    2. 2-rwSr--r-T 表示设置了粘滞位但其他用户组没有可执行权限

    设置方式:

    sticky权限同样可以通过chmod命令设置:

    chmod +t <文件列表..>

    我们可以进一步使用4位八进制数字同时赋值正常权限和附加权限。

    chmod <sabc> file...

    其中s是表示附加权限的把八进制数字,abc与之前一致,分别是对应User、Group、及Other(拥有者、群组、其他组)的权限。因为SUID对应八进制数字是4,SGID对于八进制数字是2,则“4755”表示设置SUID权限,“6755”表示同时设置SUID、SGID权限。

    我们进一步将上小节的例子中的二进制数转变为八进制表示形式,则:

    1. -rw-r-Sr-- = 0 1 0 1 1 0 1 0 0 1 0 0 = 2644
    2. -rwsr-xr-x = 1 0 0 1 1 1 1 0 1 1 0 1 = 4755
    3. -rwsr-sr-x = 1 1 0 1 1 1 1 0 1 1 0 1 = 6755
    4. -rwsr-sr-t = 1 1 1 1 1 1 1 0 1 1 0 1 = 7755

    设置 netlogin 的权限为拥有者可读写执行,群组和其他权限为可读可执行:

    chmod 755 netlogin

    设置 netlogin 的权限为拥有者可读写执行,群组和其他权限为可读可执行,并且设置suid:

    chmod 4755 netlogin

    chmod 4755与chmod 755对比多了附加权限值4,这个4表示其他用户执行文件时,具有与所有者同样的权限(设置了SUID)。

    为什么要设置4755 而不是 755? 

    假设netlogin是root用户创建的一个上网认证程序,如果其他用户要上网也要用到这个程序,那就需要root用户运行chmod 755 netlogin命令使其他用户也能运行netlogin。但假如netlogin执行时需要访问一些只有root用户才有权访问的文件,那么其他用户执行netlogin时可能因为权限不够还是不能上网。这种情况下,就可以用 chmod 4755 netlogin 设置其他用户在执行netlogin也有root用户的权限,从而顺利上网。

    (5)umask

    在类unix系统中,umask是确定掩码设置的命令,该掩码控制如何为新创建的文件设置文件权限。

    umask确定了文件创建时的初始权限。

    文件或目录权限为文件目录默认权限减去umask得到初始文件权限,文件初始默认权限为0666,目录为0777。

    若用户umask为0002,则新创建的文件或目录在没有指定的情况下默认权限分别为0664、0775。

    使用方式:当不指定模式时,是查看默认的umask,当指定模式时,系统就会采用指定的模式,但是,指定的是临时生效的,也就是在当前shell下,如果想全局永久生效,那么就需要修改配置文件/etc/bashrc,修改的位置如下:

    第一个位置是修改普通用户的umask,第二个是修改root的umask。修改完了之后使用source /etc/bashrc重新读取配置文件。

    由于root用户默认的umask为022,所以当使用root创建一个目录时,目录的默认权限为755(drwxr-xr-x),创建的文件的默认权限为666-022 = 644(-rw-r--r--)。

    但是,当我们修改umask的时候,如果修改的umask反向遮罩出来的文件的权限中带有执行(x)权限,会默认对最终权限进行加一(还是防止恶意文件的执行),如下:

    创建的test.txt文件默认权限为666-001 = 665,即-rw-rw-r-x,由于会默认加一,所以文件的最终权限就变为了。

    -rw-rw-rw-,设计的就是这么巧妙。

    五、selinux

    系统资源都是通过进程来读取更改的,为了保证系统资源的安全,传统的Linux使用用户、文件权限的概念来限制资源的访问,通过对比进程的发起用户和文件权限以此来保证系统资源的安全,这是一种自由访问控制方式(DAC);但是随着系统资源安全性要求提高,出现了在Linux下的一种安全强化机制(SELinux),该机制为进程和文件加入了除权限之外更多的限制来增强访问条件,这种方式为强制访问控制(MAC)。这两种方式最直观的对比就是,采用传统DAC,root可以访问任何文件,而在MAC下,就算是root,也只能访问设定允许的文件。

    SELinux(Secure Enhanced Linux)安全增强的Linux是由美国国家安全局NSA针对计算机基础结构安全开发的一个全新的Linux安全策略机制。SELinux可以允许系统管理员更加灵活的来定义安全策略。

    SELinux是一个内核级别的安全机制,从Linux2.6内核之后就将SELinux集成在了内核当中,因为SELinux是内核级别的,所以我们对于其配置文件的修改都是需要重新启动操作系统才能生效的。

    现在主流发现的Linux版本里面都集成了SELinux机制,CentOS/RHEL都会默认开启SELinux机制。

    工作原理如下图:

    SELinux基本概念

    我们知道,操作系统的安全机制其实就是对两样东西做出限制:进程系统资源(文件、网络套接字、系统调用等)。

    在之前学过的知识当中,Linux操作系统是通过用户和组的概念来对我们的系统资源进行限制,我们知道每个进程都需要一个用户才能执行。

    在SELinux当中针对这两样东西定义了两个基本概念:域(domin)和上下文(context)。

    工作类型:

    SELinux下存在不同的规则,SELinux根据不同的工作类型对这些规则打开或关闭(on|off<布尔值1|0>),然后通过规则的开启与关闭具体地限制不同进程对文件的读取。

    getsebool -a 或者 sestatus -b 查看当前工作类型下各个规则的开启与否。

    setsebool -P 规则名称 [0|1]    # 修改当前工作类型下指定规则的开启关闭,-P表示同时修改文件使永久生效。

    域就是用来对进行进行限制,而上下文就是对系统资源进行限制。

    security context介绍

    安全上下文存在于进程与文件中,context随进程一起存入内存中,文件的context存放在其对应的inode中,因此进程在访问文件时,要先读取inode,再判断是否能够访问该文件。

    1. ls -Z # 显示文件的安全上下文
    2. ps -eZ # 显示所有进程的安全上下文

    我们可以通过 ps -Z 这命令来查看当前进程的域的信息,也就是进程的SELinux信息:

    1. [root@xiaoluo ~]# ps -Z
    2. LABEL PID TTY TIME CMD
    3. unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2503 pts/0 00:00:00 su
    4. unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2511 pts/0 00:00:00 bash
    5. unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 3503 pts/0 00:00:00 ps

    通过 ls -Z 命令我们可以查看文件上下文信息,也就是文件的SELinux信息:

    1. [root@xiaoluo ~]# ls -Z
    2. -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
    3. drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 Desktop
    4. -rw-r--r--+ root root system_u:object_r:admin_home_t:s0 install.log
    5. -rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog

    在稍后我们来探讨一下这些字段所代表的含义。

    策略

    在SELinux中,我们是通过定义策略来控制哪些域可以访问哪些上下文。

    在SELinux中,预置了多种的策略模式,我们通常都不需要自己去定义策略,除非是我们自己需要对一些服务或者程序进行保护。

    在CentOS/RHEL中,其默认使用的是目标(target)策略,那么何为目标策略呢?

    目标策略定义了只有目标进程受到SELinux限制,非目标进程就不会受到SELinux限制,通常我们的网络应用程序都是目标进程,比如httpd、mysqld,dhcpd等等这些网络应用程序。

    我们的CentOS的SELinux配置文件是存放在 /etc/sysconfig/ 目录下的 selinux 文件,我们可以查看一下里面的内容:

    1. [root@xiaoluo ~]# cat /etc/sysconfig/selinux
    2. # This file controls the state of SELinux on the system.
    3. # SELINUX= can take one of these three values:
    4. # enforcing - SELinux security policy is enforced.
    5. # permissive - SELinux prints warnings instead of enforcing.
    6. # disabled - No SELinux policy is loaded.
    7. SELINUX=enforcing
    8. # SELINUXTYPE= can take one of these two values:
    9. # targeted - Targeted processes are protected,
    10. # mls - Multi Level Security protection.
    11. SELINUXTYPE=targeted   // 我们的CentOS使用的策略就是目标策略

    SELinux模式

    SELinux的工作模式一共有三种 enforcing、permissive和disabled。

    ①enforcing  强制模式:只要是违反策略的行动都会被禁止,并作为内核信息记录。

    ②permissive  允许模式:违反策略的行动不会被禁止,但是会提示警告信息。

    ③disabled  禁用模式:禁用SELinux,与不带SELinux系统是一样的,通常情况下我们在不了解SELinux时,将模式设置成disabled,这样在访问一些网络应用时就不会出问题了。

    上面也说了SELinux的主配置文件是 /etc/sysconfig/selinux :

    1. [root@xiaoluo ~]# cat /etc/sysconfig/selinux
    2. # This file controls the state of SELinux on the system.
    3. # SELINUX= can take one of these three values:
    4. # enforcing - SELinux security policy is enforced.
    5. # permissive - SELinux prints warnings instead of enforcing.
    6. # disabled - No SELinux policy is loaded.
    7. SELINUX=enforcing  //  我们看到SELinux默认的工作模式是enforcing
    8. # SELINUXTYPE= can take one of these two values:
    9. # targeted - Targeted processes are protected,
    10. # mls - Multi Level Security protection.
    11. SELINUXTYPE=targeted

    使用命令修改工作模式只在当前有效,想要开机生效,而且如果想要在disabled和其他两种模式之间切换,只有修改配置文件参数然后重启,该配置文件是/etc/selinux/config,另外也可以通过/etc/sysconfig/selinux文件修改,其实该文件是/etc/selinux/config的软链接文件。

    我们SELinux默认的工作模式是enforcing,我们可以将其修改为 permissive或者是disabled。

    1. cat /etc/selinu/config
    2. sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

    我们如果要查看当前SELinux的工作状态,可以使用 getenforce 命令来查看:

    1. [root@xiaoluo ~]# getenforce
    2. Enforcing

    当前的工作模式是 enforcing,我们如果要设置当前的SELinux工作状态,可以使用 setenforce [0|1] 命令来修改,setenforce 0表示设置成 permissive,1表示enforcing

    注意:通过 setenforce 来设置SELinux只是临时修改,当系统重启后就会失效了,所以如果要永久修改,就通过修改SELinux主配置文件。

    1. [root@xiaoluo ~]# setenforce 0
    2. [root@xiaoluo ~]# getenforce
    3. Permissive
    4. [root@xiaoluo ~]# setenforce 1
    5. [root@xiaoluo ~]# getenforce
    6. Enforcing

     我们可以通过 ls -Z 这个命令来查看我们文件的上下文信息,也就是SELinux信息:

    1. [root@xiaoluo ~]# ls -Z
    2. -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
    3. drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 Desktop
    4. -rw-r--r--+ root root system_u:object_r:admin_home_t:s0 install.log
    5. -rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog

    我们发现其比传统的 ls 命令多出来了 system_u:object_r:admin_home_t:s0 这个东西,我们现在就来分析一下这段语句所代表的含义:

    system_u:object_r:admin_home_t:s0
    

    这条语句通过:划分成了四段,第一段 system_u 代表的是用户,第二段 object_r 表示的是角色,第三段是SELinux中最重要的信息,admin_home 表示的是类型,最后一段 s0 是跟MLS、MCS相关的东西,暂时不需要管。

    1. ①system_u  指的是SElinux用户,root表示root账户身份,user_u表示普通用户无特权用户,system_u表示系统进程,通过用户可以确认身份类型,一般搭配角色使用。身份和不同的角色搭配时有权限不同,虽然可以使用su命令切换用户但对于SElinux的用户并没有发生改变,账户之间切换时此用户身份不变,在targeted策略环境下用户标识没有实质性作用。
    2. ②object_r  object_r一般为文件目录的角色、system_r一般为进程的角色,在targeted策略环境中用户的角色一般为system_r。用户的角色类似用户组的概念,不同的角色具有不同的身份权限,一个用户可以具备多个角色,但是同一时间只能使用一个角色。在targeted策略环境下角色没有实质作用,在targeted策略环境中所有的进程文件的角色都是system_r角色。
    3. ③admin_home  文件和进程都有一个类型,SElinux依据类型的相关组合来限制存取权限。

    Selinux实例

    下面我们通过一个实例来看一下上下文 context 的值和SELinux的访问控制

    比如说我搭建好了一个Web服务器,我们知道www服务器其默认网页存放位置是在 /var/www/html 这个目录下,我们如果在这里新建一个 index.html 测试页面,启动我们的www服务器,刷新就能见到其内容了,这时我们如果是在我们的 /home 目录下建立一个 index.html 页面,然后将其移动到 /var/www/html 这个目录下,再刷新页面,其还会不会正常显示呢?

    首先我们启动我们的 httpd 服务:

    1. [root@xiaoluo ~]# service httpd restart
    2. Stopping httpd: [ OK ]
    3. Starting httpd: httpd: apr_sockaddr_info_get() failed for xiaoluo
    4. httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
    5. [ OK ]

    然后打开浏览器,输入我们的 127.0.0.1 来访问,此时看到的界面是Apache的测试界面:

    因为我们此时的 /var/www/html 下还不存在任何页面:

    1. [root@xiaoluo home]# ll /var/www/html/
    2. total 0

    接下来我们在 /home 目录下建立一个 index.html 的页面,然后将其移动到我们的 /var/www/html 目录下:

    1. [root@xiaoluo home]# vi index.html
    2. This is a test about SELinux
    3. [root@xiaoluo home]# mv index.html /var/www/html/
    4. [root@xiaoluo html]# cd /var/www/html/
    5. [root@xiaoluo html]# ls
    6. index.html

    此时,按照正常情况,因为html目录下存在了一个index.html的页面,我们此时如果刷新浏览器页面,应该会跳转到index.html页面的。

    但是事实我们发现,页面还是在这个测试页面,到底是为什么呢?这个就跟我们的SELinux的安全策略有关系了,我们可以去 /var/log/audit 这个目录下查看 audit.log 这个文件,从中找出错误信息:

    1. [root@xiaoluo html]# tail /var/log/audit/audit.log
    2. type=CRED_DISP msg=audit(1369575601.957:289): user pid=3637 uid=0 auid=0 ses=44 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='op=PAM:setcred acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
    3. type=USER_END msg=audit(1369575601.957:290): user pid=3637 uid=0 auid=0 ses=44 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='op=PAM:session_close acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
    4. type=AVC msg=audit(1369575729.534:291): avc: denied { getattr } for pid=3619 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
    5. type=SYSCALL msg=audit(1369575729.534:291): arch=c000003e syscall=4 success=no exit=-13 a0=7f34198634f8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=7f341985ff60 items=0 ppid=3612 pid=3619 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
    6. type=AVC msg=audit(1369575729.535:292): avc: denied { getattr } for pid=3619 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
    7. type=SYSCALL msg=audit(1369575729.535:292): arch=c000003e syscall=6 success=no exit=-13 a0=7f34198635c8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=1 items=0 ppid=3612 pid=3619 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
    8. type=AVC msg=audit(1369575736.549:293): avc: denied { getattr } for pid=3618 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
    9. type=SYSCALL msg=audit(1369575736.549:293): arch=c000003e syscall=4 success=no exit=-13 a0=7f34198634f8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=7f341985ff60 items=0 ppid=3612 pid=3618 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
    10. type=AVC msg=audit(1369575736.549:294): avc: denied { getattr } for pid=3618 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
    11. type=SYSCALL msg=audit(1369575736.549:294): arch=c000003e syscall=6 success=no exit=-13 a0=7f34198635c8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=1 items=0 ppid=3612 pid=3618 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)

    从这个日志文件中,我们就可以看到刷新页面不出来index.html的原因就是因为我们的SELinux安全策略所导致的

    我们通过 ls -Z 命令先来看看刚移动过来的 index.html 的上下文信息:

    1. [root@xiaoluo html]# ls -Z
    2. -rw-r--r--. root root unconfined_u:object_r:home_root_t:s0 index.html

    我们发现其第三个字段的类型是 home_root_t,这是为什么呢?因为我们刚才是在 /home 目录下创建的这index.html文件,所以其默认会继承上一层目录的SELinux的类型信息,我们可以查看一下 /home 这个目录的上下文信息:

    1. [root@xiaoluo html]# ls -Z -d /home/
    2. drwxr-xr-x. root root system_u:object_r:home_root_t:s0 /home/

    我们看到,其第三个字段和我们刚才的index.html相同,由此可以看出文件的context值是受上一级目录影响的,一般情况下它们会继承上一级目录的context值,但是,一些安装服务产生的文件context值会例外,不继承上级目录的context值,服务会自动创建它们的context值,比如没有装http服务的时候/var/目录下时没有www目录的,安装httpd服务后该服务会自动创建出所需的目录,并定义与服务相关的目录及文件才context值,它们并不会继承上级目录的context值。

    1. [root@xiaoluo html]# ls -Z -d /var
    2. drwxr-xr-x. root root system_u:object_r:var_t:s0 /var
    3. [root@xiaoluo html]# ls -Z -d /var/www/html/
    4. drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

    此时我们发现我们的 /var/www/html 这个目录的上下文类型是 httpd_sys_content_t, 而我们刚才移动过来的 index.html 的类型却是 home_root_t,因为我们此时的SELinux的工作模式是 enforcing,所以对于违反策略的行动是被禁止的,所以我们刷新页面并不会出现我们的index.html里面的信息,那么我们这个时候应该解决这个问题呢?

    通常解决办法由两种:

    ①直接将SELinux的工作模式设置成 disabled,这样就不会出现策略拦截问题了,但是这样的话我们的系统就没有SELinux安全防护了

    ②通过 restorecon 或者 chcon 命令来修复我们的文件上下文信息

    命令 restorecon 可以用来恢复文件默认的上下文:

    restorecon -R -v /var/www/html/index.html  //-R 表示递归,如果是目录,则该目录下的所有子目录、文件都会得到修复  

    命令 chcon 可以改变文件的上下文信息,通常我们使用一个参照文件来进行修改:

    chcon --reference=/var/www/html/index.html /var/www/html/test.html

    这里我们通过使用 restorecon 命令来恢复我们文件默认的上下文:

    1. [root@xiaoluo html]# restorecon -v index.html
    2. restorecon reset /var/www/html/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
    3. [root@xiaoluo html]# ls -Z
    4. -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

    我们看到,使用 restorecon 命令以后,index.html的上下文信息就继承了上一级目录 html 这个目录的上下文信息了,这个时候我们再刷新页面就可以看到我们index.html里面的内容了。

    通过这个实例我们就明白了文件的上下文信息与SELinux之间的关系了,并知道了通过查看 /var/log/audit/audit.log 这个日志文件的信息找出错误所在,以及通过 restorecon 命令来修复我们的文件的上下文信息。

    安装testlink时,出现”testlink/gui/templates_c、testlink/logs、testlink/upload_area不可写”

    在Testlink安装到最后,'...目录是否可写(由于用户运行webserver进程)’过程出错,如下图所示:

    1、/var/www/html/testlink/gui/templates_c、/var/www/html/testlink/logs、/var/www/html/testlink/upload_area这些目录没有写权限。

    所以先去给赋了些权限:

    1. chmod -R 777 /var/www/html/testlink/gui/templates_c
    2. chmod -R 777 /var/www/html/testlink/logs
    3. chmod -R 777 /var/www/html/testlink/upload_area

    所有目录都有了写权限,仍然没有解决这个问题。

    2. 原来是SELinux阻止/usr/sbin/httpd 对/var/www/html/testlink/gui/templates_c进行写操作,以前只知道有SELlinx,最多也是接触过SELinx的关闭.所以最简单的方法就是关闭SELinux。

    那如果不关闭SELinux又该怎样做呢?

    SELinux极大的增强了Linux系统的安全性,能将用户权限关在笼子里,如httpd服务,因此能有效的防范0-day类的攻击。

    a) 用如下命令获取默认/var/www目录的SELinux上下文:

    semanage fcontext -l |grep '/var/www'

    从中可以看到Apache只能访问包含 httpd_sys_rw_content_t标签的文件,如果希望Apchae使用某个目录作为网站文件目录,就需要给这个目录下的文件增加httpd_sys_content_t标签。

    b) 那么,首先在这个目录下的文件添加默认标签类型:

    semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/testlink/gui/templates_c'
    

    c) 然后用新的标签类型标注已有文件,Apache就可以使用改目录下的文件构建网站了:

    restorecon -v '/var/www/html/testlink/gui/templates_c'

     d) 按同样的方法,修改/var/www/html/testlink/logs和/var/www/html/testlink/upload_area。

    SELinux日志管理

    SELinux阻止的进程的日志记录存放在/var/log/audit/audit.log文件中,但是该文件中的内容用户阅读体验很差,可以去cat /var/log/audit/audit.log看看,因此系统为我们提供了sealert工具,帮助我们整理该日志文件,sealert工具处理日志文件的时候需要花费一点时间,请耐心等待。

    另外SELinux的日志功能需要auditd.service服务的开启。

    1. 确保本机配置了httpd服务并处于开启状态:

     2./ usr/sbin/httpd命令会开启进程去读取/var/www/html/目录下以.html结尾的文件,现在在家目录下创建文件~/index.html,随意编写内容,之后把新创建的文件移动至/var/www/html/下。

    3.我们通过浏览器,在地址栏输入本机IP,查看成功与否,当出现如下界面的时候表示访问失败。

    4.我们在配置服务的时候确定了没有问题,这时候我们要想到可能是SELinux阻止了我们访问。我们通过命令:

    sealert -a /var/log/audit/audit.log

    查看SELinux日志,我们找到httpd的关键字,阅读内容,下图中的内容是我们主要关注的部分,其他则是/var/log/audit/audit.log的内容,我们可以忽略。最后我们优先考虑改动最小的解决方案,即修改SELinux标签。

    5.执行命令restorecon -v /var/www/html/index.html,就是修改该文件为httpd能够访问的默认标签。

    6.再用浏览器访问查看结果,这次成功。

  • 相关阅读:
    ArcGIS软件制作双变量等值区域地图(Bivariate Choropleth Maps)
    ActiveMQ是什么?-九五小庞
    JavaScript防抖和节流(从认识到理解到手写)
    开发高性能知识付费平台:关键技术策略
    Spring中bean的注入方式
    【软件工程与实践】(第四版)第6章习题答案详解
    我对汉诺塔问题的理解
    RHCE之路从服务器,selinux
    Python批量爬取简历模板
    在 Vue 应用中下载.doc文档(或任何其他类型的文件)
  • 原文地址:https://blog.csdn.net/qq_35029061/article/details/126205363