惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
Schneier on Security
Schneier on Security
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
Scott Helme
Scott Helme
Webroot Blog
Webroot Blog
Project Zero
Project Zero
Google Online Security Blog
Google Online Security Blog
The Last Watchdog
The Last Watchdog
Spread Privacy
Spread Privacy
Hacker News: Ask HN
Hacker News: Ask HN
PCI Perspectives
PCI Perspectives
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News | PayPal Newsroom
Help Net Security
Help Net Security
The Hacker News
The Hacker News
H
Heimdal Security Blog
O
OpenAI News
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Security Affairs
P
Proofpoint News Feed
S
Secure Thoughts
腾讯CDC
Google DeepMind News
Google DeepMind News
量子位
罗磊的独立博客

卡瓦邦噶!

服务器高性能网络调优 | 卡瓦邦噶! 为何写作 | 卡瓦邦噶! 读《金阁寺》 | 卡瓦邦噶! 雨季又来 | 卡瓦邦噶! MTU Probe 引起的初始延迟 | 卡瓦邦噶! 3.5 秒的固定延迟问题 | 卡瓦邦噶! 学习网络的一点经验 | 卡瓦邦噶! ARP 问题诊断 | 卡瓦邦噶! 网络断断续续…… | 卡瓦邦噶! Piccolo P2P 镜像分发 | 卡瓦邦噶! 一起看电影 | 卡瓦邦噶! 《征服C指针》 | 卡瓦邦噶! 我的姥姥 | 卡瓦邦噶! Python的哲学 Python 3.5的新特性 学校不教的计算机课 垃圾回收(GC)的三种基本方式 在编程中体验纯粹的快乐 从《美丽新世界》谈自由 在快钱实习 迷人的嗓音和迷人的故事——《Sleepyhead》 Python 的十个自然语言处理工具 记一个愚蠢的bug 一年炉石传说的游戏体验 《以撒的结合:重生》网页版图鉴 分清 C++的指针、引用和数组 笑话三则 自由比皇帝更伟大——《悲惨世界》笔记 Git 10 周年访谈:Linus 讲述背后故事 用 0x3f3f3f3f 设定最大int值的优点 Joel给计算机系学生的建议 一个词法分析器的简单实现 怎样才算健康的生活方式 MacVim 配置攻略 学习培训课程的视频效果好吗? 语言的控制 可悲的大多数 CSS样式思维导图 2014年终总结 奥巴马成为首位写程序的美国总统 青岛老城区的下水道好在哪里? 做优秀 UI 的七个建议(第二部分) 选择爱情的骑士 Git简明教程 Java集合总览 读 《1984》 java问答:终极父类(六)——等待/唤醒和接口 Java 问答:终极父类(五)——toString() Hyperlapse快速视频背后的技术细节 平庸之恶 Java程序员须知的七个日志管理工具 苏州 逛书摊随想 关于考试作弊 你的工作不仅仅是编程 推荐在线学习Java的英文资源 关注女性命运——《千禧年三部曲》 用好你的幻灯片——《演说之禅》 使用ReentrantLock和Lambda表达式让同步更纯净 新手学编程,从哪里开始? 程序员都是工程师吗? 不要学习代码,要学会思考 Java 问答:终极父类(四)——hashCode() Java 问答:终极父类(三)——finalize()和 getClass() 程序员职业之路的选择 我是一名摄影家 写给何小树的城市指南 为什么一些语言会比别的快? Java的常见误区与细节 跟朋友在一起玩游戏 死神永生——读《三体》 五种类型的程序员 创业圣经——读《黑客与画家》 纪念加西亚·马尔克斯 Junit中处理异常的另一种方式:catch-exception Java8采用Martin Fowler的方法创建内部DSL Linux HotSopt虚拟机GC线程的CPU占用率 J2EE概念介绍 如何成为一名黑客 Java 问答:终极父类(二)——equals()方法 为什么我喜欢Java Java 问答:终极父类(一)——clone()方法 七个改变世界的Java项目 java中默认类型转换的小问题 传统与创新 欢迎来到互联网 莫言和马尔克斯——读《生死疲劳》 位运算的妙用 读《人为什么活着》 写博客教会我的事情 中国特色操作系统 2013年总结 《永不妥协》影评 恨不相逢未嫁时——《廊桥遗梦》影评 如何优雅地使用PPT 给明年依然年轻的我们 天才与柱子 黑客守则和黑客精神 Looking for Freedom——《被解救的姜戈》 简洁之道
Linux的用户与管理
laixintao · 2017-12-10 · via 卡瓦邦噶!

很久以来,我对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(计算机认识数字比较容易,而人类认识单词比较容易),我们平时所说的用户名只是便于人类操作和记忆。

Shell

1

2

3

4

5

vagrant@saltmaster:~$ ls -l

total 256

-rw-r--r-- 1 root    root    256191 Nov 13 06:26 bootstrap-salt.sh

-rw-rw-r-- 1 vagrant vagrant      0 Nov 26 08:44 filea

-rw-r--r-- 1 root    root       100 Nov 20 06:30 nettools.sls

对于每个文件,记录的其实是一个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文件中,格式如下:

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

vagrant@saltmaster:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

mail:x:8:8:mail:/var/mail:/usr/sbin/nologin

news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin

proxy:x:13:13:proxy:/bin:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

backup:x:34:34:backup:/var/backups:/usr/sbin/nologin

每一行代表一个账户,通过:来分割信息。数一数会发现一共有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文件的格式如下:

Shell

1

2

3

4

5

6

vagrant@saltmaster:~$ clear

vagrant@saltmaster:~$ sudo head -n 4 /etc/shadow

root:!:17466:0:99999:7:::

daemon:*:17379:0:99999:7:::

bin:*:17379:0:99999:7:::

sys:*:17379:0:99999:7:::

可以看到,这也是用:来分割的,一共有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

Shell

1

2

3

4

5

vagrant@saltmaster:~$ sudo head -n 4 /etc/group

root:x:0:

daemon:x:1:

bin:x:2:

sys:x:3:

一共四个字段:

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

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

Shell

1

2

3

4

5

6

vagrant@saltmaster:~$ sudo head -n 4 /etc/gshadow

root:*::

daemon:*::

bin:*::

sys:*::

systemd-timesync:!::

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

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

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

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

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

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

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

Shell

1

2

3

4

5

6

7

8

vagrant@saltmaster:~$ groups

adm cdrom sudo dip plugdev lxd lpadmin sambashare vagrant

vagrant@saltmaster:~$ touch test_a

vagrant@saltmaster:~$ newgrp sudo

vagrant@saltmaster:~$ touch test_b

vagrant@saltmaster:~$ ll test_*

-rw-rw-r-- 1 vagrant adm  0 Nov 26 15:46 test_a

-rw-rw-r-- 1 vagrant sudo 0 Nov 26 15:47 test_b

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

Shell

1

2

3

4

5

6

7

vagrant@saltmaster:~$ exit

exit

vagrant@saltmaster:~$ touch test_c

vagrant@saltmaster:~$ ll test_*

-rw-rw-r-- 1 vagrant adm  0 Nov 26 15:46 test_a

-rw-rw-r-- 1 vagrant sudo 0 Nov 26 15:47 test_b

-rw-rw-r-- 1 vagrant adm  0 Nov 26 15:48 test_c

二、创建与管理用户

1.useradd

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

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

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

vagrant@saltmaster:/home$ useradd tom

useradd: Permission denied.

useradd: cannot lock /etc/passwd; try again later.

vagrant@saltmaster:/home$ sudo -s

root@saltmaster:/home# useradd tom

root@saltmaster:/home# ls

vagrant

root@saltmaster:/home# grep tom /etc/passwd /etc/shadow /etc/group

/etc/passwd:tom:x:1001:1001::/home/tom:

/etc/shadow:tom:!:17496:0:99999:7:::

/etc/group:tom:x:1001:

root@saltmaster:/home# ls

vagrant

root@saltmaster:/home# su - tom

No directory, logging in with HOME=/

$ pwd

/

$ touch tom_file

touch: cannot touch 'tom_file': Permission denied

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

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

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

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

vagrant@saltmaster:~$ useradd -D

GROUP=100

HOME=/home

INACTIVE=-1

EXPIRE=

SHELL=/bin/sh

SKEL=/etc/skel

CREATE_MAIL_SPOOL=no

vagrant@saltmaster:~$ cat /etc/default/useradd

# Default values for useradd(8)

#

# The SHELL variable specifies the default login shell on your

# system.

# Similar to DHSELL in adduser. However, we use "sh" here because

# useradd is a low level utility and should be as general

# as possible

SHELL=/bin/sh

#

# The default group for users

# 100=users on Debian systems

# Same as USERS_GID in adduser

# This argument is used when the -n flag is specified.

# The default behavior (when -n and -g are not specified) is to create a

# primary user group with the same name as the user being added to the

# system.

# GROUP=100

#

# The default home directory. Same as DHOME for adduser

# HOME=/home

#

# The number of days after a password expires until the account

# is permanently disabled

# INACTIVE=-1

#

# The default expire date

# EXPIRE=

#

# The SKEL variable specifies the directory containing "skeletal" user

# files; in other words, files such as a sample .profile that will be

# copied to the new user's home directory when it is created.

# SKEL=/etc/skel

#

# Defines whether the mail spool should be created while

# creating the account

# CREATE_MAIL_SPOOL=yes

vagrant@saltmaster:~$

2.passwd

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

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

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

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

Shell

1

2

3

4

5

6

7

8

vagrant@saltmaster:~$ chage -l vagrant

Last password change : Oct 27, 2017

Password expires : never

Password inactive : never

Account expires : never

Minimum number of days between password change : 0

Maximum number of days between password change : 99999

Number of days of warning before password expires : 7

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文件支持对用户组授权(以%开头)。格式如下:

Shell

1

2

用户账号     登陆者的来源主机名=可切换的身份    可执行的命令(绝对路径)

root        ALL=(ALL)                     ALL

其中,可以修改最后一列为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的东西还是要扎扎实实学,多少年过去了,这些知识都没怎么变!