Linux 学习笔记(一)- 用户


  一直想学习 Linux,但无奈小白不知道从何入手。经常看群里服务端的同事提到 root 、sudo,那我想着从用户管理入手,先认清楚大小王总是可以的吧,趁工作的空档学习了一些基本知识,大部分描述来自于《Linux从入门到精通》一书。

记录一下尝试过的命令:

root 可以做什么

  这个问题的答案是 anything。没错,作为整个系统中拥有最高权限的用户,root 可以对系统做任何事情。root 可以访问、修改、删除系统中的任何文件和目录。另外,对于如下这些受限的操作,一般只有 root 用户能够执行。

  • 添加删除用户;
  • 安装软件;
  • 添加删除设备;
  • 启动和停止网络服务;
  • 某些系统调用(例如对内核的请求);
  • 关闭系统。

提示:像“关闭系统”这样的操作都需要 root 用户来执行,看起来是一件特别古怪的事情。事实上,作为 Linux 的祖先,UNIX 是一种典型的服务器操作系统。而服务器的关闭和启动都必须得到管理员的授权(试想一个普通用户登录服务器,然后随意执行关机命令会怎样)。出于操作简易性的考虑,桌面版的 Linux 允许普通用户在图形界面下关闭系统。但在命令行下执行关机命令仍然需要 root 口令。Linux 系统上的每个文件和目录都属于某个特定的用户,没有得到许可,其他用户就不能访问这些对象。但 root 用户却可以访问所有用户的文件,就像使用自己的东西一样。

  系统不会因为用户输入的命令足够“愚蠢”而拒绝执行。相反,系统会美滋滋地执行这样一条命令,然后把自己完完整整地删除了,例如江湖传说:rm -rf /*

So… Don’t drink and root. 日常工作、学习都尽量建立自己专属的用户来操作系统,这应该是个好习惯吧,没必要冒没必要的险🤓~

root 口令

仅在必要的时候才使用 root 账号,例如新建普通用户。

su

用户可以执行不带参数的 su 命令将自己提升至 root 权限,需要 root 口令。

sudo

可以临时使用 root 身份运行一个程序,并在程序执行完毕后返回普通用户权限。sudo -s 将自己提升为 root 用户,等同于 suexit 回到先前的用户状态。

用户与用户组

Linux 可以允许多个用户同时登录到系统上,并响应每一个用户的请求。系统管理员的权限:

  • 添加和删除用户
  • 分配用户主目录
  • 限制用户的权限

  Linux 为每一个用户启动一个进程,然后由这个进程接受用户的各种请求。对于用户组权限,组员自动拥有组的权限。多人协作的项目,定义一个组非常有用。
  在某些服务器程序安装时,会生成一些特定的用户和用户组,用于对服务器进行管理。例如,可以使用 mysql 用户启动和停止 MySQL 服务器,还有 nginx 等等。之所以不用 root 用户启动某些服务,主要是出于安全性的考虑。

useradd

添加用户

  • 添加名为 tommy 的用户,并自动建立主目录:
1
useradd -m tommy
  • 更改 tommy 的登录密码:
1
passwd tommy
  • 为某个组新建用户:建立名为 tommy 的账号,并指定其属于 guys 组:
1
useradd -g guys tommy

  在用户建立的时候为其指定一个组看上去是一个很不错的想法。但遗憾的是,这样的设置增加了用户由于不经意间地设置权限而能够彼此读取文件的可能性,尽管这通常不是用户的本意。因此一个好的建议是,在新建用户的时候用户单独创建一个同名的用户组,然后把用户归入这个组。这正是不带 -g 参数的 useradd 命令的默认行为。

  • 建立名为 tommy 的用户,并指定其登录后使用 bash 作为 Shell:
1
useradd -s /bin/bash tommy

参数选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-b, --base-dir BASE_DIR #..........新账户的主目录的基目录
-c, --comment COMMENT #............新账户的 GECOS 字段
-d, --home-dir HOME_DIR #..........新账户的主目录
-D, --defaults #...................显示或更改默认的 useradd 配置
-e, --expiredate EXPIRE_DATE #.....新账户的过期日期
-f, --inactive INACTIVE #..........新账户的密码不活动期
-g, --gid GROUP #..................新账户主组的名称或 ID
-G, --groups GROUPS #..............新账户的附加组列表
-h, --help #.......................显示此帮助信息并推出
-k, --skel SKEL_DIR #..............使用此目录作为骨架目录
-K, --key KEY=VALUE #..............不使用 /etc/login.defs 中的默认值
-l, --no-log-init #................不要将此用户添加到最近登录和登录失败数据库
-m, --create-home #................创建用户的主目录
-M, --no-create-home #.............不创建用户的主目录
-N, --no-user-group #..............不创建同名的组
-o, --non-unique #.................允许使用重复的 UID 创建用户
-p, --password PASSWORD #..........加密后的新账户密码
-r, --system #.....................创建一个系统账户
-R, --root CHROOT_DIR #............chroot 到的目录
-P, --prefix PREFIX_DIR #..........prefix directory where are located the /etc/* files
-s, --shell SHELL #................新账户的登录 shell
-u, --uid UID #....................新账户的用户 ID
-U, --user-group #.................创建与用户同名的组
-Z, --selinux-user SEUSER #........为 SELinux 用户映射使用指定 SEUSE

groupadd

  • 添加一个名为 newgroup 的组。
1
groupadd newgroup

history

Linux,准确地说是 Shell,会记录用户的每一条命令。history 可以查看自己曾经执行的操作。

直接使用 history 会列出当前用户所有使用过的命令并加以编号。存储在用户主目录的 .bash_history 文件中,这个文件默认情况下可以存储1000条命令记录。

  • history 10 列出最近使用的10条命令
1
2
3
4
5
6
7
8
9
10
11
[tommy@VM-0-13-centos ~]$ history 10
26 2022-02-18 12:30:33 ls
27 2022-02-18 12:30:40 cd ../httpbin
28 2022-02-18 12:30:43 ls
29 2022-02-18 12:31:36 cd ~
30 2022-02-18 12:31:37 ls
31 2022-02-18 12:31:40 git -v
32 2022-02-18 12:31:54 git --version
33 2022-02-18 12:32:18 sudo git --version
34 2022-02-21 13:51:28 history
35 2022-02-21 13:51:32 history 10

history 命令仅在 BASH 中适用??这个我还真不太清楚,像 Mac ZSH(Z-Shell)上是类似这样用 - history -10
Linux 的许多操作都是针对文件的,所以也可以直接查看文件达到 history 的效果,eg:

1
2
cat /home/tommy/
sudo cat .bash_history

.bash_history 对于其他受限用户是不可读的,这也正是为什么要使用 sudo 的原因。
FYI:首次使用 sudo 命令会看到下面贴心的提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[tommy@VM-0-13-centos ~]$ sudo cd /etc/

我们信任您已经从系统管理员那里了解了日常注意事项。

总结起来无外乎这三点:

#1) 尊重别人的隐私。

#2) 输入前要先考虑(后果和风险)。

#3) 权力越大,责任越大。

[sudo] tommy 的密码:

tommy 不在 sudoers 文件中。此事将被报告。

/etc/passwd

在 Linux 中所做的一切基本配置最终都将反映到配置文件中,用户管理也不例外。所有的用户信息都登记在 /etc/passwd 文件中,而 /etc/shadow 文件则保存着用户的登录密码。

  • passwd:所有用户可读,root 写;
  • shadow:root 读写。

us

查看 shadow 文件的内容

us 命令可以得到 shadow 文件的内容,限于篇幅,我们举例说明:

1
root:$1$Bg1H/4mz$X89TqH7tpi9dX1B9j5YsF.:14838:0:99999:7:::

其格式为:

{用户名}:{加密后的口令密码}:{口令最后修改时间距原点(1970-1-1)的天数}:{口令最小修改间隔(防止修改口令,如果时限未到,将恢复至旧口令):{口令最大修改间隔}:{口令失效前的警告天数}:{账户不活动天数}:{账号失效天数}:{保留}
【注】:shadow 文件为可读文件,普通用户没有读写权限,超级用户拥有读写权限。如果密码字符串为*,则表示系统用户不能被登入;如果字符串为!,则表示用户名被禁用;如果字符串为空,则表示没有密码。
我们可以使用 passwd –d 用户名 清空一个用户的口令密码。

userdel

删除用户。

  • 删除 tommy 这个用户,但默认情况下,并不会删除用户的主目录:
1
userdel tommy 
  • 删除账号的同时,删除其主目录:
1
userdel -r tommy  
  • 未删除用户主目录,再次添加用户时的提示:
1
2
3
4
5
6
7
[root@VM-0-13-centos ~]$ useradd -m tommy

useradd:警告:此主目录已经存在。

不从 skel 目录里向其中复制任何文件。

正在创建信箱文件: 文件已存在

  在删除用户的同时删除其主目录,以释放硬盘空间,这看起来无可厚非。但是,在输入 -r 选项 之前,仍有一个问题需要问问自己:需要这么着急吗?如果被删除的用户又要恢复,或者用户的某些文件还需要使用(这样的情况在服务器上经常出现),那么有必要暂时保留这些文件。比较妥当的方法是,将被删除的的用户主目录保留几周,然后再手动删除。在实际的工作环境中,这个做法显得尤为重要。

usermod

管理用户账号。

常用选项:

1
2
3
4
5
-d	# 修改用户主目录
-e # 修改账号的有效期限。以公元月/日/年的形式表示(MM/DD/YY)
-g # 修改用户所属的组
-l # 修改用户账号名称
-s # 修改用户登录后所使用的的 Shell
  • 把 john 改为 mike,有效期是 12/31/22 :
1
usermod -l mike -d /home/mike -e 12/31/22 john
  • 修改正在登录的用户,提示:
1
usermod: user tommy is currently used by process 28693

参数选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-c, --comment #....................注释 GECOS 字段的新值
-d, --home HOME_DIR #..............用户的新主目录
-e, --expiredate EXPIRE_DATE #.....设定帐户过期的日期为 EXPIRE_DATE
-f, --inactive INACTIVE #..........过期 INACTIVE 天数后,设定密码为失效状态
-g, --gid GROUP #..................强制使用 GROUP 为新主组
-G, --groups GROUPS #..............新的附加组列表 GROUPS
-a, --append GROUP #...............将用户追加至上边 -G 中提到的附加组中,并不从其它组中删除此用户
-h, --help #.......................显示此帮助信息并推出
-l, --login LOGIN #................新的登录名称
-L, --lock #.......................锁定用户帐号
-m, --move-home #..................将主目录内容移至新位置 (仅于 -d 一起使用)
-o, --non-unique #.................允许使用重复的(非唯一的) UID
-p, --password PASSWORD #..........将加密过的密码 (PASSWORD) 设为新密码
-R, --root CHROOT_DIR #............chroot 到的目录
-P, --prefix PREFIX_DIR #..........prefix directory where are located the /etc/* files
-s, --shell SHELL #................该用户帐号的新登录 shell
-u, --uid UID #....................用户帐号的新 UID
-U, --unlock #.....................解锁用户帐号
-v, --add-subuids FIRST-LAST #.....add range of subordinate uids
-V, --del-subuids FIRST-LAST #.....remove range of subordinate uids
-w, --add-subgids FIRST-LAST #.....add range of subordinate gids
-W, --del-subgids FIRST-LAST #.....remove range of subordinate gids
-Z, --selinux-user SEUSER #.......用户账户的新 SELinux 用户映射

有一个 -m 备注了仅与 -d 一起使用,把 john 原来的主目录文件移动到新的位置:

1
usermod -l tommy -d /home/tommy -m john

id

查看用户的 UID、GID 及其所属的组。

id 不带参数显示当前登录用户的信息:

1
uid=0(root) gid=0(root) 组=0(root)

id nginx 查看 nginx 的信息:

1
uid=993(nginx) gid=991(nginx) 组=991(nginx)

su

用户间切换。

  • 不带任何参数的 su 命令将用户提升至 root 权限,需要 root 口令。通过 su 获取的特权将一直持续到使用 exit 命令退出为止。
1
su
  • 切换到 tommy 用户,需要 tommy 的口令。
1
su tommy

提示:尽量通过绝对路径使用 su 命令,这个命令通常保存在 /bin 目录下。这将一定程度上防止溜入到搜索路径下的名为 su 的程序窃取用户口令。

sudo

受限的特权。

  sudo 是一个程序。接受命令行作为参数,并以 root 身份(或者也可以是其他用户)执行它。在执行命令之前,sudo 会首先要求用户输入自己的口令,口令只需要输入一次。出于安全性的考虑,如果用户在一段时间内(默认是5分钟)没有再次使用 sudo,那么此后必须再次输入口令。这样的设置避免了特权用户不经意间将自己的终端留给了哪些并不受欢迎的人。
通过配置 /etc/sudoers 指定用户可以执行的特权命令:

  • 指定 root 用户可以使用 sudo 在任何机器上(第一个 ALL)以任何用户身份(第二个 ALL)执行任何命令(第三个 ALL):
1
2
Allow root to run any commands anywhere
root ALL=(ALL) ALL

sudoer 中的每一行权限说明包含了下面这些内容:

  • 该权限适用的用户;
  • 这一行配置在哪些主机上适用? (这个我不是太懂…)
  • 该用户可以运行的命令;
  • 该命令应该以哪个用户身份执行。

提示:sudoers 中的命令应该使用绝对路径来指定,这样可以防止一些人以 root 身份执行自己的脚本程序。
修改sudoers文件应该使用 visudo 命令。这个命令依次执行下面这些操作:

  • 检查以确保没有其他人正在编辑这个文件。
  • 调用一个编辑器编辑该文件。
  • 验证并确保编辑后的文件没有语法错误。
  • 安装使 sudoers 文件生效。