• 《Linux 就是这个范儿


    用户的身份

    Linux 下的用户等级实际上是非常简单的,就两个等级 root 和非 root。root 用户在 Linux 下是拥有至高无上的权利的,也就是说它可以胡作非为。但是比较幸运的是,只有一个用户是 root,它的用户名就叫 root。而非 root 用户的权利是严格受限的,只能访问由 root 规定的文件。

    澡堂子模型

    我们把 Linux 的用户管理方式比喻成一个澡堂子模型,因为这非常形象。所有非 root 用户,都只是这个澡堂子的顾客:root 用户则是这个澡堂子的服务生;Linux 系统就是这个大澡堂子。

    去过澡堂子的人都知道,一进门就会有服务生接待你,让你登记并发给你一个带有号牌的钥匙。这个过程跟 root 用户给其他用户分配帐号是一个道理。登记是向系统中添加用户,钥匙是给你登录系统的密码,而号牌上的号码就是你的用户名。

    当你获得钥匙之后,就可以进入更衣室了。更衣室一般都会有几组大柜子。每个大柜子又有 n 多的小柜子组成,其中有一个小柜子是属于你的。怎么找到属于你的柜子呢?看柜子上面的号码!这个号码与你钥匙号牌上的号码是一致的。

    这个过程跟我们登录 Linux 系统的过程很相似。正确登陆后,我们就会拥有一个自己的文件目录,这个目录一般是 /home/[username],后面的 [username] 与你的用户名相同。一般称这个目录为“home 目录”。更衣室的柜子就是你的 home 目录,里面可以放入一些你的私人物品,可以保证别人偷不走。

    只要离开你的 home 目录,就进入了公共区间。一般都是只读的,但有少数的位置是能够写入数据的,比如 /temp 目录。在使用 Linux 的过程中如果忘记了自己的密码,只要向 root 用户申请,就能够变更新的密码。

    理解用户角色

    在 Linux 系统中还有一些用户是用来完成特定任务的,比如 nobody、admin、ftp 等。需要注意,在 Linux 中不管用户名看起来有多牛,只要不是 root ,它就一定是个普通用户,权力大小都是相同的。很多资料上说的所谓用户角色的概念,尤其是说角色不同然后权限不同的观点不是十分精准,很容易造成 Linux 用户有权限大小的印象。其实所谓的权限,则是不同的用户所能访问的文件不同而产生的一种假象。而这种假象又不是单独一个用户的概念能决定的,还要用到用户组的概念。

    什么是用户组呢?可以把它理解为用户的职业。一个用户可以属于多个用户组,而且还要注意,一个用户至少应该属于一个用户组。

    虽然用户角色不能跟权限靠上关系,但不同角色有些时候还是有待遇差别的,所谓的待遇就是是否拥有密码、home 目录以及 shell 这些资源。有些用户的主要任务就是运行某些服务程序以确保安全的,比如 nobody 用户就可以用于 Nginx(一个高性能的 HTTP 和反向代理服务器) 的工作进程。对于这类用户一般是不分配密码和 shell(严格来说还是分配 shell 了的,只是分配的是 /sbin/nologin 这个特殊的 shell。) 的,甚至 home 目录也没有。为什么要这么做呢?

    首先,可能会有很多服务程序默认使用这个用户,如果设置了密码,程序就无法自动使用了;其次,因为不会有人使用这个用户登录系统,也就没有必要分配一个 shell 给它,然而私有的 home 目录也显得有些多余。

    /etc/passwd文件查看用户

    从这个文件名上看,应该是跟密码有关。的确是这样,只是那已经成为历史了。现在保存密码的文件是 /etc/shadow,也就是传说中的“影子文件”。/etc/passwd 文件,它是用来存放用户基本信息的。这个文件的部分内容如下:

    [root@linux lixin]# more /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
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    ......
    pulse:x:496:494:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin
    piranha:x:60:60::/etc/sysconfig/ha:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
    luci:x:141:141:luci high availability management application:/var/lib/luci:/sbin/nologin
    mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
    dovecot:x:97:97:Dovecot IMAP server:/usr/libexec/dovecot:/sbin/nologin
    dovenull:x:495:491:Dovecot's unauthorized user:/usr/libexec/dovecot:/sbin/nologin
    tcpdump:x:72:72::/:/sbin/nologin
    jason:x:500:500:Jason Yang:/home/jason:/bin/bash

    文件的每一行都代表一个用户。换句话说,这个文件有几行你的系统中就拥有几个用户。每一行由冒号“:”分割成7个字段,其结构如下所示:

    用户名 : 密码 : UID : GID : 用户全名 : home 目录 : shell

    这个文件中比较重要的是 UID(User ID)GID(Group ID),无论是用户还是用户组,Linux 只靠它们来识别。所以 UID 和 GID 都只是一个数字。为了区别不同的用户或用户组,需要保持它们自身在系统中的唯一性。UID 和 GID 是可以相同的,因为它们代表的是不同的概念(可以把他们理解为两张数据库表中的主键值),都为 0 的 UID 和 GID 是 Linux 系统中比较特殊的,它们分配给 root 用户和 root 用户组。UID 和 GID 是可以通过程序获取的,所以可以通过这个特殊的值来判断是否能够胡作非为。

    虽然系统只区别 0 和 非零的 UID 和 GID,但是在使用习惯上还是进行了一些分段的(类似我们的平时分配端口号那样)。0 自然不用说,就是给 root 的;1~499是属于系统用户的,比如前面提到的那些待遇比较差的和一些甚至是占坑的就属于这类;500~4294967295是分配普通用户的。所以你会发现,你系统中的第一个被添加的用户的 UID 和 GID 都是 500。

    /etc/group文件查看用户组

    跟用户组有关的文件就是 /etc/group 文件了,也就是 /etc/passwd 中 GID 的来源。这个文件的部分内容如下所示:

    [root@linux ~]# more /etc/group
    root:x:0:
    bin:x:1:bin,daemon
    daemon:x:2:bin,daemon
    sys:x:3:bin,adm
    adm:x:4:adm,daemon
    tty:x:5:
    disk:x:6:
    lp:x:7:daemon
    mem:x:8:
    kmem:x:9:
    wheel:x:10:
    mail:x:12:mail,postfix
    uucp:x:14:
    man:x:15:
    games:x:20:
    gopher:x:30:
    ......
    fuse:x:492:
    stapusr:x:156:
    stapsys:x:157:
    stapdev:x:158:
    webalizer:x:67:
    piranha:x:60:
    sshd:x:74:
    postgres:x:26:
    luci:x:141:
    mysql:x:27:
    dovecot:x:97:
    dovenull:x:491:
    sfcb:x:490:root
    tcpdump:x:72:
    slocate:x:21:
    jason:x:500:

    与 /etc/passwd 类似,同样是每行代表一个用户组,只是这个文件比较简单,被冒号“:”分割成了四段。行结构如下所示:

    组名 : 用户组密码 : GID : 用户组内的用户名

    从 /etc/group 文件的结构可以看出,不但用户有密码,用户组也是有密码的。那么用户组密码是做什么的呢?是给用户组管理员用的。不过目前很少有这个机会要配置用户组管理员,与 /etc/passwd 一样,组密码是存储在 /etc/gshadow 文件中。那么这个字段也就是纯粹的“歪歪”了,它永远都是“x”。

    比较怪异的是“用户组内的用户名”这个字段,因为从上述文件中会发现,有很多组是没有使用这个字段的。而使用这个字段的,则会使用逗号“,”来分割每个用户名。那么这个字段到底是什么含义呢?前面我们就说过,一个用户是可以身兼数职的(多个用户组)。那么,只要用户兼职了这个用户组,它的名字就会出现在这个字段里。那么那些没有使用这个字段的组呢?很显然,就是没有人兼职呗。但是没有人兼职,并不代表没人专职。在 /etc/passwd 文件中,某个用户的 GID 字段所代表的就是专职用户组。按照 Linux 中的术语,这叫“初始用户组”;那些兼职的用户组,就被叫做“支持用户组”。对于专职的用户来讲,是可以不出现在“用户组内的用户名”这个字段的。使用 groups 命令可以查看所有的“支持用户组”,而且在“支持用户组”的列表中第一个出现的那个组还有一个称呼,叫“有效用户组”。

    管理用户和组

    Linux 系统为用户和用户组的增、删、改提供了一些基本的命令。这些命令的作用就是对 /etc/passwd 和 /etc/group 这两个文件进行增、删、改来完成的。外加一个 /etc/shadow 文件专门用来管理密码。

    Linux 中添加一个新的用户,可以使用 useradd 命令,同时还可以使用 adduser 命令。但 useradd 命令在任何 Linux 发行版都是一样的,所以我们最好牢记的是它,那么,添加一个新用户最简单的方法,可以使用这样的命令(注意,需要 root 权限):

    [root@linux ~]# useradd lucky

    这样名为 lucky 的用户就添加到系统中了。同时,系统已经帮我们设定好了很多的默认值了,这包括:

    1、创建一个唯一的 UID;
            2、添加一个与用户名相同的用户组和一个唯一的 GID,并将用户设置为改组的专职用户;
            3、在 /home 目录下创建一个与用户名相同的目录;
            4、设置 shell 为 bin/bash

    唯一还没有设置的就是密码了,使用 passwd 命令可以做到这一点,如下所示:

    [root@linux ~]# passwd lucky
    更改用户 lucky 的密码 。
    新的 密码:######
    重新输入新的 密码:######
    passwd: 所有的身份验证令牌已经成功更新。

    当录入密码时,光标是不会有任何反映的,不会有类似图形界面的“***”或“###”什么的出现。在文本状态下,所有有关密码的操作都是这样,包括使用文本界面登录的时候。虽然这种方式不允许我们在输入密码时被打断,但是安全性更好。

    刚才的操作只是给指定用户修改密码(passwd 命令传递要修改的用户名),如果要修改当前登录用户的密码,不带用户名参数即可。更复杂的,比如修改密码的时效性等高级的内容,还有 chage 命令。

    我们在添加新用户的时候难免不犯点错误,比如名字给弄错了。这个时候能有修正错误的方法将会是很可爱的事情,正好 usermod 命令能干这事。实际上 usermod 并不是弥补错误而提供的,因为修正用户的某些细微的配置参数实际上是更常见的操作,比如希望使用一个与众不同的 shell,usermod 命令简单示例如下:

    [root@linux ~]# usermod -l lucky123 lucky

    这样名为 lucky 的用户,登录名将被更改为 lucky123,关于 usermod 命令更多使用方式,请参考《usermod 命令详解》,或使用 man 命令查看帮助。

    要删除某个用户,可以使用 userdel 命令。这个命令相当简单,希望删掉谁就把谁的用户写在它后面就行。如果你是 root,userdel 命令基本上就是你的判官笔了,“写谁”谁就消失了。此外,它还有一个“-r”的命令选项,把用户的 home 目录一同删掉。所以这个命令不但会“杀人”,还会“抄家”。

    至于用户组的管理实际上是跟用户很像的,也拥有差不多相同的命令,差别就是将“user”这个前缀替换成“group”,即 groupaddgroupmodgroupdel

    如果你对前面介绍的这些命令还有什么疑问,那就千万不要忘记我们在第一章中介绍的那个 man 命令,它能帮助你了解到全部。后面的内容中所出现的命令我们也不会太多地去讲述具体用法,我们希望你能养成一个自学的好习惯。

    利用sudo假借身份

    Linux 用户在执行某些操作的时候,时常会借用一下其他用户的身份,那么借用谁的身份呢?答案是 root 的,也就是以 root 身份来执行某些操作。比如 /etc/shadow 文件,由于其特殊性,普通用户是不被允许查看其内容的。但是拥有 sudo 特权的用户,可以执行以下命令,查看到这个文件的内容:

    [jason@linux ~]$ sudo cat /etc/shadow

    普通用户一旦拥有 sudo 的特权,几乎就可以胡作非为了,但是需要付出一点代价,需要在将要执行的命令前面冠上 sudo 这个前缀(别忘了空格分割)。同时被系统提示要求输入密码。但是,你现在可能不能立即验证这个功能,因为你现在所使用的这个用户(非root)未必具备 sudo 特权。那么,可以利用 root 用户让某个普通用户具备 sudo 特权。

    给某个用户赋予 sudo 特权,实际上就是更改 /etc/sudoers 文件中的内容。这个文件比较重要的内容如下所示:

    [root@linux ~]# cat /etc/sudoers
    ......
    ## Allow root to run any commands anywhere
    root    ALL=(ALL)       ALL
    
    ## Allows people in group wheel to run all commands
    # %wheel        ALL=(ALL)       ALL
    
    ## Same thing without a password
    # %wheel        ALL=(ALL)       NOPASSWD: ALL
    
    ## Allows members of the users group to mount and unmount the
    ## cdrom as root
    # %users  ALL=/sbin/mount/mnt/cdrom, /sbin/umount/mnt/cdrom
    ......

    在这个文件中,所有以“#”开头的行都是注释内容。所以这个文件中的内容绝大多数都是废话,因为只有一行没有以“#”开头。那一行的内容就是:

    root        ALL=(ALL)        ALL

    它的含义是说 root 用户可以使用 sudo 特权以 root 权限执行任何命令。显然又是一句废话,root 用户有必要运用它的 sudo 特权吗?但是学着它的样子,自己添加一行,比如:

    jason        ALL=(ALL)        ALL

    那么 jason 用户就可以使用 sudo 特权以 root 权限执行任何命令了。

    如果需要赋予 sudo 特权的用户只有少数那么几个,这样单独授权的方式没有什么问题。但是 Linux 还支持另外一种授权方法,那就是针对用户组授权,如下所示:

    %wheel        ALL=(ALL)        ALL

    这一行的作用就是让 wheel 用户组的所有用户默认拥有 sudo 特权。那么当需要给某个用户授权时,只要将其加入到 wheel 用户组即可。通过对比,与单独针对用户授权,针对用户组授权的区别在于在名称前面加了一个百分号“%”。

    sudo 还有另外一个更为霸气的功能,就是在下面的这一行中。

    %wheel        ALL=(ALL)        NOPASSWD:ALL

    同样是给 wheel 用户组授权,但是关键的就是这个 NOPASSWD,可以使得不需要输入密码即可拥有 root 权限。这个 NOPASSWD 并不仅仅作用于用户组,对于我们前面所说的针对单个用户授权的方法也是有效的。

    上面所介绍的这些修改,会让拥有 sudo 特权的用户能够以 root 权限执行任何命令,很多时候会觉得这个权限给的太过宽松,显然会威胁到管理员的地位。所以做必要的限制还是合理的。下面的代码能够满足这一需求:

    %users   ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

    这一行主要描述了 users 用户组,可以执行:

    /sbin/mount/mnt/cdrom

    /sbin/umount/mnt/cdrom

    这两个命令,其他的都将被 Linux 系统拒绝。需要注意,这里一定要写明命令的完全路径,两个命令之间使用逗号“,”分割。

    显然一个命令一个命令地写是非常麻烦的,只允许执行这几个命令也是有违背赋予 sudo 特权的初衷的。但是别着急,sudo 还有另外一种写法,可以是这样:

    %users   ALL=(ALL)   ALL,!/usr/sbin/adduser, !/usr/sbin/useradd

    这一行使得 users 用户组无法使用 sudo 特权给系统添加新的用户。关键就在叹号“!”这里,它表示禁止使用某些命令。

    使用 sudo 特权,必须在每个命令前冠以 sudo,这会给管理员的很多工作造成不需要的麻烦,su 命令可以解决这个问题。

    su 命令就是做零时用户切换的,默认是切换到 root 用户。su 在做用户切换的时候也会提示输入密码,但是与 sudo 需要输入自己的密码不同,su 要求输入目标用户的密码,如果是切换到 root,那么要求的是 root 密码。一旦切换完成,就会将当前的用户转换为目标用户。如果希望再切换回原始用户,就可以使用 exit 命令。

    如果不给 su 命令任何参数,它切换的用户是 root 用户,同时不会更改当前所在的目录。比如说你当前所在的目录是 /home/jason,那么执行完 su 命令后,依然是在这个目录。当给 su 命令传递一个“-”参数时,即执行“su -”,则会改变当前目录到目标用户的 home 目录。

    顺便说一下,拥有 sudo 特权的用户,是可以通过执行:

    [jason@linux ~]$ sudo su

    命令,直接使用自己的密码切换成 root 用户的。原理就是 root 用户使用 su 命令切换到任何用户都不提示密码。这显然是不安全的。为了避免这种问题发生,应该在 /etc/sudoers 文件中明确禁止 su 被 sudo 特权执行。

    我是谁?

    我们需要先做一些准备,请以普通用户登录系统,比如我是 jason,然后执行命令:

    [jason@linux ~]$ whoami
    jason
    [jason@linux ~]$ who am i
    jason    pts/0       2014-09-23 00:38 (192.168.0.100)

    接着我们使用 su 命令切换到 root 用户下再试一下:

    [root@linux ~]# whoami
    root
    [root@linux ~]# who am i
    jason    pts/0       2014-09-23 00:38 (192.168.0.100)

    看出区别来了吗?whoami 这个命令的结果是不同的,但是 who am i 命令却有相同结果,要解释这背后的机制,需要引入另外两个新的概念--实际用户(UID)和有效用户(EUID,即 Effective UID)。

    所谓的实际用户是指用户登录时所使用的用户,所以在整个登录会话中,实际用户是不会发生变化的(who am i 执行的结果);而有效用户则是指当前执行操作的用户(whoami 执行的结果),这个是能够利用 su 或 sudo 命令进行任意切换的,也就是真正决定权限高低的用户,一般情况下,实际用户和有效用户是相同的,只有发生用户身份切换的时候,才会有差异。对那些经常需要切换用户的系统管理员来说,就经常需要搞清当前使用的是什么身份,毕竟切来切去的换做谁都有可能凌乱。

  • 相关阅读:
    Docker部署Mysql实践
    Docker部署Zookeeper部署集群实践(2)
    Docker部署Zookeeper部署实践(1)
    Docker部署Jenkins 2.285版持续部署集成实践(1)
    Ubuntu18.04安装docker
    Git的配置
    C语言的一些小知识
    线段树模板整理
    关于Kmp
    HDU-2063(二分图匹配模板题)
  • 原文地址:https://www.cnblogs.com/jasonsoop/p/3976024.html
Copyright © 2020-2023  润新知