管理员/虚拟用户/普通用户UID范围

Root用户UID = 0

虚拟用户UID范围: (CentOS7)1 ~ 999; (CentOS6) 1 ~ 499。

普通用户UID范围 >= 1000。

虚拟用户是没办法使用shell prompt的,原因如下(以CentOS7为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ awk '/nologin/{print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
dovecot:x:97:97:Dovecot IMAP server:/usr/libexec/dovecot:/sbin/nologin
dovenull:x:998:996:Dovecot's unauthorized user:/usr/libexec/dovecot:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

passwd文件中最后一个冒号(:)后接的shell prompt,很明显这些用户是无法使用shell登录的。

用户管理

用户创建

1
useradd 用户名

When we run ‘useradd’ command in Linux terminal, it performs following major things:

  1. It edits /etc/passwd, /etc/shadow, /etc/group and /etc/gshadow files for the newly created User account.
  2. Creates and populate a home directory for the new user.
  3. Sets permissions and ownerships to home directory.

-The Complete Guide to “useradd” Command in Linux - 15 Practical Examples

创建虚拟用户的方法

-M - 不创建家目录

-s - 指定使用的shell的路径

1
useradd violet -M -s /sbin/nologin

创建的虚拟用户UID数值是大于等于1000。

-u - 指定创建的用户的UID

-g - 指定创建的用户的主组

-G - 指定创建的用户的次要组(附加组)

-c - 指定创建的用户的用户注释说明信息

1
2
3
# useradd violet06 -u 1009
# id violet06
uid=1009(violet06) gid=1009(violet06) groups=1009(violet06)
1
2
# useradd violet06 -u 1009 -g violet05
uid=1009(violet06) gid=1006(violet05) groups=1006(violet05)
1
2
3
# useradd violet06 -u 1009 -G violet05
# id violet06
uid=1009(violet06) gid=1009(violet06) groups=1009(violet06),1006(violet05)
1
2
3
# useradd violet06 -c "manage db"
# grep 'violet06' /etc/passwd
violet06:x:1009:1009:manage db:/home/violet06:/bin/bash

-p 指定创建的用户的密码(这个密码应该是加密后的密码)

对useradd -p的解释_weixin_34174132的博客-CSDN博客
https://blog.csdn.net/weixin_34174132/article/details/91539386

1
2
# grep 'violet' /etc/shadow
violet:$6$QNUo3m1i$bL3EAkJn8sUXEE581lVxZ9/fbgcKyFkQQ/5edq7JtUdYO.00qen5QxtiHFFO4LbDpGy0hux4giBfg6Fr1K2Z./:18632:0:99999:7:::

比如"123456"密码的加密后的密码是第一个冒号和第二个冒号之间的字符串

1
$6$QNUo3m1i$bL3EAkJn8sUXEE581lVxZ9/fbgcKyFkQQ/5edq7JtUdYO.00qen5QxtiHFFO4LbDpGy0hux4giBfg6Fr1K2Z./

那么useradd -p应该这样使用

1
# useradd violet06 -p '$6$QNUo3m1i$bL3EAkJn8sUXEE581lVxZ9/fbgcKyFkQQ/5edq7JtUdYO.00qen5QxtiHFFO4LbDpGy0hux4giBfg6Fr1K2Z./'

接下来就可以输入用户名violet06,密码为123456。由此这个’-p’参数设置密码麻烦,不推荐使用,还是使用passwd命令比较好。

用户删除

1
userdel USER

注意:如果被删除的用户的用户主组还加入了其他用户,那么这个主组是无法删除的。举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# useradd violet02
useradd: user 'violet02' already exists
# id violet02
uid=1003(violet02) gid=1003(violet02) groups=1003(violet02)
# id violet03
uid=1004(violet03) gid=1004(violet03) groups=1004(violet03)
# usermod -G violet02 violet03
# id violet03
uid=1004(violet03) gid=1004(violet03) groups=1004(violet03),1003(violet02)
# userdel violet02
userdel: group violet02 not removed because it has other members.
# id violet02
id: violet02: no such user
# ll -d /home/violet02
drwx------ 2 1003 violet02 62 Jan 15 20:48 /home/violet02

可以从例子中看到,可以删除该用户,但该用户的主组无法删除。

上面例子中,用户的家目录未被删除。

接着上个例子创建被删除的用户

1
2
3
4
5
6
7
8
# useradd violet02
useradd: group violet02 exists - if you want to add this user to that group, use -g.
# useradd violet02 -g violet02
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
Creating mailbox file: File exists
# id violet02
uid=1008(violet02) gid=1003(violet02) groups=1003(violet02)

可见如果想要再次创建被删除的用户,需要在使用useradd命令时指定主组。

在删除用户时,最好指定’-r’删除:

-r - 删除用户信息的同时,删除家目录和邮件目录(mail spool)。

在使用该选项前,请注意为备份家目录和邮件目录建立必要的备份。

用户切换

普通用户切换用户:

1
2
3
su - 用户名	# 切换到某个用户
su - root
# 然后输入密码

退出切换的用户:

1
exit

# - 表示管理员身份

$ - 表示普通用户身份

登录用户检测

whoami - 该命令可以用于打印当前登录的用户是谁

比如,

1
2
# whoami
root

who - 该命令用于检查所有登录的用户,并将其打印出来

打印格式为: [用户名称] [终端] [登录时间]

注意[终端]的格式有两种:

  1. ttyn。比如tty1, tty2, …
  2. pts/n。比如pts/0, pts/1, …

tty和pts的区别可以参考linux - Difference between pts and tty - Unix & Linux Stack Exchange
tty: native terminal device(本地终端设备)。比如,你就在服务器上登录了系统,没有利用任何远程方式,从物理上,服务器和你是"无距离"的。

pts: pseudo terminal slave(伪终端从设备)。比如利用ssh或xterm连接的终端。你可以理解你利用XShell远程登录你的Linux

,那么在这整个XShell就是一个伪终端从设备。"伪"体现在你可以远程操作Linux,就仿佛你在服务器身边真正操作它一样。

比如

1
2
3
4
# who
root tty1 2021-01-21 14:38
root pts/1 2021-01-21 14:10 (192.168.10.1)
root pts/2 2021-01-21 14:13 (192.168.10.1)

用户信息修改

  • usermod命令

-s - 修改用户的登录方式
-g - 修改用户的主要的组信息
-G - 修改用户的附属组信息
-c - 修改用户的注释信息

用户信息查看

  • id命令

用于显示用户信息。用户打印有效用户的UID, GID和组,对于不存在的用户,该命令会提示形如"id 查询的用户名: no such user"的错误信息

应用 - 查询用户UID,GID,GROUPS

1
$ id violet

应用 - 检查用户是否存在

1
2
$ id violet100
id: violet100: no such user
  • w命令
1
2
3
4
5
6
7
$ w
17:02:27 up 3 days, 14:44, 4 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 Thu14 26:24m 0.02s 0.02s -bash
violet pts/0 192.168.10.1 16:40 12:35 0.05s 0.05s -bash
root pts/4 192.168.10.1 15:00 3.00s 0.03s 0.00s w
root pts/5 192.168.10.1 15:00 13:55 0.30s 0.30s -bash
列明 简明描述 描述
USER 用户名称 用于显示使用当前终端的用户名称
TTY 终端 用于显示登陆终端的类型(tty/pts)
FROM 登录IP 用户登录到哪个IP地址
LOGIN@ 登录时间 用户登录的时间
IDLE 空闲时间 用户上次使用终端进行操作的时间
JCPU 所有进程使用时长 与用户登录的终端相关的所有进程的使用时长
PCPU 当前进程使用时长 用户当前使用的进程(该进程信息在WHAT列有显示)的使用时长
WHAT 当前进程信息 用户当前使用的进程和相关选项或参数。
  • last命令

用于显示用户上次登录信息

1
2
3
4
5
6
7
8
9
# last
violet pts/0 192.168.10.1 Fri Jan 22 16:40 still logged in
root pts/5 192.168.10.1 Fri Jan 22 15:00 still logged in
root pts/4 192.168.10.1 Fri Jan 22 15:00 still logged in
...
root tty1 Fri Dec 25 14:55 - 15:22 (00:27)
reboot system boot 3.10.0-862.el7.x Fri Dec 25 14:43 - 15:22 (00:39)

wtmp begins Fri Dec 25 14:43:01 2020
  • lastlog命令

用于显示所有用户最近登录的信息

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
# lastlog
Username Port From Latest
root pts/5 192.168.10.1 Fri Jan 22 15:00:18 +0800 2021
bin **Never logged in**
daemon **Never logged in**
adm **Never logged in**
lp **Never logged in**
sync **Never logged in**
shutdown **Never logged in**
halt **Never logged in**
mail **Never logged in**
operator **Never logged in**
games **Never logged in**
ftp **Never logged in**
nobody pts/1 Sun Jan 10 19:51:06 +0800 2021
systemd-network **Never logged in**
dbus **Never logged in**
polkitd **Never logged in**
tss **Never logged in**
abrt **Never logged in**
sshd **Never logged in**
postfix **Never logged in**
violet pts/0 192.168.10.1 Fri Jan 22 16:40:32 +0800 2021
orchid **Never logged in**
dovecot **Never logged in**
dovenull **Never logged in**
ntp **Never logged in**
violet01 pts/1 Fri Jan 15 20:48:15 +0800 2021
violet03 **Never logged in**
violet04 **Never logged in**
violet05 **Never logged in**
flower **Never logged in**
violet02 **Never logged in**
violet06 pts/0 Fri Jan 22 16:49:50 +0800 2021

密码设置

用户设置密码

1
2
passwd 用户名	# 修改指定用户的密码
psswd # 修改当前用户的密码
  • passwd命令

交互式设置密码的方法:

1
passwd USER

为violet用户设置密码,密码需要输入两次

1
passwd violet

非交互式设置密码的方法:(不安全,因为通过history命令可查看到明文)

1
echo PASSWORD | passwd --stdin USER

比如为violet用户设置密码为123456:

1
echo 123456 | passwd --stdin violet

用户组管理

主组和次要组的区别

这个问题可以参考Linux Users and Groups | Linode。下面给出我参考的理解:

由于一个用户可以有多个组,肯定有一个组为主组(Primary Group),其他为次要组(Secondary Groups)。

  • 主组

通过"man usermod"查看命令使用手册时,主组的英文名为Initial login group,大部分老外也会称主组为Primary group。

先看看主组。主组就是默认组,对每一个新创建的用户来说,如果你不使用’-G’或’-g’指定用户归属哪个组,该用户会归属于与用户名称同名的组,而这个组就是默认组。如何查看一个用户的主组呢?

1
2
$ id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),1007(flower)

"gid=1000(violet)"表示该用户的主组id值为1000,主组的名称为violet。

  • 次要组(附加组)

次要组的英文名称为Supplementary groups或Secondary groups。

1
2
$ id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),1007(flower)

"groups=1000(violet),1007(flower)"中"groups"表示这个用户(violet)所属的组有哪一些。可以看到该用户属于两个组,一个violet组,一个flower组,通过"gid=1000(violet)"确定主组为violet,那么flower则为次要组。

  • 那么一个用户的默认组有什么用呢?
  1. 当用户登录Linux时,都会有一个与之关联的用户组,这个组就是默认组。
  2. 除此之外,如果用户创建文件或目录,那么这个文件或目录都会关联上所属人(owner)和与用户主组的信息,比如
1
2
3
4
5
# ll -d /root
dr-xr-x---. 4 root root 4096 Jan 21 15:00 /root
# mkdir /root/test
# ll -d /root/test
drwxr-xr-x 2 root root 6 Jan 21 15:30 /root/test

root目录和root目录下的test目录的所属人就是root用户,并且其默认组为root组。

  1. 而且,通过id命令也可以看到主组的信息:
1
2
# id root
uid=0(root) gid=0(root) groups=0(root)

"gid=0(root)"可以看出主组为root

再用id命令举个例子

1
2
$ id violet
uid=1000(violet) gid=1007(flower) groups=1007(flower),20(games),1000(violet)

在这个例子中,"gid=1007(flower)"可得知violet用户的主组是flower,它的次要组有games, violet,它所属的组有flower, games, vioelt。

用户加入一个组

Reference: Usermod Command in Linux | Linuxize.

-a -G - 为用户增添一个组。添加成功后可以在/etc/group中查看组内用户的信息。

语法格式如下

1
2
# GROUP:当group有多个时,应该有逗号进行分割,而不是空格。
$ usermod -a -G GROUP USER

violet用户加入games组的实例如下

1
2
3
4
5
6
7
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)
# usermod -a -G games violet
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),20(games)
# awk '$1 ~ /games/{print}' /etc/group
games:x:20:violet

games:x:20:violet表示games组中gid=20,该组中用户有violet。

用户退出一个组

-d - 在用户组中删除指定用户

语法格式如下

1
gpasswd -d USER GROUP

用户退出一个组的正确步骤:

  1. 利用id检查退出的组是否为主组,若退出的组为主组,需要先修改主组为次要组,否则进行下一步
  2. 使用"gpasswd -d USER GROUP"退出组。

violet用户退出games组(其中games为主组)的实例

1
2
3
4
5
6
7
8
9
# id violet
uid=1000(violet) gid=20(games) groups=20(games),1000(violet)
# usermod -g violet violet
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),20(games)
# gpasswd -d violet games
Removing user violet from group games
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)

特别注意: 用户无法删除从主组中退出,若要删除主组,需要先将主组降为次要组后,再使用gpasswd退出组,否则就会出现错误提示。虽然/etc/group显示用户退出了主组,实际上用户violet创建文件所属的组扔为原来的主组。例子如下

1
2
3
4
5
6
7
8
9
10
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)
# usermod -g games violet
# id violet
uid=1000(violet) gid=20(games) groups=20(games),1000(violet)
# gpasswd -d violet games
Removing user violet from group games
gpasswd: user 'violet' is not a member of 'games'
# awk -F: '$1 ~ /games$/{print}' /etc/group
games:x:20:

看到/etc/group中violet的组信息并不是games:x:20:violet,可见violet已经退出了主组。但是在violet用户的Shell prompt上创建文件时,文件所属的组还是原来的games主组:

1
2
3
4
5
[violet ~]$ touch test.txt
[violet ~]$ ll
total 4
...
-rw-rw-r-- 1 violet games 0 Jan 21 16:05 test.txt

正确的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost ~]# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)
[root@localhost ~]# usermod -a -G games violet
[root@localhost ~]# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),20(games)
[root@localhost ~]# usermod -g games violet
[root@localhost ~]# id violet
uid=1000(violet) gid=20(games) groups=20(games),1000(violet)
[root@localhost ~]# usermod -g violet violet
[root@localhost ~]# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),20(games)
[root@localhost ~]# awk '$1 ~ /games/{print}' /etc/group
games:x:20:violet
[root@localhost ~]# gpasswd -d violet games
Removing user violet from group games
[root@localhost ~]# awk '$1 ~ /games/{print}' /etc/group
games:x:20:
[root@localhost ~]# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)

修改用户的主组

修改主组

-g - 强制改变用户的主组

语法格式如下

1
$ usermod -g GROUP USER

由于该命名是强制改变用户的主组,因此改变用户的主组,先确定用户是否加入了指定的组。

举例,若要修改violet用户的主组为flower组,但是violet用户并没加入flower组,先让violet用户加入flower组:

1
2
3
4
5
6
7
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet)
# usermod -a -G flower violet
# id violet
uid=1000(violet) gid=1000(violet) groups=1000(violet),1007(flower)
# usermod -g flower violet
uid=1000(violet) gid=1007(flower) groups=1007(flower),20(games),1000(violet)

可以看到若violet用户所属的组中并没有flower的话,添加了主组为flower后,其所属的组也多了个flower。

添加用户备注信息

-c - 添加用户备注信息,这个备注是关于GECOS (the full name of the user)的信息,备注信息会添加到/etc/passwd

1
$ usermod -c "GECOS Comment" USER

-d - 改变用户的家目录,原来家目录的内容不会移动到新的家目录

-m - 配合’-d’使用,改变家目录的同时,原家目录内容也会迁移到新的家目录。

1
2
3
4
# By default, the command doesn’t move the content of the user’s home directory to the new one.
$ usermod -d HOME_DIR USER
# To move the content, use the -m option. If the new directory does not already exist, it is created:
$ usermod -d HOME_DIR -m USER

-s - 改变用户默认的shell

The default shell is the shell that is run after you log in to the system. By default, on most Linux systems, the default shell is set to Bash Shell.

You can find out what shells are available on your system by displaying the /etc/shells file’s content.

1
2
# SHELL:其他shell的绝对路径
$ usermod -s SHELL USER

-u - 改变用户UID

1
$ usrmod -u UID USER

-l - 改变用户名称

1
2
3
4
# NEW_USER: 新用户名称
$ usermod -l NEW_USER USER
# In the example below, we are renaming the user linuxize to lisa to “1050”:
sudo usermod -l linuxize lisa

-e - 改变用户到期时间,当当前时间到了到期时间时,用户会被关闭。

到期时间存储在/etc/shadow

1
2
3
4
5
$ usermod -e DATE USER
# For example, to disable the user linuxize on 2022-02-21, you would run the following command:
sudo usermod -e "2022-02-21" linuxize
# To disable the expiration of an account, set an empty expiry date:
sudo usermod -e "" linuxize

查询用户到期时间

1
$ chage -l USER

-L - 锁定用户。

The commands will insert an exclamation point (!) mark in front of the encrypted password. When the password field in the /etc/shadow file contains an exclamation point, the user will not be able to login to the system using password authentication. Other login methods, like key-based authentication or switching to the user are still allowed. If you want to lock the account and disable all login methods, you also need to set the expiration date to 1.

1
2
3
4
$ usermod -L USER
# Examples:
$ sudo usermod -L linuxize
$ sudo usermod -L -e 1 linuxize

-U - 解锁用户

1
$ usermod -U USER

用户授权

背景:普通用户在运行命令时,可能会出现"Permission denied"的情况,这时候需要申请root授权。

普通用户获得权限的方式

  • su切换root用户
  • 让root用户通过chmod修改要目标文件或目录的权限
  • sudo
  • 设置特殊权限位

su - root和su root的区别?

"su - root"是切换到root账号使用,使用的是root用户的环境变量;

"su root"则是取得root的特权,以root的身份执行程序,但保留原来用户环境。

说明:有些命令即使你使用"su root"切换到root用户,仍无法执行,所以切换到root用户时,建议使用"su - root"。

与普通用户violet有关的环境变量,例子如下:

env命令用于显示系统中已存在的环境变量,以及在定义的环境中执行指令。

1
2
3
4
5
6
7
[violet@localhost ~]$ env | grep 'violet'
USER=violet
MAIL=/var/spool/mail/violet
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/violet/.local/bin:/home/violet/bin
PWD=/home/violet
HOME=/home/violet
LOGNAME=violet

取得root权限时:

1
2
3
4
5
6
7
8
9
10
[violet@localhost ~]$ su root
Password:
[root@localhost /home/violet]# env | grep 'violet'
USER=violet
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/violet/.local/bin:/home/violet/bin
MAIL=/var/spool/mail/violet
PWD=/home/violet
LOGNAME=violet
[root@localhost /home/violet]# env | grep 'root'
HOME=/root

切换到root用户时:

1
2
3
4
5
6
7
8
9
10
11
[violet@localhost ~]$ su - root
Password:
Last login: Fri Jan 22 19:44:51 CST 2021 on pts/0
[root@localhost ~]# env | grep 'violet'
[root@localhost ~]# env | grep 'root'
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root

可以看到"su - root"切换到root用户后,PATH路径下有一个/root/bin

sudo配置

1
2
sudo -l	# 查看当前用户的特权信息
sudo -k # 查看当前用户的密码缓存

sudo配置文件编辑

visudo - 相等于"vi /etc/sudoers"。但是使用visudo有一个语法检查的功能。

1
visudo -c	# 提示编辑的文件是否符合语法规则

在root用户下输入visudo

1
# visudo

进入vim跳转到93行(键盘按下"93GG"即可跳转)

授权用户权限的格式如下:

1
[用户名]    [网络中的主机]=[执行命令的目标用户]    [执行的命令范围]
  • 授予用户指定命令的执行权限
1
violet   ALL=(ALL)       /bin/ls, /bin/touch

上述例子授予violet用户ls和touch命令root权限。

这样violet普通用户可以通过sudo ls命令查看处于权限限制下目录的文件列表,例子如下

1
2
3
4
5
[violet@localhost ~]$ ls /root
ls: cannot open directory /root: Permission denied
[violet@localhost ~]$ sudo ls /root
[sudo] password for violet:
anaconda-ks.cfg awk_test.txt info.txt test test.txt violet ...
  • 授予大量命令,并排除指定命令
1
violet   ALL=(ALL)       /bin/*, ! /bin/vi

或者

1
violet   ALL=(ALL)       /usr/bin/*, /usr/sbin/*, !/bin/vi, !/usr/sbin/visudo

批量授予给普通用户大量命令时,切记不能让普通用户拥有修改sudo配置文件的权利!

  • 授予用户使用命令不需要密码
1
violet   ALL=(ALL)       NOPASSWD: ALL

ALL表示violet用户可以执行所有需要root权限的命令时,都不需要密码,这样的做法很危险。

1
violet   ALL=(ALL)       NOPASSWD:  /usr/bin/*, /usr/sbin/*, !/bin/vi, !/usr/sbin/visudo

violet用户可以执行上述"bin和sbin"目录的文件时,都不需要密码.