Linux的用户与管理

很久以来,我对Linux用户的概念都很模糊,只知道如果碰到“Permission Denied”就用sudo来执行,甚至在服务器上跑的很多东西都是用root来跑的。今天花时间学习了一下Linux用户有关的知识,记一下笔记。

本文所有代码都是在virtualbox虚拟机中进行,环境:Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-87-generic x86_64),用户名vagrant,密码vagrant。

一、用户与用户组

1.Linux是如何分辨每一个用户的

Linux并不是通过用户名来分辨每一个用户的,而是通过UID(计算机认识数字比较容易,而人类认识单词比较容易),我们平时所说的用户名只是便于人类操作和记忆。

对于每个文件,记录的其实是一个UID,之所以显示成用户名“vagrant”、“root”,是因为在/etc/passwd中存储了有关的用户信息,ls程序在显示的时候,会根据此文件将对应的UID显示成用户名。如果我们在/etc/passwd这个文件中将UID修改,那么ls将显示的是一个UID,而不是用户名。

用户登录Linux的流程如下:

  1. 寻找/etc/passwd是否有这个用户名,如果有,读出对象的UID和GID(group ID),以及主目录和配置
  2. 读取/etc/shadow,核对密码
  3. 进入shell

2. passwd文件和shadow文件

Linux所有的用户都保存在/etc/passwd文件中,格式如下:

每一行代表一个账户,通过:来分割信息。数一数会发现一共有7个字段,这7个字段分别代表:

  1. 账户名称
  2. 密码,可以看到所有的密码都是x,这是因为很多程序会读/etc/passwd,将用户名和密码放在一起很不安全,后来密码移动到 /etc/shadow文件中了,/etc/passwd文件只留一个x占位。
  3. UID
  4. GID
  5. 用户信息说明
  6. 主目录(即登录之后立即所在的位置)
  7. shell 登录之后启动的shell,这里有一个特殊的shell就是nologin,上面的例子中,像是backup这种账户是无法登录shell的。所以当我们新建一些系统服务的账号,类似apache,Jenkins等都可以让它们不要登录系统

/etc/shadow文件的格式如下:

可以看到,这也是用:来分割的,一共有9列,每一列代表的意思如下:

  1. 账户名称
  2. 密码
  3. 最近改动密码的日期(相对于第0天,也就是1970年1月1日的偏移天数)
  4. 密码不可改动的日期,如果是0则可以随时修改
  5. 密码需要重新更改的日期,如果不改账户将会变为过期。可以看到默认设置是99999=273年
  6. 字段5前几天进行提醒
  7. 密码过期后的宽限时间,字段5+本字段天数之后依然没有更改才算过期。宽限时间内用户登录会被强制要求修改密码
  8. 账户失效日期,到期无法使用
  9. 保留字段

3.有效用户组与初始用户组

每一个用户都有一个用户组,和UID一样,Linux分辨用户组也是通过GID的,而不是通过名字。和/etc/passwd /etc/shadow一样,对于用户组有 /etc/group /etc/gshadow

先来看/etc/group

一共四个字段:

  1. 用户组名字
  2. 用户组密码,其实很少用,和passwd一样,用x占位了
  3. GID
  4. 此用户组的用户列表,逗号分搁,没有空格(一个用户组可以有多个用户,一个用户可以在多个用户组)

/etc/gshadow的内容几乎和/etc/group一样:

要注意的事第二个字段,是密码,如果第二个字段是!,表明该用户组没有用户组管理员。不过由于sudo的存在,其实用户组管理员的功能很少使用了。

  1. 用户组名字
  2. 密码列
  3. 用户组管理员的账号
  4. 该用户组的所属账号

仔细观察你可能发现这样一个问题:在/etc/passwd里面说某一个用户的用户组ID是a,但是在/etc/group的a用户组ID下并没有看到这个账户的名字啊?

这是因为,passwd里面的用户组叫做“初始化用户组”,就是你登录到shell的用户组。这个用户组不需要写到groups里面。

如果一个用户属于很多用户组,这么这些用户组的权限,该用户都会有。那么创建一个文件,默认的用户组应该是哪个呢?

答案是“有效用户组”,通过groups命令,可以查看当前用户的所在用户组,其中,排在第一个的是有效用户组,如果创建文件就会模式使用这个用户组。

下面的命令演示了有效用户组以及用户组的切换:

需要注意的是,newgrp是通过新开一个shell来赋予用户新的用户组的权限,通过exit可以回到之前的用户组。

二、创建与管理用户

1.useradd

了解了用户和用户组的概念,接下来开始讲用户的管理。

创建一个新的账户的命令是useradd,执行这个命令需要读写/etc/passwd等文件,所以一般需要root账户来执行。

上面的代码新建了一个tom账户,可以看到,系统并没有默认为tom创建一个home目录。在CentOS中,使用useradd,系统一般会默认帮你做这几件事:

  1. /etc/passwd中创建一行与账号相关的数据
  2. /etc/shadow创建相关数据,但是密码为空
  3. /etc/group创建一个与用户名一模一样的名称
  4. /home下创建一个和用户名一样的目录,权限700

我们简单的使用useradd命令,Linux会帮我们自动配置一些参数,这些参数是参考的哪里呢?见下面两条命令的输出就明白了:

2.passwd

创建用户用useradd,然后需要为用户创建密码,使用passwd命令。需要注意的有以下几点:

  1. passwd修改自己账户的密码,普通用户需要输入旧密码,root用户不需要
  2. root用户可以修改其他用户的密码而不需要输入旧密码
  3. 普通用户在创建密码时会经过PAM模块检查密码的强度,而root无需遵守强度检查

3.其他一些修改账户的命令(sudo)

chage命令可以修改密码参数有关的信息。

usermod可以修改有效用户组、初始用户组、主目录等与用户有关的信息。

userdel可以删除用户。这个命令非常危险,将会从/etc/passwd/etc/shadow,中删除用户,也会删除/home/user用户目录。一般情况下,我们暂停某个账户可以只将账户的状态设置为不可用,例如/etc/shadow第八个字段(账号失效日期)设置为0即可。如果确实需要删除用户,也可以用userdel -r username,这样会先删除find / -user username,然后再删除用户。

4.用户可以使用的一些命令

上面介绍的都是sudo用户对账户的管理,还有一些命令普通用户就可以使用:

  1. finger查阅用户有关的信息
  2. chfn change finger,修改用户的详细信息
  3. chsh 改变默认登录的shell
  4. id可以用来查询用户的id

5.用户组的管理

在上面我们已经认识了用户和用户组,以及用户的管理。其实用户组的管理也是类似,只不过是/etc/group/etc/gshadow而已。要注意的是,newgrp是新开启一个shell,用新的环境来登录用户和用户组的。仔细想想, 这是一个很有趣的问题。正好我在写这篇文章的第三天(本文估计要写一个周),Julia写了一篇博客:How do groups work on Linux? 这篇博客正好说明了newgrp的行为:Linux运行的进程都保存着有效组GID的属性,当进程想要通过组权限(这里略去了UID检查过程)读一个文件的时候,当看一个文件是否可以读的时候,Linux检查一下此进程的有效组里面是否有等于文件的组的,如果有那么就可以读。Julia之前误认为是:Linux检查一下此进程的用户是否可以读文件,如果不可以,就看一下用户所在的组,是否有等于文件所属的组的。——这样的话,就要每次去读/etc/passwd了!

另外有关用户组还要知道的一个命令是gpasswd,这个命令可以分配组管理员。组管理员可以添加或删除用户到某一个用户组。有点像论坛的版主的意思。

三、精确的权限控制ACL

我们知道,Linux的文件系统有三组权限,分别是“owner group other”,这样无法做到对同一group的成员,或对都是others的成员控制权限。所以就有了ACL(Access Control List)。ACL可以针对单一用户、单一文件或目录进行rwx的权限设置。这是一个UNIX-Like操作系统权限外的支持项目,需要文件系统的支持(mount | grep acl)。

这里没有啥需求所以没有仔细研究,更多的资料读者可以自行搜索,推荐IBM Linux ACL 体验

四、用户切换su, su – 和sudo

su用来切换用户,使用方法是 su - username-的意思是环境变量。比如说su - vagrant那么会以vagrant来登录shell,所有的环境变量都会变成vagrant的。如果不加-那么就只是id变成vagrant,进去之后如果收MAIL,还会是原来的用户的。

su - root就可以登录root账户了!其实root可以省略,su - 就是登录root账户的意思。使用某个账户临时运行一下命令:su - root -c command,这里的root也可以省略。注意如果root账户没有密码的话,会出现 Authentication failure。

su是简单的切换命令。现在有一个问题,如果每个人都有用root账户权限的需求,那么就要有很多人知道root账户的密码,这很不安全,所以就有了sudo命令。sudo可以让你用其他用户(通常是root账户)来执行命令。使用sudo的账户必须在/etc/sudoers里面。系统验证sudo的过程如下:

  1. 当用户执行sudo命令时,系统先从/etc/sudoers文件中检查用户是否有执行权限
  2. 如果有,让用户输入自己的密码
  3. 执行sudo后面的命令

sudoers文件支持对用户组授权(以%开头)。格式如下:

其中,可以修改最后一列为NOPASSWD:ALL来免除每次运行sudo都需要的密码操作。(设置之后简直每天可以多好几秒呢!)

好了,基本的管理和操作到这里差不多了,上面的学习过程都是参考的鸟哥的Linux私房菜第三版(这本书讲的挺细的但是有点啰嗦,让人摸不透重点)。其余还提到了一些内容,下面就只列一下,有需要的可以去了解:

  1. PAM模块,对密码强度的的检查就是这个模块实现的,基本上就是个API
  2. 查询在线用户与登录日志: w, who, last, lastlog
  3. 用户之间发送消息: write, mesg, wall
  4. 发送mail:MAIL
  5. 一些用户有关的检查工具:pwck, pwconv, pwunconv, chpasswd
  6. 如何批量创建账号? passwd --stdin

本文完结!(接下来是废话了)写这篇博客花了三个星期!好吧,虽然中间有各种各样别的事情来分心。之前有人在论坛上说,《鸟哥私房菜》这本书草草看了一遍但是不想再看了,又没学到什么东西。我也有差不多类似的感受,这本书好是好,但是太详细,实践又比较少,写的比较像手册(很多书都写的像手册)。学习的过程中不要怕慢,自己多试试就好了,多记笔记。感慨一下,人家制作出来的东西,我们竟然要花这么多时间去学习,差距啊。另外Linux的东西还是要扎扎实实学,多少年过去了,这些知识都没怎么变!

Linux的用户与管理”已经有4条评论

  1. 看起来太复杂了,做的事情也比较杂,做了部署的事情,还有监控管理,权限管理。相比之下ansible,saltstack部署,grafana监控这种专门的工具更加专业和可靠。可以参考一下aisible这种实现。

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注