Linux 在保证安全的前提下,可以让多个用户同时登陆系统工作。对于这样一个多用户多任务的系统,它是如何保证稳定与安全的呢。这一章就让我们来看看 Linux 是如何管理这些用户的吧
用户与权限
Linux 中有用户与用户组的概念,
用户及用户组
用户
linux 中的用户分成 3 类:
序号 | 用户 | UID | 权限 |
---|---|---|---|
1 | 系统管理员 | 0 | 管理系统的用户 |
2 | 系统用户 | 1 ~ 999 | 系统的服务程序有独立的系统用户来运行,为避免某个系统服务被黑客提权到整个服务器 |
3 | 普通用户 | 1000 ~ | 由管理员创建的日常工作用户 |
用户组
用户组是为了方便对用户权限的统一管理而设置的,在 linux 中创建一个用户就会创建一个与用户同名的基本用户组,把用户加入到其他用户组时,这个其他用户组称为扩展用户组。一个用户可以有一个基本用户组和多个扩展用户组。
常用命令
序号 | 命令 | 参数 | 功能 |
---|---|---|---|
1 | useradd | -d | 指定用户的 home 目录 |
-e | 账户的到期时间 | ||
-u | 指定用户的 UID | ||
-g | 指定用户的组 id | ||
-G | 指定用户的扩展组 id | ||
-s | 指定默认 shell | ||
2 | groupadd | 组名 | 创建用户组 |
3 | usermod | 修改用户属性 | |
-c | 用户备注 | ||
-d -m | 指定 home 目录并把文件移过去 | ||
-L | 锁定、禁止登陆 | ||
-U | 锁定、允许登陆 | ||
-G | 修改扩展用户组 | ||
-g | 修改基本用户组 | ||
4 | passwd | 修改密码、锁定密码 | |
5 | userdel | 删除用户 | |
-r | 同时删除用户及 home 目录 |
示例
- 创建一个普通用户,home 目录为
/home/wilson
,uid=8888
、shell=/sbin/nologin
>>> useradd -d /home/wilson -u 8888 -s /sbin/nologin wilson >>> id linuxprobe uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)
- 把 wilson 加入 root 用户组
>>> id wilson uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe) >>> usermod -G root wilson uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
- 删除用户及目录
>>> userdel -r wilson
文件
文件类型
linux 一切是文件,但也分成不同类型:
序号 | 标识 | 类型 |
---|---|---|
1 | - |
普通文件 |
2 | d |
目录文件 |
3 | l |
链接文件 |
4 | b |
块设备文件 |
5 | c |
字符设备文件 |
6 | p |
管道文件 |
文件归属
一个文件归属包括:所有者、所有组和其他用户,
文件基本权限
基本标识
序号 | 标识 | 文件 | 目录 |
---|---|---|---|
1 | r |
可读取内容 | 可读取目录中的文件列表 |
2 | w |
可增、删、改内容 | 可在目录中增、删、改文件名 |
3 | x |
可运行一个脚本程序 | 可进入目录 |
文件的特殊权限
权限 | 说明 |
---|---|
suid | 上方宝剑,临时拥有管理员权限 |
sgid | 1. 对文件:让执行者有文件属组权限 2. 对目录:目录中创建的文件自动继承目录用户组 |
sbit | 粘滞位/保护位,只能删除自己文件不能删除别人文件 |
删除文件的权限在于用户对目录文件是否有写入权限,
chmod 和 chown
命令 | 功能 | 格式 |
---|---|---|
chmod | 设置文件或目录的基本权限 | chmod 777 abc |
chown | 设置文件或目录的属主和属组 | chown 属主:属组 文件/目录(-R) chown root:bin test |
示例
- 执行者拥有属组权限
>>> ls -l /dev/kmem cr--r----- 1 root system 2, 1 Feb 11 2017 kmem # kmem 只有 root 和 system 组可以读取 # 用户通过 ps 命令查看 kmem 内容 >>> -ls -l ps -r-xr-sr-x 1 bin system 59346 Feb 11 2017 ps # ps 命令具有sgid权限,用户执行ps时,会具有system组权限
- 部门内设置共享目录,员工可在目录中创建和读取文件
>>> mkdir department # 让所有员工都可以读、写 >>> chmod -Rf 777 department/ # 增加sgid,目录中员工创建的文件自动继承目录组权限 >>> chmod -Rf g+s department/ # 这样普通用户在 department 中创建的文件自动继承了它的组
- 对目录设置保护位
>>> chmod -R o+t linux/
文件的隐藏权限
命令
命令 | 格式/参数 | 说明 |
---|---|---|
chattr | chattr [参数] 文件 | +参数 增加权限;-参数 删除权限 |
-a | 只能添加,不能删除 | |
lsattr | lsattr [参数] 文件 | 显示文件的隐藏属性 |
示例
-
普通用户创建目录,设置不能删除
>>> touch test >>> chattr +a test
-
显示文件的隐藏属性
[root@linuxprobe ~]# lsattr linuxprobe -----a---------- linuxprobe [root@linuxprobe ~]# chattr -a linuxprobe [root@linuxprobe ~]# lsattr linuxprobe ---------------- linuxprobe
文件访问控制列表 FACL
特性
- 针对某个特定用户或者特定的用户组设置文件或目录的操作权限,就要用到文件访问控制列表(FACL)
- 对目录设置了 FACL,则目录中的文件都继承其 FACL
- 对文件设置 FACL,则文件不再继承目录的 FACL
命令
命令 | 参数 | 说明 |
---|---|---|
setfacl | setfacl [参数] 文件/目录 | 针对特定用户/组设置的操作权限 |
-R | 目录 | |
-m | 文件 | |
-b | 删除 FACL | |
getfacl | getfacl 文件/目录 | 查看 FACL |
示例
-
让 wilson 有查看 root 目录的权限
>>> setfacl -Rm u:wilson:rwx /root >>> su - wilson Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1 >>> ls /root anaconda-ks.cfg Downloads Pictures Public >>> ls -ld /root dr-xrwx---+ 14 root root 4096 May 4 2017 /root # 文件权限的 . 变成了 + 说明设置了 FACL
-
查看 FACL
>>> getfacl /root getfacl: Removing leading '/' from absolute path names # file: root # owner: root # group: root user::r-x user:wilson:rwx group::r-x mask::rwx other::---
su 命令与 sudo 服务
命令 | 参数 | 说明 |
---|---|---|
su | 让用户在不退出登陆的情况下,切换到其他用户 | |
- | 完全切换,把环境变量信息也变更 | |
sudo | 提供额外的权限来完成 root 任务 | |
-l | 列出当前用户可执行的命令 | |
visudo | 编辑 sudo 服务的配置文件 |
sudo 特点
- 限制用户执行指定的命令
- 记录用户执行的每一条命令
- 配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数
- 验证密码的后 5 分钟内(默认值)无须再让用户再次验证密码
visudo
格式: 谁可以使用 允许使用的主机=(以谁的身份) 可执行命令的列表
visudo
96 ##
97 ## Allow root to run any commands anywhere
98 root ALL=(ALL) ALL
# wilson可以执行所有root命令,只需输入自己的密码
99 wilson ALL=(ALL) ALL
# 只能以root权限执行cat
100 linuxprobe ALL=(ALL) /usr/bin/cat
# 执行时不需输入密码
101 tom ALL=NOPASSWD: /usr/sbin/poweroff
存储结构
一切从 /
开始
文件系统是OS在存储设备上组织文件的方法,Linux 的文件系统把一切都看成文件来操作。所有文件都是从根目录 /
开始的,然后根据文件系统层级标准(FHS)采用树形结构组织文件。Linux 还定义了目录的用途。
注意: Linux 是区分大小写的,所以 wilso 和 Wilson 是两个不同的文件
绝对路径与相对路径
绝对路径是从 /
开始的路径,相对路径是以工作目录开始的路径
常见目录及内容
目录 | 功能 |
---|---|
/boot |
开机所需文件—内核、开机菜单以及所需配置文件等 |
/dev |
以文件形式存放任何设备与接口 |
/etc |
配置文件 |
/home |
用户主目录 |
/bin |
存放单用户模式下还可以操作的命令 |
/lib |
开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数 |
/sbin |
开机过程中需要的命令 |
/media |
用于挂载设备文件的目录 |
/opt |
放置第三方的软件 |
/root |
系统管理员的家目录 |
/srv |
一些网络服务的数据文件目录 |
/tmp |
任何人均可使用的“共享”临时目录 |
/proc |
虚拟文件系统,例如系统内核、进程、外部设备及网络状态等 |
/usr/local |
用户自行安装的软件 |
/usr/sbin |
Linux系统开机时不会使用到的软件/命令/脚本 |
/usr/share |
帮助与说明文件,也可放置共享文件 |
/var |
主要存放经常变化的文件,如日志 |
/lost+found |
当文件系统发生错误时,将一些丢失的文件片段存放在这里 |
物理设备文件
Linux 把物理设备也看成文件,这些文件的名称由内核中的udev设备管理器命名。udev服务会以守护进程的形式运行,一直监听内核的信号来管理设备 /dev
目录下的文件。
常见的硬件设备文件
硬件设备 | 设备文件名 |
---|---|
IDE设备 | /dev/hd[a-d] |
SCSI/SATA/U盘 | /dev/sd[a-p] |
软驱 | /dev/fd[0-1] |
打印机 | /dev/lp[0-15] |
光驱 | /dev/cdrom |
鼠标 | /dev/mouse |
磁带机 | /dev/st0或/dev/ht0 |
存储设备的分区
主机上的硬盘以 /dev/sd
开头,每块硬盘根据系统内核的识别顺序,用 a~p
来表示 (共16块)。硬盘的分区规则为:
- 1~4:主分区或扩展分区
- 5~-:逻辑分区
设备文件名的解析
我们来解析一下 /dev/sda5
这个设备文件名包含的内容:
解析:
/dev
:目录下的是硬件设备sd
:存储设备a
:同类接口中第1个被识别的设备5
:这个设备是一个逻辑分区/dev/sda5
:系统中第一块被识别到的硬件设备中分区编号为5的逻辑分区的设备文件
主分区与逻辑分区
硬盘设备由扇区(512byte)组成。第1个扇区保存着主引导记录(446 字节)与分区信息表(64字节),每一个分区信息需要16字节,所以分区信息表只能包含4个分区信息。这4个分区就是主分区。下面就是第1扇区的分布图:
为了实现更多的分区,我们就让主分区表中某个分区指向另一个分区而不再记录分区信息。这时这个分区名为扩展分区(叫分区指针更合适一点),扩展分区所指向的位置不再是一个分区,而是多个分区(即所谓的逻辑分区)的集合,而这些分区,会通过指针(下一跳的位置)的方式串联起来(实际上扩展分区项所指向的是第一个逻辑分区的首扇区,而在第一个逻辑分区的首扇区中,会记录下一个逻辑分区首扇区的地址)。要想访问到逻辑分区中的内容,需要进行多次的跳转。而要实现这一点,在启动操作系统以前是难以完成的,这也就是为什么,操作系统不能安装在逻辑分区的原因了。
扩展分区,严格地讲它不是一个实际意义的分区,它仅仅是一个指向下一个分区的指针,这种指针结构将形成一个单向链表。
文件系统
Linux 中文件建立、写入、读取、修改、转存与控制都是通过文件系统完成的。
常见的文件系统
名称 | 说明 | |
---|---|---|
Ext3 | 日志文件系统,异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误 它会把整个磁盘的每个写入动作的细节都预先记录下来,以便在发生异常宕机后能回溯追踪到被中断的部分,然后尝试进行修复 |
|
Ex4 | Ext3的改进版本,存储容量高达1EB,且能够有无限多的子目录 | |
XFS | 高性能的日志文件系统,RHEL 7中默认,宕机后快速恢复被破坏的文件 |
硬盘格式化
对于一块新硬盘,我们需要对它先分区,再格式化,最后挂载到文件系统中才可以使用。Linux 中有一个 super block 硬盘地图,记录整个文件系统的信息。Linux 把每个文件的权限、属性放在一个 inode 中,每个文件占有一个 128 字节的 inode。里面记录了:
- 该文件的访问权限 (rwx)
- 属主与属组 (owner, group)
- 文件大小 (size)
- 文件的时间(ctime、atime、mtime)
- 文件的特殊权限(SUID、SGID、SBIT)
- 文件的真实数据地址(point)
文件的实际内容则保存在block块中(大小可以是1KB、2KB或4KB),所以inode中记录着多个存放内容的block地址,当inode写满之后(一个inode的默认大小仅为128B(Ext3),记录一个block则消耗4B),又会自动分配出一个block块,专门用于像inode那样记录其他block块的信息,这样把各个block块的内容串到一起,就能够让用户读到完整的文件内容了
挂载硬件设备 mount
将设备与目录文件相关联就是挂载。命令格式为mount 文件系统 挂载目录
,卸载格式为 unmount 目录
手动挂载
例如:把 /dev/sdb2
挂载到 /backup
目录,命令如下:
>>> mount /dev/sdb2 /backup
自动挂载
在 /etc/fstab
文件中,以格式 设备文件 挂载目录 格式类型 权限类型 是否备份 是否自检
填好后,系统启动时就会自动挂载相应设备
字段 | 含义 |
---|---|
设备文件 | 一般为设备的路径+设备名称,也可以写唯一识别码(UUID,Universally Unique Identifier) |
挂载目录 | 指定要挂载到的目录,需在挂载前创建好 |
格式类型 | 指定文件系统的格式,比如Ext3、Ext4、XFS、SWAP、iso9660(此为光盘设备)等 |
权限选项 | 若设置为defaults,则默认权限为:rw, suid, dev, exec, auto, nouser, async |
是否备份 | 若为1则开机后使用dump进行磁盘备份,为0则不备份 |
是否自检 | 若为1则开机后自动进行磁盘自检,为0则不自检 |
示例
把文件系统为ext4的设备/dev/sdb2
挂载到 /backup
,默认权限,无需备份,无需自检:
>>> vim /etc/fstab
/dev/sdb2 /backup ext4 defaults 0 0
添加硬盘
把硬盘插入主板后,系统内核 udev 会检测到硬盘设备,更新 /dev
中的设备(假设为 /dev/sdb
)。要读写硬盘,先要对其进行分区,我们先从中划分出2GB的分区设备,供使用:
磁盘分区 fdisk
我们用 fdisk 磁盘设备名
来对设备进行分区,它是通过交互界面完成分区的,其中参数含义如下:
参数 | 含义 |
---|---|
m | 查看全部可用的参数 |
n | 添加新的分区 |
d | 删除某个分区信息 |
l | 列出所有可用的分区类型 |
t | 改变某个分区的类型 |
p | 查看分区表信息 |
w | 保存并退出 |
q | 不保存直接退出 |
-
执行分区命令
>>> fdisk /dev/sdb Welcome to fdisk (util-linux 2.23.2). Command (m for help): p Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors Units = sectors of 1 * 512 = 512 bytes ...
-
创建新分区,这里参数p是创建主分区,参数e是创建扩展分区
Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p # 主分区
-
输入分区号(1-4)
Partition number (1-4, default 1): 1 # 扇区的起始位置,默认即可 First sector (2048-41943039, default 2048):此处敲击回车 Using default value 2048 # 设置分区结束位置 Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +2G Partition 1 of type Linux and of size 2 GiB is set
-
查看分区表
# 查看分区表 Command (m for help): p Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x47d24a34 Device Boot Start End Blocks Id System # 新建的 2G 分区 /dev/sdb1 /dev/sdb1 2048 4196351 2097152 83 Linux # 输入 w 写入分区信息 Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
-
把分区信息同步给内核
[root@linuxprobe ]# file /dev/sdb1 /dev/sdb1: cannot open (No such file or directory) [root@linuxprobe ]# partprobe [root@linuxprobe ]# partprobe [root@linuxprobe ]# file /dev/sdb1 /dev/sdb1: block special
格式化 mkfs
现在得到的是一个存储设备,但没有格式化信息,Linux 不知以什么协议操作设备,所以我们还需要格式化这个硬件存储设备,使其成为一个系统操作的对象。格式化命令:mkfs <tab>
# 设备以 xfs 协议交互
[root@linuxprobe ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1 isize=256 agcount=4, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0
data = bsize=4096 blocks=524288, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
挂载存储器 mount
[root@linuxprobe ~]# mkdir /newFS
# 挂载设备到文件系统
[root@linuxprobe ~]# mount /dev/sdb1 /newFS/
# 查看硬盘使用量
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 18G 3.5G 15G 20% /
devtmpfs 905M 0 905M 0% /dev
tmpfs 914M 140K 914M 1% /dev/shm
tmpfs 914M 8.8M 905M 1% /run
tmpfs 914M 0 914M 0% /sys/fs/cgroup
/dev/sr0 3.5G 3.5G 0 100% /media/cdrom
/dev/sda1 497M 119M 379M 24% /boot
/dev/sdb1 2.0G 33M 2.0G 2% /newFS
查看文件占用空间 du
du [选项] [文件]
>>> du -sh /newFS/
33M /newFS/
设置自动挂载
>>> vim /etc/fstab
/dev/sdb1 /newFS xfs defaults 0 0
添加交换分区
交换分区用来把内存中不常用的内容保存在硬盘里,一般交换分区大小为内存大小的 1.5~2 倍。现在我们从 /dev/sdb
中划出 5GB 分区用于交换空间。
-
新建分区
>>> fdisk /dev/sdb Welcome to fdisk (util-linux 2.23.2). Changes will remain in memory only, until you decide to write them. ... # 新建分区 Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) # 分区为主分区 e extendedSelect (default p): p Partition number (2-4, default 2): First sector (4196352-41943039, default 4196352): 此处敲击回车 Using default value 4196352 # 分区大小 5G Last sector, +sectors or +size{K,M,G} (4196352-41943039, default 41943039): +5G Partition 2 of type Linux and of size 5 GiB is set # 显示分区信息 Command (m for help): p ...... /dev/sdb1 2048 4196351 2097152 83 Linux # 新建的分区 /dev/sdb2 4196352 14682111 5242880 83 Linux # 写入分区表 Command (m for help): w The partition table has been altered!
-
分区格式化为 SWAP
>>> mkswap /dev/sdb2 Setting up swapspace version 1, size = 5242876 KiB no label, UUID=2972f9cb-17f0-4113-84c6-c64b97c40c75
-
SWAP 挂载到文件系统
# 查看分区大小 [root@linuxprobe ~]# free -m total used free shared buffers cached Mem: 1483 782 701 9 0 254 -/+ buffers/cache: 526 957 Swap: 2047 0 2047 # 用 swapon 命令挂载 [root@linuxprobe ~]# swapon /dev/sdb2 # 交换分区变大了 [root@linuxprobe ~]# free -m total used free shared buffers cached Mem: 1483 785 697 9 0 254 -/+ buffers/cache: 530 953 Swap: 7167 0 7167
-
设置自动挂载交换分区
>>> vim /etc/fstab /dev/sdb2/ swap swap defaults 0 0
磁盘配额 quota
管理员需要针对用户和用户组,分配特定文件夹可以使用的最大空间和最大文件数量,命令为 quota
。限制分为软限制和硬限制,软限制只会给出警告。
我们设置 /boot
目录让它支持 quota 磁盘配额技术:
-
quota 支持
>>> vim /etc/fstab /dev/mapper/rhel-root / xfs defaults 1 1 # 让 boot 支持配额 UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults,uquota 1 2 >>> reboot >>> mount | grep boot # boot 已支持配额 /dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,usrquota)
-
创建一个对
/boot
有写入权限的用户 tom>>> useradd tom >>> chmod -Rf o+w /boot
-
设计配额服务
# 硬盘使用量的软限制和硬限制分别为3MB和6MB # 创建文件数量的软限制和硬限制分别为3个和6个 >>> xfs_quota -x -c 'limit bsoft=3m bhard=6m isoft=3 ihard=6 tom' /boot >>> xfs_quota -x -c report /boot User quota on /boot (/dev/sda1) Blocks User ID Used Soft Hard Warn/Grace ---------- -------------------------------------------------- root 95084 0 0 00 [--------] # tom 用户 tom 0 3072 6144 00 [--------]
-c
:以参数的形式设置要执行的命令-x
:专家模式,让运维人员能够对quota服务进行更多复杂的配置
-
用 tom 用户,创建体积为 5MB 和 8MB 文件
>>> su - tom # 写入成功 >>> dd if=/dev/zero of=/boot/tom bs=5M count=1 5242880 bytes (5.2 MB) copied, 0.123966 s, 42.3 MB/s # 写入失败 >>> dd if=/dev/zero of=/boot/tom bs=8M count=1 dd: error writing ‘/boot/tom’: Disk quota exceeded
-
重新编辑用户配额
edquota [参数] [用户]
用户编辑配额。>>> edquota -u tom
-u
:针对哪个用户进行设置-g
:针对哪个用户组进行设置
软链接和硬链接
-
硬链接 指向原始文件 inode 的指针,系统不为它分配独立的 inode,所以硬链接文件和原始文件其实就是同一个文件,只是名称不同。
每添加一个硬链接,该文件的 inode 连接数加1;只有当文件的连接数为0时,它才算彻底删除
所以即使原文件被删除,我们还是可以通过硬链接来访问文件。
-
软链接 仅包含所链接的文件路径,类似“快捷方式”
链接命令 ln
ln [选项] 链接 原文件
其中 -s
创建符号链接,否则创建硬链接
参数 | 功能 |
---|---|
-s | 创建“符号链接”(如果不带-s参数,则默认创建硬链接) |
-f | 强制创建文件或目录的链接 |
-i | 覆盖前先询问 |
-v | 显示创建链接的过程 |
区别:
- 软链接:快捷方式
- 硬链接:新建了一个inode(block 指针),不能对目录操作,不能跨分区
增加硬链接,原文件链接数增加到了 2
>>> ln readme.txt readit.txt
>>> ls readme.txt
# 链接数为 2
-rw-r--r-- 2 root root 26 Jan 11 00:13 readme.txt