Linux学习_09-Linux的用户管理

账号和用户组

系统管理员的主要工作就是管理账号。我们先来了解一下linux系统是如何识别每个用户的。

用户标识符:UID和GID

linux的用户至少有2个ID,也就是UID用户ID和GID用户组ID。虽然登录的时候输入的是用户名,但其实系统识别的是这个两个ID。

使用id命令,可以查看用户的这两个id

[root@node4 ~]# id root
uid=0(root) gid=0(root)=0(root)
[root@node4 ~]# id nginx
uid=1000(nginx) gid=1001(nginx)=1001(nginx)

通过这两个ID,Linux系统就把用户和群组和文件联系了起来,总而实现了权限管理。

用户账号

当我们登录Linux系统时,系统大概做了如下事情:

  1. 首先查找/etc/passwd里是否有输入的账号,如果有的话获取UID和GID
  2. 从/etc/shadow文件中核对密码
  3. 如果以上ok,进入shell界面

接下来分别介绍passwd和shadow这两个文件

  • /etc/passwd

    每一行代表一个账号。其中比较靠前的是系统自带的账号。

    [root@node4 ~]# head -n 4 /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    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
    

    每一行的结构如下:

    1. 账号名称:例如root
    2. 密码:现在是x,早期的UNIX系统,密码就存在这里。现在已废弃。
    3. UID和GID:比如第一行就是0:0。系统账号的范围是1-999,用户账号范围是1000-60000
    4. 用户信息说明字段
    5. 用户家目录
    6. shell:用户登录后提供的默认shell
  • /etc/shadow

    [root@node4 ~]# head -n 4 /etc/shadow
    root:$6$Rj7coYh/STyMcxjn$ZY.l1SDPcsJv1NUwiA.INYB7Q/bTxAXHFyRTm42M/qxdPWAt9Ly3eQSpu1Xn5v9LkxLJITwb6igAUPMOD.mBj/::0:99999:7:::
    bin:*:18353:0:99999:7:::
    daemon:*:18353:0:99999:7:::
    adm:*:18353:0:99999:7:::
    

    shadow文件的每一行的结构如下:

    1. 账号名称
    2. 密码:此处存储的是真正的密码
    3. 最近修改密码的日期:为空的话,说明密码没修改过
    4. 密码不可被修改的天数:如果是0,表示密码随时可以修改
    5. 密码需要修改的天数:就是密码有效期,99999基本就是无需修改
    6. 密码需要修改前的警告天数:默认是7
    7. 密码过期后的密码失效天数
    8. 账号失效日期
    9. 保留字段

用户组

组相关的信息存放在/etc/group和/etc/gshadow中,我们继续来了解一下

  • /etc/group

    [root@node4 ~]# head -n 4 /etc/group
    root:x:0:
    bin:x:1:
    daemon:x:2:
    sys:x:3:
    

    每一行代表一个用户组,结构是组名、组密码、GID、用户组中的账号名称

  • 有效用户组(effective group和初始用户组(initial group

    passwd里存储的GID就是用户的初始用户组,也就是说,用户登录系统默认拥有这个用户组的权限。

    如果一个用户属于多个群组,他将拥有这些群组的所有权限。

    但如果用户新建一个文件,该文件的默认用户组,取决于用户的有效用户组。

    用groups命令可以查看用户有效群组

    [root@node4 ~]# usermod -a -G users nginx
    [root@node4 ~]# groups nginx
    nginx : nginx users
    

    我们通过如下命令,新建一个用户,指定群组并允许登录

    [root@node4 ~]# groupadd testgroup
    [root@node4 ~]# useradd -g testgroup testuser -s /bin/bash
    [root@node4 ~]# usermod -a -G users testuser
    [root@node4 ~]# passwd testuser
    

    用testuser登录后,新键一个文件,可以发现文件权限是属于有效群组的

    [testuser@node4 ~]$ groups
    testgroup users
    [testuser@node4 ~]$ touch testfile
    [testuser@node4 ~]$ ll testfile
    -rw-r--r-- 1 testuser testgroup 0 422 21:42 testfile
    
  • newgrp:有效用户组的切换

    可以使用newgrp命令切换有效群组为已经拥有的群组,例如

    [testuser@node4 ~]$ newgrp users
    [testuser@node4 ~]$ groups
    users testgroup
    

    这时候你会发现向上的命令无法使用历史命令了,这是因为newgrp事实上是通过新开了一个shell的方式来实现切换有效用户组的,可以通过exit退出。退出后就又变成之前的用户组了。

    [testuser@node4 ~]$ exit
    exit
    [testuser@node4 ~]$ groups
    testgroup users
    
  • /etc/gshadow

    [root@node4 ~]# head -n 4 /etc/gshadow
    root:::
    bin:::
    daemon:::
    sys:::
    

    组名:密码:用户组管理员账号:用户组中用户账号(和etc/group相同

    gshadow最大的功能就是建立用户组管理员。该管理员有权将用户加入到自己的组中。

账号管理

新增用户useradd

使用useradd命令来添加一个用户

useradd [-u UID] [-g 初始用户组] [-G 次要用户组] [-mM] \
> [-c 说明栏] [-d 家目录] [-s shell] 账号名称
参数说明:
-u 指定UID -g 初始用户组
-M 不创建家目录,系统账号默认此参数
-m 创建家目录,普通账号默认此参数
-c 对应passwd第五列,账号说明
-d 指定家目录,必须使用绝对路径
-r 建立一个系统账号
-s shell 默认指定/bin/shell

例如:

[root@node4 ~]# useradd -g testgroup testuser -s /bin/bash

userad命令建立用户的默认值,可以使用-D查看

[root@node4 ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

删除用户userdel

使用如下命令就可以删除用户

userdel username
-r 删除的同时删除家目录

默认情况下,如果用户所属的组没有其他用户了,就会一并删除用户组。

这取决于/etc/login.defs的USERGROUPS_ENAB 参数

设置密码passwd

默认创建的用户是无法登录的,需要用passwd设置密码

passwd 账号名称
参数:
-l 锁定用户
-u 解锁用户
--stdin 管道数据作为密码输入
-S 显示密码大部分信息

注意,如果passwd后什么都不加,表示修改当前用户密码。

使用stdin的一个例子:

# stdin不是所有Linux版本都支持,请使用man passwd确认
echo "abc@1234" | passwd --stdin usera

好处是不用多次输入密码确认了,缺点是该命令会保留在历史命令中,密码很容易泄露。所以stdin一般用在脚本批量创建多个用户时。

锁定登录和解锁,事实上是通过在/etc/shadow里给密码加上!!来实现的

[root@node4 ~]# passwd -l testuser
锁定用户 testuser 的密码 。
passwd: 操作成功
[root@node4 ~]# passwd -S testuser
testuser LK 2024-04-22 0 99999 7 -1 (密码已被锁定。)
[root@node4 ~]# grep testuser /etc/shadow
testuser:!!$6$oJh4Uczu$dwkoctc/RXPZI2nL3YyxSMJCzel1VPTjarVkP/P53tFhKS7coIbJXAC9rhdxKyytmmvPkEGvjqmSHY9p/4kVF0:19835:0:99999:7:::
[root@node4 ~]# passwd -u testuser
解锁用户 testuser 的密码。
passwd: 操作成功
[root@node4 ~]# grep testuser /etc/shadow
testuser:$6$oJh4Uczu$dwkoctc/RXPZI2nL3YyxSMJCzel1VPTjarVkP/P53tFhKS7coIbJXAC9rhdxKyytmmvPkEGvjqmSHY9p/4kVF0:19835:0:99999:7:::

如果希望用户第一次登录时修改密码,需要通过change命令

user add agetest
echo "123456" | passwd --stdin agetest
change -d 0 agetest

查看用户密码过期情况

chage -l username

用户修改usermod

usermod -参数 username
-c 账户说明
-d 修改家目录
-e 过期日期
-f 密码过期时间,0立即失效 -1 永不失效
-g 初始用户组
-G 次要用户组
-l 修改用户名称
-s shell文件
-u UID
-L 锁定
-U 解锁

用户功能

上面的添加删除用户,都是root用户才有的功能,那么普通用户有哪些功能呢

  • id 查看用户信息,也可以确定某用户是否存在

    [testuser@node4 ~]$ id
    uid=1002(testuser) gid=1003(testgroup)=1003(testgroup),100(users)
    
  • finger 也可以列出用户信息,但可能包含机密信息,所以该命令默认已经不安装。可以使用yum安装

    [root@node4 ~]# finger
    Login     Name       Tty      Idle  Login Time   Office     Office Phone   Host
    root      root       pts/0          Apr 25 19:54                           (192.168.32.1)
    testuser  hanayo     pts/1          Apr 25 20:49 shanghai   456123         (192.168.32.1)
    
    
  • chfn 修改用户信息

    [testuser@node4 ~]$ chfn
    Changing finger information for testuser.
    名称 []: hanayo katyotin^H^H
    chfn: control characters are not allowed
    名称 []: hanayo
    办公 []: shanghai
    办公电话 []: 456123
    住宅电话 []: 182222
    
    密码:
    Finger information changed.
    
    
  • chsh 也就是change shell

    [root@node4 ~]# chsh -l
    /bin/sh
    /bin/bash
    /usr/bin/sh
    /usr/bin/bash
    

用户组修改

用户组的修改其实和用户比较类似

  • groupadd 添加用户组

    groupadd -g gid groupname
    -g 指定GID
    -r 建立系统用户组
    
  • groupmod 修改用户组

    groupmod -g gid -n group_name groupname
    -g 修改GID
    -n 修改组名
    
  • groupdel 删除用户组。如果当前组有用户,删除会报错

    groupdel groupname
    
  • gpasswd:用户组管理员

    gpasswd groupname
    gpasswd -A user1 -M user3 groupname
    group -rR groupname
    -A 将改组管理权授权给user1
    -M 将用户加入该组
    -r 删除groupname的密码
    -R 让groupname的密码失效
    gpasswd -ad user groupname
    -a 用户加入组
    -d 用户从组删除
    

ACL权限设置

仅仅依靠owner,group,others搭配r,w,x来进行权限管理是不够的。Linux还有一种详细的权限管理,也就是ACL Access Control List

用以下命令可以确认当前系统是否支持acl:

[root@node4 ~]# dmesg | grep -i acl
[    1.215136] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
[    3.483737] SGI XFS with ACLs, security attributes, no debug enabled

ACL权限设置getfacl和setfacl

  • setfacl 设置详细权限

    setfacl -bkRd [{-m|-x} acl参数] 目标文件名
    -m 设置后续的acl参数
    -x 删除后续acl参数
    -b 删除所有acl参数
    -k 删除默认acl参数
    -R 递归设置
    -d 设置默认acl参数,对目录设置时使用
    

    以下是一个实例

    [root@node4 ~]# touch acl_test1
    [root@node4 ~]# ll acl_test1 
    -rw-r--r-- 1 root root 0 425 21:41 acl_test1
    [root@node4 ~]# setfacl -m u:testuser:rx acl_test1 
    [root@node4 ~]# ll acl_test1 
    -rw-r-xr--+ 1 root root 0 425 21:41 acl_test1
    用acl修改权限后,权限多了个+
    
  • getfacl 查看权限

    getfacl filename
    

    查看刚刚的权限

    [root@node4 ~]# getfacl acl_test1 
    # file: acl_test1
    # owner: root
    # group: root
    user::rw-  # 所有者的权限
    user:testuser:r-x  # 特定用户的权限
    group::r--  # 所属用户组默认权限
    mask::r-x  # 有效权限
    other::r-- # 其他人的权限
    
  • 设定单一用户组权限:g:用户组:权限

    [root@node4 ~]# setfacl -m g:testgroup:rx acl_test1 
    [root@node4 ~]# getfacl acl_test1 
    # file: acl_test1
    # owner: root
    # group: root
    user::rw-
    user:testuser:r-x
    group::r--
    group:testgroup:r-x  # 该群组权限已设置
    mask::r-x
    other::r--
    
  • mask是啥?mask的意义是**用户或群组的权限,只有在mask的群星范围内,才会生效。**如下,因为权限交集只有r,所以testuser的权限只有r。mask通常用来设定权限的最大范围。

    [root@node4 ~]# setfacl -m m:r acl_test1 
    [root@node4 ~]# getfacl acl_test1 
    # file: acl_test1
    # owner: root
    # group: root
    user::rw-
    user:testuser:r-x		#effective:r--
    group::r--
    group:testgroup:r-x		#effective:r--
    mask::r--
    other::r--
    
  • 文件夹权限继承

    用acl设定的权限,默认目录中的信件文件夹是不继承的,需要加上 d

    setfacl -m d:u:testuser:rx /mydir/mydir
    
  • 取消所有权限设置,注意-x是删除某个用户的acl设置,而-b是删除所有

    setfacl -x u:testuser /mydir/mydir
    setfacl -x d:u:testuser /mydir/mydir
    
    # 设置某用户不可使用某目录,注意权限用-代指
    setfacl -m u:usera:- /dir/dir
    

用户身份切换

在生产环境中,一般使用普通用户登录用户,这样比较安全。这样有以下好处

  • 避免危险操作:比如著名的【rm -rf /】如果你用root用户执行了这个,就要准备提桶跑路了。而用一般用户就没权限执行这个,就不用担心了
  • 用较低权限启动服务:比如nginx服务用nginx用户启动,这样就算这个用户被攻击了,系统不至于被完全攻陷
  • 软件本身限制:某些远程ssh工具不允许root直接登录

SU命令

su是最常用的身份切换命令

su -lm -c 命令 username
- 如果只有- 比如【su -】代表切换root,跟用户名表示切换其他用户
-c 仅执行一次命令
-l 后面需要加上想要切换的用户的账号
-m 使用目前的环境设置, 而不是新用户的

从root切换成testuser

[root@node4 ~]# su testuser
[testuser@node4 root]$ env | grep 'root'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/default/bin:/usr/java/default/bin:/opt/zookeeper-3.4.6/bin:/opt/hadoop-2.6.5/bin:/opt/hadoop-2.6.5/sbin:/opt/nginx/sbin:/root/bin
MAIL=/var/spool/mail/root
PWD=/root
# 可以看到已经切换了,但是环境变量中很多还是root的值
[testuser@node4 root]$ exit
exit  # 通过exit命令可以退出su环境

通过上面例子可以看出,只使用su命令切换身份的话,很多变量不会被修改。所以切换用户,建议加上-,如下

[root@node4 ~]# su - testuser
上一次登录:六 427 09:52:45 CST 2024pts/0[testuser@node4 ~]$ env | grep 'root'
[testuser@node4 ~]$ env | grep 'testuser'
USER=testuser
MAIL=/var/spool/mail/testuser
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/java/default/bin:/usr/java/default/bin:/opt/zookeeper-3.4.6/bin:/opt/hadoop-2.6.5/bin:/opt/hadoop-2.6.5/sbin:/opt/nginx/sbin:/home/testuser/.local/bin:/home/testuser/bin
PWD=/home/testuser
HOME=/home/testuser
LOGNAME=testuser
# 可以看到变量都已经变成新的了
[testuser@node4 ~]$ exit
登出  # 同样使用exit退出

假如我们当前是用普通用户登录的,只是想用root执行一个命令,

# testuser用户无权限
[testuser@node4 ~]$ head -n 3 /etc/shadow
head: 无法打开"/etc/shadow" 读取数据: 权限不够
[testuser@node4 ~]$ su - -c "head -n 3 /etc/shadow"
密码:   <==此处输入密码
root:$6$Rj7coYh/STyMcxjn$ZY.l1SDPcsJv1NUwiA.INYB7Q/bTxAXHFyRTm42M/qxdPWAt9Ly3eQSpu1Xn5v9LkxLJITwb6igAUPMOD.mBj/::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
[testuser@node4 ~]$ 身份还是testuser,已经成功执行了命令

总结一下:

  • 使用【su - username】切换用户,才会完整切换到新用户环境
  • 如果仅执行一次命令,可以使用【su - -c “命令”】
  • 使用root切换到其他用户,不需要输入密码

SUDO命令

上述命令切换有一个问题,就是切换到root权限需要知道root的密码。这显然是不安全的,而SUDO命令可以让普通用户以root身份执行命令。

  • sudo的用法(默认情况下sudo只有root可以使用

    sudo [-b] [-u username]
    参数:
    -b: 后台执行命令
    -u: 以该用户身份执行命令
    

    例1:

    # 使用sshd的身份建立一个新文件,注意看,权限是sshd
    [root@node4 ~]# sudo -u sshd touch /tmp/mysshd
    [root@node4 ~]# ll /tmp/mysshd
    -rw-r--r-- 1 sshd sshd 0 427 10:09 /tmp/mysshd
    

    例2:

    # 用testuser的身份建立文件
    [root@node4 tmp]# sudo -u testuser sh -c "mkdir ~testuser/www; \
    >cd ~testuser/www; echo 'hello'>index.html"
    
  • visudo和/etc/sudoers

    用户是否能够使用sudo命令,取决于/etc/sudoers的设置值。/etc/sudoers拥有特殊的语法,必须使用visudo命令去修改。我们通过以下几个例子来说明

    例1:单一用户可以使用root所有命令

    
    [root@node4 ~]# visudo
    ......
    ## Allow root to run any commands anywhere
    root    ALL=(ALL)       ALL   <== 找到这一行
    testuser    ALL=(ALL)       ALL  <== 新增这一行,注意所有ALL都是大写
    ......
    

    visudo实际上就是用vi命令修改这个文件,上面新增的含义是

    用户账号  登录者来源主机=(可切换的身份) 可执行的命令
    

    用testuser试试

    # 没有权限执行的命令,用sudo就可以执行了
    [testuser@node4 ~]$ tail -n 1 /etc/shadow
    tail: 无法打开"/etc/shadow" 读取数据: 权限不够
    [testuser@node4 ~]$ sudo tail -n 1 /etc/shadow
    testuser:$6$oJh4Uczu$dwkoctc/RXPZI2nL3YyxSMJCzel1VPTjarVkP/P53tFhKS7coIbJXAC9rhdxKyytmmvPkEGvjqmSHY9p/4kVF0:19835:0:99999:7:::
    

    例2:使用wheel用户组

    在centos7以后,wheel默认是启用的

    [root@node4 ~]# visudo
    ...
    testuser    ALL=(ALL)       ALL  # 把这一行删掉
    ...
    ...
    %wheel  ALL=(ALL)       ALL  # 找到这一行,表示wheel用户组的用户可以使用sudo
    ...
    %wheel  ALL=(ALL)       NOPASSWD: ALL  # 这一行表示无需密码
    

    我们把testuser添加进wheel组,这个组名可以自定义

    [root@node4 ~]# usermod -a -G wheel testuser
    

    这样,testuser就可以免密码的使用sudo了

    例3:部分授权

    前面两个例子都是授予了root的所有权限,如果只想授予部分功能,可以像如下这样

    [root@node4 ~]# visudo
    ...
    testuser    ALL=(root)       !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
    ...
    

    授权了testuser可以修改其他用户的密码,但无法修改root的密码

    例4:对多个用户授权

    如果要对多个用户授权,可以创建别名。这样就不用重复输入那串长长的语句了。

    [root@node4 ~]# visudo
    ...
    User_Alias ADMPW = user1, user2, user3
    Cmnd_Alias ADMPWCOM = !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
    ADMPW    ALL=(root)       ADMPWCOM
    ...
    

特殊shell

我们可以在创建用户的时候,指定shell为nologin来阻止用户登录

-s /sbin/nologin

比如我们只让某用户有ftp权限,

# useradd -g 用户组 -d 指定默认目录 -M 不创建家目录 禁止登录 用户名
useradd -g ftpgroup -d /opt/ftp/userA  -M -s /sbin/nologin userA

这实际上是通过PAM模块实现的

PAM模块

PAM是插入式验证模块的简称。在过去,验证密码是否正确有很多种方式,有了PAM之后,身份验证就只通过PAM统一进行就可以了。

这一段了解即可,详细内容我略过了。

用户信息传递

Linux是可以多用户登录的,那这些同时登录的用户之间,如何进行信息传递呢。

查询命令

  • w或者who,可以列出当前登录用户

    [root@node4 ~]# w
     12:06:58 up  2:34,  2 users,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.32.1     09:36    2.00s  0.08s  0.00s w
    testuser pts/1    192.168.32.1     10:30   28:42   0.01s  0.01s -bash
    
  • lastlog,列出最近登录时间

    [root@node4 ~]# lastlog
    用户名           端口     来自             最后登陆时间
    root             pts/1427 10:00:31 +0800 2024
    ......
    

用户信息传递

  • write命令可以在用户之间传递信息

    [root@node4 ~]# write testuser pts/1
    hello, i am root
    ## 传入一个中断信号,比如ctrl d
    此时testuser会收到
    Message from root@node4 on pts/0 at 12:13 ...
    hello, i am hanayo
    EOF
    
  • 广播命令wall

    [root@node4 ~]# wall "I'wii shutdown right now."
    [root@node4 ~]# 
    Broadcast message from root@node4 (pts/0) (Sat Apr 27 12:18:10 2024):
    
    I'wii shutdown right now.
    
    
  • 通过邮件mail命令,可以在用户之间发送邮件

小结

本章主要学习了如下内容

  • 账号和用户组,UID和GID
  • 账号管理基本命令,ACL权限设置
  • 身份管理和切换
  • 用户之间的信息传递
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值