picaj的分享

Linux基础部分(下)

一、磁盘阵列RAID

1、RAID 0

将数据条带化,读写性能*N,但是挂了一块盘会导致所有数据丢失。

image-72

2、RAID 1

将数据镜像化,读写性能*1,挂了一块盘有备份。

image-73

3、RAID 5

写性能*1,读性能*(N-1)

RAID5的核心思想是使用奇偶校验信息来提供数据的冗余备份。当其中一个硬盘驱动器发生故障时,剩余的硬盘驱动器可以通过计算奇偶校验信息来恢复丢失的数据。这种方式既提供了数据冗余和容错能力,又降低了整体存储成本。

image-74

4、RAID 10

先做数据镜像,再做数据条带

读写性能*N(N为RAID0的硬盘数,此例为2),不能同时坏数据块1a与2a

image-75

5、部署磁盘阵列

image-76

软件阵列vs硬件阵列

硬件阵列额外花钱,而且需要缓存。在大容量文件存储的场景下,硬阵列用处不大,因为缓存几乎无用。

5.1、mdadm命令

常用参数以及作用

参数 作用
-a 检测设备名称
-n 指定设备数量
-l 指定RAID级别
-C 创建
-v 显示过程
-f 模拟设备损坏
-r 移除设备
-Q 查看摘要信息
-D 查看详细信息
-S 停止RAID磁盘阵列
-x 备份盘数量
[root@localhost ~]# yum -y install mdadm
[root@localhost ~]# mdadm -Cv /dev/md0 -a yes -n 4 -l 10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to n2
mdadm: layout defaults to n2
mdadm: chunk size defaults to 512K
mdadm: size set to 20954112K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

把制作好的RAID磁盘阵列格式化为ext4格式

[root@localhost ~]# mkfs.ext4 /dev/md0
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=256 blocks
2621440 inodes, 10477056 blocks
523852 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2157969408
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
    4096000, 7962624

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

创建挂载点然后把硬盘设备进行挂载操作

[root@localhost ~]# mkdir /mnt/RAID
[root@localhost ~]# mount /dev/md0 /mnt/RAID
[root@localhost ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   17G  1.1G   16G   7% /
devtmpfs                 898M     0  898M   0% /dev
tmpfs                    910M     0  910M   0% /dev/shm
tmpfs                    910M  9.6M  901M   2% /run
tmpfs                    910M     0  910M   0% /sys/fs/cgroup
/dev/sda1               1014M  146M  869M  15% /boot
tmpfs                    182M     0  182M   0% /run/user/0
/dev/md0                  40G   49M   38G   1% /RAID

查看/dev/md0磁盘阵列的详细信息,并把挂载信息写入到配置文件中,使其永久生效。

[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Mon Apr 15 17:43:04 2019
        Raid Level : raid10
        Array Size : 41908224 (39.97 GiB 42.91 GB)
     Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
      Raid Devices : 4
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Mon Apr 15 17:44:14 2019
             State : active, resyncing 
    Active Devices : 4
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 0

            Layout : near=2
        Chunk Size : 512K

Consistency Policy : resync

     Resync Status : 66% complete

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : 9b664b1c:ab2b2fb6:6a00adf6:6167ad51
            Events : 15

    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync set-A   /dev/sdb
       1       8       32        1      active sync set-B   /dev/sdc
       2       8       48        2      active sync set-A   /dev/sdd
       3       8       64        3      active sync set-B   /dev/sde
[root@localhost ~]# echo "/dev/md0 /RAID ext4 defaults 0 0" >> /etc/fstab 
测试磁盘性能:
# 从zero里面取无穷无尽的文件,写入file文件,每次取256M,取4次。
# 因为先写内存,再到硬盘,防止内存过载。
[root@localhost ~]#  dd < /dev/zero > file bs=256M count=4
记录了4+0 的读入
记录了4+0 的写出
1073741824字节(1.1 GB)已复制,2.21844 秒,484 MB/秒

6、关闭部署好的磁盘阵列

关闭RAID阵列
[root@localhost ~]# umount /dev/md0 /mnt/RAID/
# 先取消在文件系统中的挂载
[root@localhost ~]# mdadm -S /dev/md0
#必须清除成员磁盘当中阵列的超级块信息,这一步很重要!否则开机会重新做RAID
[root@localhost ~]# mdadm --zero-superblock /dev/sd[b-e]
#取消开机自动挂载,干掉那一行
[root@localhost ~]# vim /etc/fstab

7、损坏磁盘阵列及修复

在确认有一块物理硬盘设备出现损坏而不能继续正常使用后,应该使用mdadm命令将其移除,然后查看RAID磁盘阵列的状态,可以发现状态已经改变。

[root@localhost ~]# mdadm /dev/md0 -f /dev/sdb
mdadm: set /dev/sdb faulty in /dev/md0
[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu Apr 18 09:25:38 2019
        Raid Level : raid10
        Array Size : 41908224 (39.97 GiB 42.91 GB)
     Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
      Raid Devices : 4
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Thu Apr 18 09:28:24 2019
             State : clean, degraded 
    Active Devices : 3
   Working Devices : 3
    Failed Devices : 1
     Spare Devices : 0

            Layout : near=2
        Chunk Size : 512K

Consistency Policy : resync

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : 09c273ff:77fa1bc2:84a934f1:b924fa6e
            Events : 27

    Number   Major   Minor   RaidDevice State
       -       0        0        0      removed
       1       8       32        1      active sync set-B   /dev/sdc
       2       8       48        2      active sync set-A   /dev/sdd
       3       8       64        3      active sync set-B   /dev/sde

       0       8       16        -      faulty   /dev/sdb

在RAID 10级别的磁盘阵列中,当RAID 1磁盘阵列中存在一个故障盘时并不影响RAID 10磁盘阵列的使用。当购买了新的硬盘设备后再使用mdadm命令来予以替换即可,在此期间我们可以在/RAID目录中正常地创建或删除文件。由于我们是在虚拟机中模拟硬盘,所以先重启系统,然后再把新的硬盘添加到RAID磁盘阵列中。

[root@localhost ~]# umount /mnt/RAID/
#有时候失败,告诉设备忙,-f参数都没用
#用fuser -v -n file /mnt/RAID/查看谁占用文件详细,包括进程号
#用fuser -v -n tcp 22命令查看tcp22号端口占用的进程与用户
#用fuser -mk /mnt/RAID/命令杀死所有占用该文件的进程
#先热移除sdb
[root@localhost ~]# mdadm /dev/md0 -r /dev/sdb
#再加上sdb
[root@localhost ~]# mdadm /dev/md0 -a /dev/sdb
mdadm: added /dev/sdb
[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu Apr 18 09:25:38 2019
        Raid Level : raid10
        Array Size : 41908224 (39.97 GiB 42.91 GB)
     Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
      Raid Devices : 4
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Thu Apr 18 09:34:14 2019
             State : clean, degraded, recovering 
    Active Devices : 3
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 1

            Layout : near=2
        Chunk Size : 512K

Consistency Policy : resync

    Rebuild Status : 30% complete

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : 09c273ff:77fa1bc2:84a934f1:b924fa6e
            Events : 47

    Number   Major   Minor   RaidDevice State
       4       8       16        0      spare rebuilding   /dev/sdb
       1       8       32        1      active sync set-B   /dev/sdc
       2       8       48        2      active sync set-A   /dev/sdd
       3       8       64        3      active sync set-B   /dev/sde
[root@localhost ~]# echo "/dev/md0        /mnt/RAID       ext4    defaults        0       0" >> /etc/fstab
[root@localhost ~]# mount -a
# 有时候重新加sdb没用,只能删了阵列重新组,数据会全丢失
#[root@localhost ~]# umount /mnt/RAID/
#[root@localhost ~]# mdadm -S /dev/md0
#[root@localhost ~]# mdadm -Cv /dev/md0 -a yes -n 4 -l 10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
#[root@localhost ~]# mkfs.ext4 /dev/md0

8、磁盘阵列+备份盘

为了避免多个实验之间相互发生冲突,我们需要保证每个实验的相对独立性,为此需要大家自行将虚拟机还原到初始状态。

部署RAID 5磁盘阵列时,至少需要用到3块硬盘,还需要再加一块备份硬盘,所以总计需要在虚拟机中模拟4块硬盘设备

现在创建一个RAID 5磁盘阵列+备份盘。在下面的命令中,参数-n 3代表创建这个RAID 5磁盘阵列所需的硬盘数,参数-l 5代表RAID的级别,而参数-x 1则代表有一块备份盘。当查看/dev/md0(即RAID 5磁盘阵列的名称)磁盘阵列的时候就能看到有一块备份盘在等待中了。

[root@localhost ~]# mdadm -Cv /dev/md0 -n 3 -l 5 -x 1 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to left-symmetric
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 512K
mdadm: /dev/sdb appears to be part of a raid array:
       level=raid10 devices=4 ctime=Thu Apr 18 09:25:38 2019
mdadm: /dev/sdc appears to be part of a raid array:
       level=raid10 devices=4 ctime=Thu Apr 18 09:25:38 2019
mdadm: /dev/sdd appears to be part of a raid array:
       level=raid10 devices=4 ctime=Thu Apr 18 09:25:38 2019
mdadm: /dev/sde appears to be part of a raid array:
       level=raid10 devices=4 ctime=Thu Apr 18 09:25:38 2019
mdadm: size set to 20954112K
Continue creating array? y           
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu Apr 18 09:39:26 2019
        Raid Level : raid5
        Array Size : 41908224 (39.97 GiB 42.91 GB)
     Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Thu Apr 18 09:40:28 2019
             State : clean 
    Active Devices : 3
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 1

            Layout : left-symmetric
        Chunk Size : 512K

Consistency Policy : resync

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : f72d4ba2:1460fae8:9f00ce1f:1fa2df5e
            Events : 18

    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync   /dev/sdb
       1       8       32        1      active sync   /dev/sdc
       4       8       48        2      active sync   /dev/sdd

       3       8       64        -      spare   /dev/sde

将部署好的RAID 5磁盘阵列格式化为ext4文件格式,然后挂载到目录上,之后就可以使用了。

[root@localhost ~]# mkfs.ext4 /dev/md0
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=256 blocks
2621440 inodes, 10477056 blocks
523852 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2157969408
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
    4096000, 7962624

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

[root@localhost ~]# echo "/dev/md0 /RAID ext4 defaults 0 0" >> /etc/fstab 
[root@localhost ~]# mkdir /mnt/RAID
[root@localhost ~]# mount -a

把硬盘设备/dev/sdb移出磁盘阵列,然后迅速查看/dev/md0磁盘阵列的状态

[root@localhost ~]# mdadm /dev/md0 -f /dev/sdb
mdadm: set /dev/sdb faulty in /dev/md0
# /dev/sde由原来的spare顶上来变成spare-building
[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu Apr 18 09:39:26 2019
        Raid Level : raid5
        Array Size : 41908224 (39.97 GiB 42.91 GB)
     Used Dev Size : 20954112 (19.98 GiB 21.46 GB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Thu Apr 18 09:51:48 2019
             State : clean, degraded, recovering 
    Active Devices : 2
   Working Devices : 3
    Failed Devices : 1
     Spare Devices : 1

            Layout : left-symmetric
        Chunk Size : 512K

Consistency Policy : resync

    Rebuild Status : 40% complete

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : f72d4ba2:1460fae8:9f00ce1f:1fa2df5e
            Events : 26

    Number   Major   Minor   RaidDevice State
       3       8       64        0      spare rebuilding   /dev/sde
       1       8       32        1      active sync   /dev/sdc
       4       8       48        2      active sync   /dev/sdd

       0       8       16        -      faulty   /dev/sdb

二、LVM逻辑卷管理器

1、LVM(逻辑卷管理器)

逻辑卷管理器是Linux系统用于对硬盘分区进行管理的一种机制,理论性较强,其创建初衷是为了解决硬盘设备在创建分区后不易修改分区大小的缺陷。尽管对传统的硬盘分区进行强制扩容或缩容从理论上来讲是可行的,但是却可能造成数据的丢失。而LVM技术是在硬盘分区和文件系统之间添加了一个逻辑层,它提供了一个抽象的卷组,可以把多块硬盘进行卷组合并。这样一来,用户不必关心物理硬盘设备的底层架构和布局,就可以实现对硬盘分区的动态调整。

image-77

物理卷处于LVM中的最底层,可以将其理解为物理硬盘、硬盘分区或者RAID磁盘阵列,这都可以。卷组建立在物理卷之上,一个卷组可以包含多个物理卷,而且在卷组创建之后也可以继续向其中添加新的物理卷。逻辑卷是用卷组中空闲的资源建立的,并且逻辑卷在建立后可以动态地扩展或缩小空间。这就是LVM的核心理念。

PE最小存储单元,VG通过PV组合好PE,成一个整的;然后LV从VG分出来可供挂载使用

2、部署逻辑卷

常用的LVM部署命令

功能/命令 物理卷管理 卷组管理 逻辑卷管理
扫描 pvscan vgscan lvscan
建立 pvcreate vgcreate lvcreate
显示 pvdisplay vgdisplay lvdisplay
删除 pvremove vgremove lvremove
扩展 vgextend lvextend
缩小 vgreduce lvreduce

为了避免多个实验之间相互发生冲突,请大家自行将虚拟机还原到初始状态,并在虚拟机中添加两块新硬盘设备,然后开机

第1步:让新添加的两块硬盘设备支持LVM技术

[root@localhost ~]# pvcreate /dev/sdb /dev/sdc
  Physical volume "/dev/sdb" successfully created.
  Physical volume "/dev/sdc" successfully created.
#有时候创建不成功,有残留数据需要重新做分区表
#[root@localhost ~]#parted /dev/sd[b-c] mklabel msdos

第2步:把两块硬盘设备加入到storage卷组中,然后查看卷组的状态

[root@localhost ~]# vgcreate storage /dev/sdb /dev/sdc
  Volume group "storage" successfully created
[root@localhost ~]# vgdisplay storage
  --- Volume group ---
  VG Name               centos
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               <19.00 GiB
  PE Size               4.00 MiB
  Total PE              4863
  Alloc PE / Size       4863 / <19.00 GiB
  Free  PE / Size       0 / 0   
  VG UUID               hXvPk7-ey0X-GUp1-NesK-9ty4-LVMc-6FUtwh

  --- Volume group ---
  VG Name               storage
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               39.99 GiB
  PE Size               4.00 MiB
  Total PE              10238
  Alloc PE / Size       0 / 0   
  Free  PE / Size       10238 / 39.99 GiB
  VG UUID               R3Lgwt-YdRK-3Qhx-vzzt-P4gM-yxbZ-VbeojU

第3步:切割出一个约为150MB的逻辑卷设备。

这里需要注意切割单位的问题。在对逻辑卷进行切割时有两种计量单位。

第一种是以容量为单位,所使用的参数为-L。例如,使用-L 150M生成一个大小为150MB的逻辑卷。

另外一种是以基本单元的个数为单位,所使用的参数为-l。每个基本单元的大小默认为4MB。例如,使用-l 37可以生成一个大小为37×4MB=148MB的逻辑卷。

# [root@localhost ~]# lvcreate -n vo -l 37 -I 8M storage
[root@localhost ~]# lvcreate -n vo -l 37 storage
  Logical volume "vo" created.
# 每个PE占4M,37*4=148M,远少于sdb的20G,不会占用到第二个PV(sdc),所以lsblk只看到占用了sdb
[root@localhost ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   20G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   19G  0 part
  ├─centos-root 253:0    0   17G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0   20G  0 disk
└─storage-vo    253:2    0  148M  0 lvm
sdc               8:32   0   20G  0 disk
sdd               8:48   0   20G  0 disk
sde               8:64   0   20G  0 disk
sr0              11:0    1 1024M  0 rom

[root@localhost ~]# lvdisplay 
  --- Logical volume ---
  LV Path                /dev/centos/swap
  LV Name                swap
  VG Name                centos
  LV UUID                RHOW0p-W5MW-lfGs-rIFk-tcmK-bKsd-bdh3ej
  LV Write Access        read/write
  LV Creation host, time localhost, 2019-04-15 17:30:59 +0800
  LV Status              available
  # open                 2
  LV Size                2.00 GiB
  Current LE             512
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:1

  --- Logical volume ---
  LV Path                /dev/centos/root
  LV Name                root
  VG Name                centos
  LV UUID                u4rM0M-cE5q-ii2n-j7Bd-eXvd-Gsw0-8ByOgp
  LV Write Access        read/write
  LV Creation host, time localhost, 2019-04-15 17:31:00 +0800
  LV Status              available
  # open                 1
  LV Size                <17.00 GiB
  Current LE             4351
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:0

  --- Logical volume ---
  LV Path                /dev/storage/vo
  LV Name                vo
  VG Name                storage
  LV UUID                WP06I4-XA8u-mGqT-uFEZ-uhyN-nbrT-ehKMTe
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2019-04-18 13:37:34 +0800
  LV Status              available
  # open                 0
  LV Size                148.00 MiB
  Current LE             37
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:2

第4步:把生成好的逻辑卷进行格式化,然后挂载使用。

[root@localhost ~]# mkfs.ext4 /dev/storage/vo
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
38000 inodes, 151552 blocks
7577 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=33816576
19 block groups
8192 blocks per group, 8192 fragments per group
2000 inodes per group
Superblock backups stored on blocks: 
    8193, 24577, 40961, 57345, 73729

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done 

[root@localhost ~]# mkdir /mnt/vo
[root@localhost ~]# mount /dev/storage/vo /mnt/vo
[root@localhost ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   17G 1003M   17G   6% /
devtmpfs                 898M     0  898M   0% /dev
tmpfs                    910M     0  910M   0% /dev/shm
tmpfs                    910M  9.5M  901M   2% /run
tmpfs                    910M     0  910M   0% /sys/fs/cgroup
/dev/sda1               1014M  146M  869M  15% /boot
tmpfs                    182M     0  182M   0% /run/user/0
/dev/mapper/storage-vo   140M  1.6M  128M   2% /vo
[root@localhost ~]# echo "/dev/storage/vo /mnt/vo ext4 defaults 0 0" >> /etc/fstab

3、扩容逻辑卷

第1步:把上一个实验中的逻辑卷vo扩展至290MB

[root@localhost ~]# umount /mnt/vo
[root@localhost ~]# lvextend -L 290M /dev/storage/vo 
  Rounding size to boundary between physical extents: 292.00 MiB.
  Size of logical volume storage/vo changed from 148.00 MiB (37 extents) to 292.00 MiB (73 extents).
  Logical volume storage/vo successfully resized.

第2步:检查硬盘完整性,并重置硬盘容量,否则挂载了还是148M

[root@localhost ~]# e2fsck -f /dev/storage/vo
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/38000 files (0.0% non-contiguous), 10453/151552 blocks
[root@localhost ~]# resize2fs /dev/storage/vo
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/storage/vo to 299008 (1k) blocks.
The filesystem on /dev/storage/vo is now 299008 blocks long.

第3步:重新挂载硬盘设备并查看挂载状态

[root@localhost ~]# mount -a
[root@localhost ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   17G 1003M   17G   6% /
devtmpfs                 898M     0  898M   0% /dev
tmpfs                    910M     0  910M   0% /dev/shm
tmpfs                    910M  9.5M  901M   2% /run
tmpfs                    910M     0  910M   0% /sys/fs/cgroup
/dev/sda1               1014M  146M  869M  15% /boot
tmpfs                    182M     0  182M   0% /run/user/0
/dev/mapper/storage-vo   279M  2.1M  259M   1% /vo

第4步,如果扩容到30G,则会占用到sdc的pv

[root@localhost ~]# umount /mnt/vo
[root@localhost ~]# lvextend -L 30G /dev/storage/vo 
[root@localhost ~]# e2fsck -f /dev/storage/vo
[root@localhost ~]# resize2fs /dev/storage/vo
[root@localhost ~]# mount -a
[root@Centos7-VM-1 ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   20G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   19G  0 part
  ├─centos-root 253:0    0   17G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0   20G  0 disk
└─storage-vo    253:2    0   30G  0 lvm  /mnt/vo
sdc               8:32   0   20G  0 disk
└─storage-vo    253:2    0   30G  0 lvm  /mnt/vo
sdd               8:48   0   20G  0 disk
sde               8:64   0   20G  0 disk
sr0              11:0    1 1024M  0 rom

4、缩小逻辑卷

第1步:检查文件系统的完整性

[root@localhost ~]# umount /mnt/vo
[root@localhost ~]# e2fsck -f /dev/storage/vo
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/74000 files (0.0% non-contiguous), 15507/299008 blocks

第2步:把逻辑卷vo的容量减小到120MB

[root@localhost ~]# resize2fs /dev/storage/vo 120M
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/storage/vo to 122880 (1k) blocks.
The filesystem on /dev/storage/vo is now 122880 blocks long.

[root@localhost ~]# lvreduce -L 120M /dev/storage/vo
  WARNING: Reducing active logical volume to 120.00 MiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce storage/vo? [y/n]: y
  Size of logical volume storage/vo changed from 292.00 MiB (73 extents) to 120.00 MiB (30 extents).
  Logical volume storage/vo successfully resized.

第3步:重新挂载文件系统并查看系统状态

[root@localhost ~]# mount -a
[root@localhost ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   17G 1003M   17G   6% /
devtmpfs                 898M     0  898M   0% /dev
tmpfs                    910M     0  910M   0% /dev/shm
tmpfs                    910M  9.5M  901M   2% /run
tmpfs                    910M     0  910M   0% /sys/fs/cgroup
/dev/sda1               1014M  146M  869M  15% /boot
tmpfs                    182M     0  182M   0% /run/user/0
/dev/mapper/storage-vo   113M  1.6M  103M   2% /vo

5、逻辑卷快照

LVM还具备有“快照卷”功能,该功能类似于虚拟机软件的还原时间点功能。例如,可以对某一个逻辑卷设备做一次快照,如果日后发现数据被改错了,就可以利用之前做好的快照卷进行覆盖还原。LVM的快照卷功能有两个特点:

[root@localhost ~]# vgdisplay 
  --- Volume group ---
  VG Name               storage
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               39.99 GiB
  PE Size               4.00 MiB
  Total PE              10238
  Alloc PE / Size       30 / 120.00 MiB
  Free  PE / Size       10208 / <39.88 GiB        //容量剩余39.88G
  VG UUID               R3Lgwt-YdRK-3Qhx-vzzt-P4gM-yxbZ-VbeojU

接下来用重定向往逻辑卷设备所挂载的目录中写入一个文件

[root@localhost ~]# echo "hello world" > /mnt/vo/readme.txt
[root@localhost ~]# ls -l /mnt/vo
total 14
drwx------. 2 root root 12288 Apr 18 13:38 lost+found
-rw-r--r--. 1 root root    12 Apr 18 13:48 readme.txt

第1步:使用-s参数生成一个快照卷,使用-L参数指定切割的大小。

另外,还需要在命令后面写上是针对哪个逻辑卷执行的快照操作。强烈建议快照大小和原来的LVM一样大

[root@localhost ~]# lvcreate -L 120M -s -n SNAP /dev/storage/vo
#强烈建议快照大小和原来的LVM一样大,虽然指定大小是120M,并不是创建一个120M大小的快照,除非修改、新增的文件超出120M才会出事情,删除不影响。
  Logical volume "SNAP" created.
[root@localhost ~]# lvdisplay 
  --- Logical volume ---
  LV Path                /dev/storage/vo
  LV Name                vo
  VG Name                storage
  LV UUID                WP06I4-XA8u-mGqT-uFEZ-uhyN-nbrT-ehKMTe
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2019-04-18 13:37:34 +0800
  LV snapshot status     source of
                         SNAP [active]
  LV Status              available
  # open                 1
  LV Size                120.00 MiB
  Current LE             30
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:2

  --- Logical volume ---
  LV Path                /dev/storage/SNAP
  LV Name                SNAP
  VG Name                storage
  LV UUID                WUhSh5-GVZx-VNs5-ChOd-2EKo-50Pj-N5VDFH
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2019-04-18 13:50:24 +0800
  LV snapshot status     active destination for vo
  LV Status              available
  # open                 0
  LV Size                120.00 MiB
  Current LE             30
  COW-table size         120.00 MiB
  COW-table LE           30
  Allocated to snapshot  0.01%
  Snapshot chunk size    4.00 KiB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:5

第2步:在逻辑卷所挂载的目录中创建一个100MB的垃圾文件,然后再查看快照卷的状态。可以发现存储空间占的用量上升了

[root@localhost ~]# dd if=/dev/zero of=/mnt/vo/files count=1 bs=100M
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 3.29409 s, 31.8 MB/s
[root@localhost ~]# lvdisplay 
  --- Logical volume ---
  LV Path                /dev/storage/vo
  LV Name                vo
  VG Name                storage
  LV UUID                WP06I4-XA8u-mGqT-uFEZ-uhyN-nbrT-ehKMTe
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2019-04-18 13:37:34 +0800
  LV snapshot status     source of
                         SNAP [active]
  LV Status              available
  # open                 1
  LV Size                120.00 MiB
  Current LE             30
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:2

  --- Logical volume ---
  LV Path                /dev/storage/SNAP
  LV Name                SNAP
  VG Name                storage
  LV UUID                WUhSh5-GVZx-VNs5-ChOd-2EKo-50Pj-N5VDFH
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2019-04-18 13:50:24 +0800
  LV snapshot status     active destination for vo
  LV Status              available
  # open                 0
  LV Size                120.00 MiB
  Current LE             30
  COW-table size         120.00 MiB
  COW-table LE           30
  Allocated to snapshot  83.71%
  Snapshot chunk size    4.00 KiB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:5

第3步:为了校验SNAP快照卷的效果,需要对逻辑卷进行快照还原操作。在此之前记得先卸载掉逻辑卷设备与目录的挂载。

[root@localhost ~]# umount /mnt/vo
[root@localhost ~]# lvconvert --merge /dev/storage/SNAP 
  Merging of volume storage/SNAP started.
  storage/vo: Merged: 31.39%
  storage/vo: Merged: 100.00%

第4步:快照卷会被自动删除掉,并且刚刚在逻辑卷设备被执行快照操作后再创建出来的100MB的垃圾文件也被清除了

[root@localhost ~]# mount -a
[root@localhost ~]# ls /vo/
lost+found  readme.txt

如果修改的文件超过120M,则不可能还原快照成功

[root@Centos7-VM-1 ~]# lvcreate -L 120M -s -n SNAP /dev/storage/vo
  Logical volume "SNAP" created.
[root@Centos7-VM-1 ~]# dd if=/dev/zero of=/mnt/vo/files count=2 bs=128M
记录了2+0 的读入
记录了2+0 的写出
268435456字节(268 MB)已复制,2.34164 秒,115 MB/秒
[root@Centos7-VM-1 ~]# lvdisplay storage
  --- Logical volume ---
  LV Path                /dev/storage/vo
  LV Name                vo
  VG Name                storage
  LV UUID                TRYAMX-buf7-8SUg-1u5r-BmPo-SE19-O7KpQt
  LV Write Access        read/write
  LV Creation host, time Centos7-VM-1, 2022-06-14 16:00:07 +0800
  LV snapshot status     source of
                         SNAP [INACTIVE]
  LV Status              available
  # open                 1
  LV Size                2.00 GiB
  Current LE             512
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:2

  --- Logical volume ---
  LV Path                /dev/storage/SNAP
  LV Name                SNAP
  VG Name                storage
  LV UUID                u767o6-unbb-ODfU-bVA1-cF03-P9kN-3pVgkY
  LV Write Access        read/write
  LV Creation host, time Centos7-VM-1, 2022-06-15 10:35:22 +0800
  LV snapshot status     INACTIVE destination for vo
  LV Status              available
  # open                 0
  LV Size                2.00 GiB
  Current LE             512
  COW-table size         120.00 MiB
  COW-table LE           30
  Snapshot chunk size    4.00 KiB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:5

[root@Centos7-VM-1 ~]# umount /mnt/vo
[root@Centos7-VM-1 ~]# lvconvert --merge /dev/storage/SNAP
  Unable to merge invalidated snapshot LV storage/SNAP.
# 记得删除快照,以便后续操作
[root@Centos7-VM-1 ~]# lvremove /dev/storage/SNAP
Do you really want to remove active logical volume storage/SNAP? [y/n]: y
  Logical volume "SNAP" successfully removed

6、删除逻辑卷

第1步:取消逻辑卷与目录的挂载关联,删除配置文件中永久生效的设备参数。

[root@localhost ~]# umount /mnt/vo/
[root@localhost ~]# vi /etc/fstab 
#
# /etc/fstab
# Created by anaconda on Mon Apr 15 17:31:00 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=63e91158-e754-41c3-b35d-7b9698e71355 /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

第2步:删除逻辑卷设备,需要输入y来确认操作

[root@localhost ~]# lvremove /dev/storage/vo 
Do you really want to remove active logical volume storage/vo? [y/n]: y
  Logical volume "vo" successfully removed

第3步:删除卷组,此处只写卷组名称即可,不需要设备的绝对路径。

[root@localhost ~]# vgremove storage
  Volume group "storage" successfully removed

第4步:删除物理卷设备

[root@localhost ~]# pvremove /dev/sdb /dev/sdc
  Labels on physical volume "/dev/sdb" successfully wiped.
  Labels on physical volume "/dev/sdc" successfully wiped.

三、软件包管理

安装、查询、卸载

1、软件包的类型

常见二进制包类型

注意!不管是源码包,还是二进制包,安装时都可能会有依赖关系

2、yum

yum是centos上用来下载和安装软件包的一个工具

我们可以使用yum install xxx命令来安装一个软件

但是大家有没有考虑过一个问题?yum工具是去哪里找到这些软件包的呢?

这就不得不提到yum源,所谓的意思就是指这些软件包的来源,也可以成称之为软件仓库

2.1、官方源

一些有名的大厂或者高校都有提供他们整合好的软件仓库

[root@localhost ~]# yum repolist    # 查看默认的源
仓库标识                                 仓库名称
AppStream                                CentOS-8 - AppStream
BaseOS                                   CentOS-8 - Base
extras                                   CentOS-8 - Extras

软件源相关文件存放的位置/etc/yum.repos.d/

[root@localhost ~]# ls /etc/yum.repos.d/
CentOS-Base.repo  CentOS-Debuginfo.repo  CentOS-Media.repo    CentOS-Vault.repo
CentOS-CR.repo    CentOS-fasttrack.repo  CentOS-Sources.repo


# 这里面的一个个.repo文件就是一个个软件仓库

可以尝试添加阿里云软件仓库,下面的是centos7的添加命令

# 先移除原有的所有源
[root@localhost ~]# rm -f /etc/yum.repo.d/*
# 通过curl命令来下载阿里云的源,并且放到/etc/yum.repi.d/下面
[root@localhost ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

[root@localhost ~]# yum clean all
[root@localhost ~]# yum makecache
[root@localhost ~]# yum repolist
2.2、yum常用命令
[root@localhost ~]# yum clean all        # 清空缓存及其他文件
[root@localhost ~]# yum makecache        # 重建缓存
[root@localhost ~]# yum repolist        # 查询可用的仓库

注意:有些命令跟软件包的名字是不同的

1. 通过命令的名字查找是属于哪个软件包
[root@localhost ~]# yum provides pstree

2. 通过配置文件查找属于哪个软件包提供的
[root@localhost ~]# yum provides /etc/ssh/sshd_config

3. 通过search参数查找
[root@localhost ~]# yum search pstree

4. 查看系统中的安装包
[root@localhost ~]# yum list installed            # 查看已安装的所有软件包
[root@localhost ~]# yum list                    # 查看所有可以安装的软件包
[root@localhost ~]# yum list httpd
# yum install xxx

- 安装httpd软件包
[root@localhost ~]# yum install httpd -y
-y:一律允许
[root@localhost ~]# yum install httpd vim nginx -y        # 多个软件包之间用空格隔开
[root@localhost ~]# yum reinstall httpd                    # 重新安装
[root@localhost ~]# yum update httpd                     # 更新软件包的版本-laster
[root@localhost ~]# yum update                             # 更新所有软件包到软件仓库的最新版本

[root@localhost ~]# yum -y install /root/httpd-2.4.6-93.el7.centos.x86_64.rpm     
# 从本地安装
[root@localhost ~]# yum -y install http://centos.ustc.edu.cn/centos/7/os/x86_64/Packages/httpd-2.4.6-93.el7.centos.x86_64.rpm    
# 从URL安装

- 软件包组就是把一些相关的软件包给整合起来,可以打包安装和卸载
[root@localhost ~]# export LANG="en-US.utf8"            切换英文环境
[root@localhost ~]# yum grouplist    # 查看可用的软件包组
Available Environment Groups:    可用环境组
   Minimal Install        最小安装
   Compute Node            计算节点
   Infrastructure Server    基础结构服务器
   File and Print Server    文件和打印服务器
   Basic Web Server        基本Web服务器
   Virtualization Host        虚拟化主机
   Server with GUI        GUI服务器
   GNOME Desktop        桌面桌面
   KDE Plasma Workspaces    KDE等离子工作区
   Development and Creative Workstation    开发创意工作站
Available Groups:        可用组    (表示还未安装的)
   Compatibility Libraries    兼容性库
   Console Internet Tools    控制台Internet工具
   Development Tools        开发工具
   Graphical Administration Tools    图形管理工具
   Legacy UNIX Compatibility    传统的Unix兼容性
   Scientific Support        科学支持
   Security Tools        安全工具
   Smart Card Support        智能卡支持
   System Administration Tools    系统管理工具
   System Management        系统管理
[root@localhost ~]# yum groupinstall "GNOME 桌面"
[root@localhost ~]# yum groupinfo "GNOME 桌面"
[root@localhost ~]# yum -y groupremove "GNOME 桌面"
[root@localhost ~]# yum -y remove httpd                     # 卸载httpd软件包
[root@localhost ~]# yum -y groupremove "GNOME 桌面"        # 卸载软件包组
[root@localhost ~]# yum history
用来查看 yum 软件包管理器执行的历史记录的

[root@localhost ~]# yum history info 4                    # 查看具体某个yum记录的信息
[root@localhost ~]# yum history undo 4                    # 回滚/撤销某个操作
[root@localhost ~]# yum history new                        # 情况所有yum历史记录
2.3、yum自建源

除了使用上述提到的官方源之外,我们也可以自己搭建一个自建源用来为系统提供软件仓库

2.3.1、实验一:本地yum镜像仓库

可以通过安装系统时下载的iso中的软件包来提供本地软件仓库

iso文件中具有一些基础的软件包

- 挂载本地ISO光盘:
[root@localhost ~]# mount /dev/cdrom /media/cdrom

- 清空原有的软件仓库
[root@localhost ~]# rm -f /etc/yum.repos.d/*

- 配置本地yum
[root@localhost ~]# cat > /etc/yum.repos.d/local.repo <<EOF
[base]
name=Centos 7 Release 7.1.1503                
baseurl=file:///media/cdrom                    
enabled=1                                    
gpgcheck=0                                    
EOF

=======================字段解释=========================
-name 软件仓库名字
-baseurl 软件包的存放的地址
-enabled 是否启用这个仓库
-gpgcheck 是否校验软件包
2.3.2、实验二:提供内网服务器软件包更新

一台server1服务器可以访问公网,一台server2服务器无法访问公网

我们可以在这台能够访问公网的服务器上下载好软件包,通过http或者ftp提供给内网中的server2机器安装软件包

server1:

第一步:下载软件包,可以使用--downloadonly选项仅下载不安装

第二部:将软件包放到合适的位置上,并且创建软件数据

[root@localhost ~]# yum clean all                        # 清理缓存和下载的包
[root@localhost ~]# yum update --downloadonly            # 仅下载更新包
[root@localhost ~]# ls /var/cache/yum/x86_64/7/base/packages/    # 查看下载的包

[root@localhost ~]# mkdir /var/ftp/update
[root@localhost ~]# find /var/cache/yum/x86_64/7/updates -iname "*.rpm" -exec cp -rf {} /var/ftp/update/ \;
[root@localhost ~]# yum -y install createrepo            # createrepo用来创建软件包的索引
[root@localhost ~]# createrepo /var/ftp/update/            # 创建软件包的索引

第三步:部署ftp文件服务器,将软件包通过ftp协议共享给sever2

# 部署ftp服务并且启动
[root@localhost ~]# yum -y install vsftpd    
[root@localhost ~]# systemctl start vsftpd

# 关闭防火墙和selinux
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

server2:

在server2上我们编写repo文件,软件的来源是有server1通过ftp服务提供

[root@localhost ~]# rm -rf /etc/yum.repos.d/*.repo    #干掉所有的仓库
[root@localhost ~]# vi /etc/yum.repos.d/update.repo
[update]
name=centos update
baseurl=ftp://192.168.72.134/update            
gpgcheck=0                                    
enabled=1                                    

[root@localhost ~]# yum clean all    
[root@localhost ~]# yum update -y        # 更新测试

3、RPM

在RHEL系列的系统上所使用的软件包为rpm包,上面使用的yum为在线安装软件包。除了在线的安装方法,我们还可以将rpm包下载到本地,然后使用rpm工具来安装这个软件包

[root@atopos ~]# rpm -ivh httpd-2.4.6-93.el7.centos.x86_64.rpm
- httpd:包名
- 2:主版本号
- 4:次版本号
- 6:修订次数,指的是第几次修改bug
- 93:release(第几次发布,指的是简单的修改参数)
- e17:操作系统版本
- x86_64:64位操作系统
[root@atopos ~]# rpm [选项] 软件包
3.1、选项

安装:

查询:

卸载:

升级:

3.2、实例:安装
[root@localhost ~]# rpm -ivh https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/httpd-2.4.6-95.el7.centos.x86_64.rpm

# 或者
[root@localhost ~]# wget https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/httpd-2.4.6-95.el7.centos.x86_64.rpm
[root@localhost ~]# rpm -ivh httpd-2.4.6-95.el7.centos.x86_64.rpm
错误:依赖检测失败:
        /etc/mime.types  httpd-2.4.6-95.el7.centos.x86_64 需要
        httpd-tools = 2.4.6-95.el7.centos  httpd-2.4.6-95.el7.centos.x86_64 需要
        libapr-1.so.0()(64bit)  httpd-2.4.6-95.el7.centos.x86_64 需要
        libaprutil-1.so.0()(64bit)  httpd-2.4.6-95.el7.centos.x86_64 需要

# 需要自己手动解决依赖关系
# 额外安装选项
# --nosignature 不检验软件包的签名
# --force 强制安装软件包
# --nodeps 忽略依赖关系
3.3、实例:查询
[root@atopos ~]# rpm -q vim-enhanced
vim-enhanced-7.4.629-8.el7_9.x86_64
[root@atopos ~]# rpm -qa |grep vim-enhanced
vim-enhanced-7.4.629-8.el7_9.x86_64
[root@atopos ~]# rpm -ql vim-enhanced
/etc/profile.d/vim.csh
/etc/profile.d/vim.sh
/usr/bin/rvim
/usr/bin/vim
/usr/bin/vimdiff
/usr/bin/vimtutor
[root@atopos ~]# rpm -qc openssh-server
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
[root@atopos ~]#
3.4、实例:卸载
[root@atopos ~]# rpm -e vim-enhanced

4、源码包管理

源码包获得途径:

编译源码包所需要的环境

这取决于源码所使用的编程语言和框架等,但是Linux基础软件包一般都是由C语言编写的,所以我们使用较多的编译环境为gccmake等等

yum install -y gcc make
4.1、编译

源码包编译三部曲

- 第一步:
./configure 
#可以指定安装路径,启用或者禁用功能等,最终生成makefile

- 第二步
make 
#按Makefile文件编译。可以加 -j 2 参数使用两个cpu核心进行编译

- 第三步
make install
#按Makefile定义的文件路径安装

make clean
#清除上一次make命令所产生的object文件,要重新执行
configure时,需要执行make clean。
4.2、案例:编译炫酷代码雨
4.2.1、压缩与解压缩

打包一个文件或者目录

tar -cvf archive.tar /path/to/directory

-c 表示创建一个新的归档文件。
-v 表示在压缩过程中显示详细信息(verbose 详细模式)。
-f 指定归档文件的名称。

# 如果要创建gzip压缩包
tar -zcvf archive.tar.gz /path/to/directory

解压缩:

tar -xvf archive.tar

-x 表示解压缩。
-v 表示显示详细信息。
-f 指定要解压缩的归档文件。

# 如果归档文件是使用 gzip 压缩的,比如 archive.tar.gz,则需要添加 -z 选项:

tar -zxvf archive.tar.gz
4.2.2、开始编译
[root@localhost ~]# yum -y install ncurses* gcc gcc-c++
[root@localhost ~]# tar -zxvf cmatrix-1.2a.tar.gz
[root@localhost ~]# cd cmatrix-1.2a
[root@localhost cmatrix-1.2a]# ./configure
[root@localhost cmatrix-1.2a]# make
[root@localhost cmatrix-1.2a]# make install
[root@localhost cmatrix-1.2a]# cmatrix

四、Linux网络管理

1、数据通信基础

image-78

1.1、IP地址

image-79

1.1.1、IP地址的类别

image-80

1.1.2、IP网络通信类型
1.1.3、子网掩码(Netmask)

image-81

image-82

1.1.4、广播地址与网络号

image-83

1.1.5、私有IP地址

image-84

2、DHCP

DHCP(动态主机配置协议),主要用于给设备自动的分配IP地址以及网络信息,以便网络设备能够连接到网络并进行通信

DHCP给设备提供的信息如下:

2.1、DHCP工作过程
  1. 客户端启动时发送 DHCP 发现(DHCPDISCOVER)广播消息,寻找 DHCP 服务器。
  2. DHCP 服务器收到广播消息后,会提供一个未被使用的 IP 地址以及其他网络配置信息(如子网掩码、默认网关、DNS 服务器等),并发送 DHCP 提供(DHCPOFFER)消息给客户端。
  3. 客户端收到一个或多个 DHCP 提供消息后,会选择其中一个 DHCP 服务器提供的 IP 地址,并发送 DHCP 请求(DHCPREQUEST)消息确认。
  4. DHCP 服务器收到客户端的 DHCP 请求消息后,会将该 IP 地址分配给客户端,并发送 DHCP 确认(DHCPACK)消息给客户端。
  5. 客户端收到 DHCP 确认消息后,就可以使用分配到的 IP 地址和其他网络配置参数连接到网络了。
dhclient

我们可以通过抓包软件,捕捉到主机通过DHCP方式获取ip的过程,一共有4个数据包:

image-85

其中每个数据包的作用如下:

Discover

消息是用于客户端向整个内网发送广播,期待DHCP服务器进行回应

这个数据包中的重要内容就是:消息类型,客户端ID,主机名,请求获得的信息

Offer

消息是DHCP服务器对客户的回应

这个消息中会回复对方所需要的所有信息

Request

这个是客户端确认DHCP服务器的消息

这个消息和第一个消息差不多,但是消息类别变为Request,并且会携带请求的IP地址

ACK

DHCP服务器给客户端的最终确认

这个消息和第二个消息差不多,但是消息类型变为ACK

2.2、DHCP续租

DHCP分配的信息是有有效期的,再租约时间快到的时候,如果我们想要继续使用这个地址信息,就需要向DHCP服务器续租

这也是大家虚拟机上IP地址经常发生变化的原因,这是因为虚拟机上默认就是以DHCP的方式获得IP地址的

我们可以查看Linux上的网络配置信息,该信息位于/etc/sysconfig/network-scripts/ifcfg-ens33

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="e4e0ca63-861a-4ea1-89bf-864bf897c381"
DEVICE="ens33"
ONBOOT="yes"
ZONE=public


# 3、可以看到配置中的BOOTPROTO字段是以dhcp来获得IP地址的。我们等会儿在带大家去修改这个网络配置信息

同样从VMware的虚拟网络设置中,也可以看到租约时间相关的内容

image-86

3、DNS(域名解析)

DNS(Domain Name System) 是一套从域名到IP的映射的协议

在网络世界中,如果我们想要给某个机器,或者是某个网站去发送一个数据,都需要通过IP地址来找到对方,比如我们想要使用百度来搜索东西,就需要知道百度的IP地址,换句话说只要知道了百度的IP地址,我们就可以访问到百度

但是IP地址不易记忆,不可能记住每一个网站的IP地址是什么,于是早期的搞IT的那帮人研发出一个叫做主机名的东西。

最开始人们把IP和主机名的的对应关系记录在本地,这个文件目前在windows系统的C:\Windows\System32\drivers\etc\hosts中。但是后面发现并不好用,而且需要经常手动更新这个文件。类似于黄历

随着主机名越来越多,hosts文件不易维护,所以后来改用域名解析系统DNS

3.1、域名

主域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称。 例如:http://www.baidu.com(域名使用.连接

3.2、常见的域名解析服务器

114.114.114.114

114.114.115.115

这是国内用户量数一数二的 dns 服务器,该 dns 一直标榜高速、稳定、无劫持、防钓鱼。

8.8.8.8

8.8.4.4

......

可以理解为由这些服务器帮我们记录的域名和IP的对应关系,我们访问域名的时候去找这些dns服务器询问该域名对应的IP地址,当然,除了上述提到的这些dns服务器,三大运营商也提供了dns解析服务

3.3、域名解析的过程
  1. 浏览器发起域名解析,首先查询浏览器缓存,如果没有,就查询hosts文件,如果没有就提出域名解析请求
  2. 客户机提出域名解析请求,并将该请求发送给本地的域名服务器。
  3. 当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。
  4. 如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址。
  5. 本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
  6. 重复第四步,直到找到正确的纪录。
  7. 本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机

4、配置网络服务

4.1、图形化配置网络

使用nmtui命令来配置网络

[root@localhost ~]# nmtui
# 4、可以将环境变量改成中文
export LANG="zh_CN.UTF-8"
# 5、改回中文是LANG="en_US.UTF-8"

image-87

image-88

image-89

image-90

image-91

image-92

4.2、命令行配置网络
# 6、修改网卡配置文件
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=7cb2fd3e-61dd-4856-87fa-c6db7ec0169b
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.91.128
PREFIX=24
# 7、NETMASK= 255.255.255.0
GATEWAY=192.168.91.2
DNS1=114.114.114.114
DNS2=114.114.115.115

当修改完Linux系统中的服务配置文件后,并不会对服务程序立即产生效果。要想让服务程序获取到最新的配置文件,需要手动重启相应的服务,之后就可以看到网络畅通了

[root@localhost ~]# systemctl restart network
[root@localhost ~]# ping baidu.com
4.2.1、动态展示:

gif-93

4.2.2、网卡配置文件参数
解释 参数
设备类型 TYPE=Ethernet
地址分配模式 BOOTPROTO=static(静态)/dhcp
网卡名称 NAME=ens33
是否启动 ONBOOT=yes
IP地址 IPADDR=192.168.99.136
子网掩码 NETMASK=255.255.255.0
网关地址 GATEWAY=192.168.88.2
DNS地址 DNS1=114.114.114.114
systemctl restart network
4.3、nmcli 工具详解

nmcli命令是redhat7或者centos7之后的命令,该命令可以完成网卡上所有的配置工作,并且可以写入 配置文件,永久生效

[root@localhost ~]# nmcli device status 
DEVICE   TYPE      STATE      CONNECTION         
ens33    ethernet  connected  ens33              
ens37    ethernet  connected  Wired connection 1 
docker0  bridge    connected  docker0            
lo       loopback  unmanaged  --
[root@localhost ~]# nmcli connection show
NAME                UUID                                  TYPE      DEVICE  
docker0             ca6db5d5-a1a1-478d-8592-112d5283069d  bridge    docker0 
ens33               122f2554-8762-40c0-8fb7-f92275a6b358  ethernet  ens33   
Wired connection 1  1099d5fd-29be-3f24-92d3-5f47c981fbae  ethernet  ens37
[root@localhost ~]# mcli con mod "ens33" ipv4.addresses 192.168.88.140/24 ipv4.gateway 192.168.88.2 ipv4.dns "8.8.8.8,8.8.4.4" ipv4.method manual
[root@localhost ~]# nmcli connection up ens33
[root@localhost ~]# nmcli connection down ens33
[root@localhost ~]# nmcli connection add type ethernet con-name dhcp_ens33 ifname ens33
[root@localhost ~]# nmcli connection delete dhcp_ens33
成功删除连接 'dhcp_ens33'(37adadf4-419d-47f0-a0f6-af849160a4f7)。
4.3.1、net-tools
默认路由:
route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.1.2

5、ifconfig

安装:yum install -y net-tools

5.1、语法
ifconfig [network_interface]
         [down|up]
         [add <address>]
         [del <address>]
         [hw <type> <hw_address>]
         [io_addr <I/O_address>]
         [irq <IRQ>]
         [media <media_type>]
         [mem_start <memory_address>]
         [metric <number>]
         [mtu <bytes>]
         [netmask <netmask>]
         [tunnel <address>]
         [-broadcast <address>]
         [-pointopoint <address>]
         [<IP_address>]
5.2、选项说明:
5.3、实例
[root@localhost cmatrix-1.2a]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.88.136  netmask 255.255.255.0  broadcast 192.168.88.255
        inet6 fe80::a49c:12c9:1ebd:8fb2  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:cb:d5:1a  txqueuelen 1000  (Ethernet)
        RX packets 122441  bytes 178564616 (170.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13762  bytes 1315614 (1.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost ~]# ifconfig ens33 down
[root@localhost ~]# ifconfig ens33 up
[root@localhost ~]# ifconfig eth0 192.168.1.56 
//给eth0网卡配置IP地址
[root@localhost ~]# ifconfig eth0 192.168.1.56 netmask 255.255.255.0 
// 给eth0网卡配置IP地址,并加上子掩码
[root@localhost ~]# ifconfig eth0 192.168.1.56 netmask 255.255.255.0 broadcast 192.168.1.255
// 给eth0网卡配置IP地址,加上子掩码,加上个广播地址
[root@localhost ~]# ifconfig eth0 mtu 1500 
//设置能通过的最大数据包大小为 1500 bytes

五、防火墙与selinux

1、防火墙相关概念

主要作用:保护内部的网络、主机、服务的安全等

我们常听到的防火墙有很多不同的类型,从大的角度来看,主要是分为硬件防火墙和软件防火墙。

硬件防火墙:

image-94

软件防火墙:

软件防火墙就是通过软件来对数据包,流量请求进行过滤等,属于从软件层面保护系统的安全。如我们熟知的360,金山毒霸,火绒安全等等。

当然防火墙除了软件及硬件的分类,也可以对数据封包的取得方式来分类,可分为代理服务器(Proxy)封包过滤机制(IP Filter)

相较于企业内网,外部的公网环境更加恶劣,罪恶丛生。在公网与企业内网之间充当保护屏障的防火墙虽然有软件或硬件之分,但主要功能都是依据策略对穿越防火墙自身的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后防火墙使用预先定制的策略规则监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。这样一来,就可以保证仅有合法的流量在企业内网和外部公网之间流动了

2、RHEL/Centos系统

对于RHEL、Centos等红帽系Linux操作系统,我们常用到的防火墙软件主要有iptables和firewalld

不过,对于Linux而言,其实Iptables和firewalld服务不是真正的防火墙,只是用来定义防火墙规则功能的"防火墙管理工具",将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能。

3、iptables

iptables过滤数据包的方式:

3.1、五链

iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链,叫规则链。 规则链则依据处理数据包的位置不同分类:

3.2、四表

iptables中的规则表是用于容纳规则链,规则表默认是允许状态的,那么规则链就是设置被禁止的规则,而反之如果规则表是禁止状态的,那么规则链就是设置被允许的规则。

image-95

规则表的先后顺序:raw→mangle→nat→filter

规则链的先后顺序:

image-96

3.3、基本选项和用法
3.3.1、选项
参数 作用
-P 设置默认策略:iptables -P INPUT (DROP\ ACCEPT)类似于黑白名单
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾加入新规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
-d 匹配目标地址
-i 网卡名称 匹配从这块网卡流入的数据
-o 网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如tcp,udp,icmp
--dports num 匹配目标端口号
--sports num 匹配来源端口号

为了防止firewalld与iptables的冲突,建议在学习iptables的时候,先关闭firewalld

3.3.2、简单用法(初体验)

案例:现在有一个web服务提供网站访问,默认情况下是允许被我们的主机访问的,我们可以尝试通过设置iptables的策略,来禁止别人访问该网站

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# yum install -y epel-release
# 安装扩展源,以便安装下面的web服务器nginx
[root@localhost ~]# yum install -y nginx
# 安装web服务器
[root@localhost ~]# systemctl start nginx
# 启动web服务器

打开浏览器访问你的IP地址,可以看到有一个网站(nginx提供的默认页面)

image-97

[root@localhost ~]# iptables -A INPUT -p tcp --dport 80 -j DROP
# 对INPUT链上增加一个策略,丢弃掉来自80端口tcp协议的请求报文

image-98

[root@localhost ~]# iptables -vnL INPUT --line-numbers
Chain INPUT (policy ACCEPT 62 packets, 4776 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       75  3900 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
3.4、iptables规则说明
3.5、iptables高级用法

image-99

-t table

指定表

-j

设置处理策略

-p

指定数据包协议类型

3.5.1、增加规则

案例一:屏蔽来自其他主机上的ping包

# 正常通过cmd去ping我们的虚拟机的IP地址
C:\Users\Atopos>ping 192.168.88.136

正在 Ping 192.168.88.136 具有 32 字节的数据:
来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64

192.168.88.136  Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 0ms,平均 = 0ms


# 在虚拟机上屏蔽来自我们物理机的ping包,注意物理机的IP的地址为:192.168.xxx.1
# ping命令是基于icmp协议的,所以这里对类型为icmp协议的数据包进行丢弃
[root@localhost ~]# iptables -A INPUT -s 192.168.88.1 -p icmp -j DROP

# 丢弃以后ping测试:
C:\Users\Atopos>ping 192.168.88.136

正在 Ping 192.168.88.136 具有 32 字节的数据:
请求超时。

# 注意,DROP和REJECT有一定的区别,DROP为丢弃数据包,不给予对方回应,所以对方就会一直等待。REJECT是拒绝对方,会将拒绝的数据包发给对方,对方就会知道我们拒绝的访问。
# 如果改成REJECT现象是:
C:\Users\Atopos>ping 192.168.88.136

正在 Ping 192.168.88.136 具有 32 字节的数据:
来自 192.168.88.136 的回复: 无法连到端口。
来自 192.168.88.136 的回复: 无法连到端口。
来自 192.168.88.136 的回复: 无法连到端口。
来自 192.168.88.136 的回复: 无法连到端口。

192.168.88.136  Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失)`其他用法`
[root@localhost ~]# iptables -A INPUT -s 192.168.88.100 -j ACCEPT
# 目标来自 192.168.88.100 这个 IP 的封包都予以接受
[root@localhost ~]# iptables -A INPUT -s 192.168.88.0/24 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -s 192.168.88.10 -j DROP
# 192.168.88.0/24 可接受,但 192.168.88.10 丢弃

案例二:屏蔽Linux系统中的远程链接服务(sshd),使得我们无法通过MobaXterm连接到虚拟机上

[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
# ssh服务所用的协议类型为tcp协议,端口号为22
# 所以我们将来自22端口上的tcp协议数据包给拒绝

当敲完这个命令以后,你的远程连接就会中断了,可以在VMware中的虚拟机终端上删除这个规则,就恢复了

删除命令:iptables -D INPUT -p tcp --dport 22 -j REJECT

3.5.2、查看规则
[root@localhost ~]# iptables [-t tables] [-L] [-nv]
参数:
-t    后面接table,例如nat或filter,如果省略,默认显示filter
-L    列出目前的table的规则
-n    不进行IP与主机名的反查,显示信息的速度会快很多
-v    列出更多的信息,包括封包数,相关网络接口等
--line-numbers 显示规则的序号
[root@localhost ~]# iptables -vnL INPUT -t filter --line-numbers
[root@localhost ~]# iptables -nL -t nat
[root@localhost ~]# iptables -nL -t mangle
[root@localhost ~]# iptables -nL -t raw
3.5.3、删除规则

通过上面学习的查看规则的方法,先查找到你想要删除的规则

# 举例
# 查看nat表上所有链的规则
[root@localhost ~]# iptables -t nat -nL --line-numbers
# 查看filter(默认表)上所有链的规则
[root@localhost ~]# iptables -nL --line-numbers
删除input链上num为1的规则
[root@localhost ~]# iptables -D INPUT 1
[root@localhost ~]# iptables -D INPUT -p tcp --dport 80 -j DROP
[root@localhost ~]# iptables -F
3.5.4、修改规则

方案一:通过iptables -D删除原有的规则后添加新的规则

方案二:通过iptables -R可以对具体某一个num的规则进行修改

# 修改端口的为8080
[root@localhost ~]# iptables -R INPUT 1 -p tcp --dport 8080 -j ACCEPT

# 针对具体的某一个表和链进行修改
# 将8080修改回80
[root@localhost ~]# iptables -t filter -R INPUT 1 -p tcp --dport 80 -j ACCEPT
3.6、自定义链

iptables中除了系统自带的五个链之外,还可以自定义链,来实现将规则进行分组,重复调用的目的

具体方法见如下案例:

案例一:我们自定义一个WEB_CHAIN链,专门管理跟web网站相关的规则策略

# 1. 先查看我们现有的系统链
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# 2. 添加WEB_CHAIN自定义链,并且查看
[root@localhost ~]# iptables -t filter -N web_chain
[root@localhost ~]# iptables -L
..........
Chain web_chain (0 references)
target     prot opt source               destination

# 3. 可以通过-E参数修改自定义链
[root@localhost ~]# iptables -t filter -E web_chain WEB_CHAIN
[root@localhost ~]# iptables -L
.........
Chain WEB_CHAIN (0 references)
target     prot opt source               destination
# 可以看到名字已经发生变化了

# 4. 向我们创建的自定义链中添加规则,开放80端口上的服务
[root@localhost ~]# iptables -t filter -A WEB_CHAIN -p tcp -m multiport --dports 80,443 -j ACCEPT

# 5. 将自定义链关联到系统链上才能使用
# 因为数据包只会经过上面讲过的五个系统链,不会经过我们的自定义链,所以需要把自定义链关联到某个系统链上

# 我们允许来自IP:192.168.88.1的访问,随后拒绝其他所有的访问,这样,只有192.168.88.1的主机可以访问这个网站
[root@localhost ~]# iptables -t filter -A INPUT -s 192.168.88.1 -j WEB_CHAIN
[root@localhost ~]# iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443 -j DROP
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
WEB_CHAIN  all  --  192.168.88.1         anywhere
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
Chain WEB_CHAIN (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http

访问测试:

image-100

- 删除自定义链

# 先清空自定义链上的规则
[root@localhost ~]# iptables -t filter -F WEB_CHAIN
# 然后通过-X选项删除自定义链
[root@localhost ~]# iptables -t filter -X WEB_CHAIN
3.7、其他用法(模块)
[root@localhost ~]# iptables -A INPUT -d 172.16.1.100 -p tcp --dport 80 -m iprange --src-range 172.16.1.5-172.16.1.10 -j DROP
[root@localhost ~]# iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --from 62  --string "google" -j REJECT

案例:

[root@localhost ~]# yum -y install httpd
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl enable httpd
[root@localhost ~]# echo "<h1>hello world</h1>" > /var/www/html/index.html
[root@localhost ~]# iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --string "world" -j REJECT
#用浏览器刷新页面发现打不开
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp spt:80 STRING match  "world" ALGO name bm TO 65535 reject-with icmp-port-unreachable

[root@localhost ~]# echo "<h1>hello XHZ</h1>" > /var/www/html/index.html
# 此时浏览器打开成功
[root@localhost ~]# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sat,Sun  -j DROP

-m time --timestart 14:30 --timestop 18:30 --weekdays Sat,Sun:在指定的时间范围内生效,即从周六到周日的14:30到18:30之间。这表示该规则只在这个时间段内生效

- 该规则的作用是在指定时间范围内,阻止来自172.16.0.0/16网段源IP地址、目标IP地址为172.16.100.10、目标端口为80的TCP数据包进入系统
[root@localhost ~]# iptables -A INPUT -d 172.16.100.10 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT

-m connlimit --connlimit-above 2:使用连接限制模块,限制连接数超过2的数据包。这表示如果同一源IP地址的连接数超过2个,将匹配到该规则

- 该规则的作用是限制目标IP地址为172.16.100.10、目标端口为22的数据包,如果同一源IP地址的连接数超过2个,则拒绝回复该数据包。这个规则可以用于防止对SSH服务的暴力破解攻击,限制来自同一IP地址的并发连接数

案例:

[root@localhost ~]# iptables -A INPUT -s 192.168.88.0/24 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT

#此时登第三个终端,会登不上
[root@localhost ~]# iptables -nL --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       tcp  --  172.16.0.0/16        172.16.100.10        tcp dpt:80 TIME from 14:30:00 to 18:30:00 on Sat,Sun UTC
2    REJECT     tcp  --  192.168.88.0/24      0.0.0.0/0            tcp dpt:22 #conn src/32 > 2 reject-with icmp-port-unreachable

[root@Centos7-VM-1 ~]# iptables -D INPUT 2
iptables -A INPUT -p icmp -m limit --limit-burst 10 --limit 20/minute -j ACCEPT
iptables -A INPUT -p icmp  -j REJECT

--limit-burst 10:设置允许的初始突发量为10个数据包。
--limit 20/minute:设置平均速率为20个数据包/分钟,即每分钟允许通过的ICMP数据包数量为20个。

- 该规则的作用是限制ICMP数据包的速率,允许初始突发量为10个数据包,以后每分钟最多允许通过20个ICMP数据包。匹配到的ICMP数据包将被接受,其他超出限制的数据包将被丢弃。这个规则可以用于控制对系统的ICMP流量,以避免过多的ICMP请求对系统造成负载过大的影响
使用 --tcp-flags 选项可以根据tcp包的标志位进行过滤。
[root@localhost ~]# iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
[root@localhost ~]# iptables -A FROWARD -p tcp --tcp-flags ALL SYN,ACK
上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。
[root@localhost ~]# iptables -A FORWARD -p tcp --syn
选项--syn相当于"--tcp-flags SYN,RST,ACK SYN"的简写。
[root@localhost ~]# iptables -A INPUT -m 模块名 --state 状态
参数:
-m    iptables的模块
        state: 状态检查
        mac:网卡硬件地址
--state     连接追踪中的状态:
        NEW: 新建立一个会话
        ESTABLISHED:已建立的连接
        RELATED: 有关联关系的连接
        INVALID: 无法识别的连接
[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT    
-m state --state NEW:使用状态模块,匹配数据包的连接状态为NEW,即新建的连接。
- 该规则的作用是允许进入系统的TCP数据包,目标端口为22(SSH服务),且连接状态为NEW(新建的连接)。这个规则用于允许建立新的SSH连接,而拒绝已经建立的或结束的连接

[root@localhost ~]# iptables -A INPUT -m mac --mac-source 00:0C:29:56:A6:A2 -j ACCEPT
-m mac --mac-source 00:0C:29:56:A6:A2:使用MAC模块,匹配源MAC地址为00:0C:29:56:A6:A2的数据包
- 该规则的作用是允许源MAC地址为00:0C:29:56:A6:A2的数据包进入系统。这个规则可以用于根据MAC地址限制网络访问,只允许特定的MAC地址通过防火墙进入系统
3.8、规则的保存与恢复
# 保存到文件中
[root@localhost ~]# iptables-save > /etc/sysconfig/iptables-config
# 从文件中导入规则
[root@localhost ~]# iptables-restore < /etc/sysconfig/iptables-config
[root@localhost ~]# yum -y install iptables-services
[root@localhost ~]# systemctl stop iptables-services
[root@localhost ~]# systemctl disable iptables-services
3.9、NAT(地址转换协议)

网络地址转换 NAT(Network Address Translation),被广泛应用于各种类型 Internet 接入方式和各种类型的网络中。原因很简单,NAT 不仅完美地解决了 IP 地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。默认情况下,内部 IP 地址是无法被路由到外网的,内部主机 10.1.1.1 要与外部 Internet通信,IP 包到达 NAT 路由器时,IP 包头的源地址 10.1.1.1 被替换成一个合法的外网 IP,并在 NAT 转发表中保存这条记录。当外部主机发送一个应答到内网时,NAT 路由器收到后,查看当前 NAT 转换表,用 10.1.1.1 替换掉这个外网地址。NAT 将网络划分为内部网络和外部网络两部分,局域网主机利用 NAT 访问网络时,是将局域网内部的本地地址转换为全局地址(互联网合法的 IP 地址)后转发数据包;

3.9.1、案例一:内网数据代理及服务映射

背景:现在有两个服务器server1和server2,server1是可以上网的,server2是不可以上网的,我们需要在server1上配置NAT来让server2通过server1去访问外网,同样我们也可以通过server1来访问位于server2服务器上的内部网站

image-101

环境准备:

两台虚拟机,可以克隆一个出来,然后server1添加一张仅主机的网卡。为了模拟server2不能上网的情况,将server2上原有的网卡改成仅主机模式。

由于server2的网卡修改成仅主机以后无法通过yum部署httpd,所以我们先在server2上部署一个Web网站

[root@localhost ~]# yum install -y httpd
[root@localhost ~]# systemctl start httpd
# 确保关闭了firewalld,防止firewalld造成干扰
[root@localhost ~]# systemctl stop firewalld

# 检查80端口是否启动
[root@localhost ~]# ss -nlt
State      Recv-Q Send-Q               Local Address:Port                              Peer Address:Port
LISTEN     0      128                              *:22                                           *:*
LISTEN     0      100                      127.0.0.1:25                                           *:*
LISTEN     0      128                             :::80                                          :::*
LISTEN     0      128                             :::22                                          :::*
LISTEN     0      100                            ::1:25                                          :::*

server1:

image-102

server2:

image-103

第一步:配置仅主机模式网卡的IP地址,其中:

server1:

IP:192.168.12.1/24

server2:

IP:192.168.12.2/24

网关:192.168.12.1 # 网关指向server1的地址

dns:114.114.114.114

第二步:在server1的Linux内核中开启数据转发功能

- 开启数据转发
[root@localhost ~]# echo "net.ipv4.ip_forward=1" >> /usr/lib/sysctl.d/50-default.conf
[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1
[root@localhost ~]# sysctl -p

或者:
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

禁止数据转发:
[root@localhost ~]# echo 0 > /proc/sys/net/ipv4/ip_forward

第三步:访问测试

ping baidu.com

3.9.2、配置SNAT让server2能够网上冲浪

server1上操作:

[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j SNAT --to-source 192.168.88.136

- POSTROUTING:数据包出口链
- SNAT:将源地址进行转发

也可以使用如下写法(PAT):
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j MASQUERADE

server2上测试网络连通性:

ping baidu.com
3.9.3、配置DNAT使得可以访问server2中的内部网站
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.12.2:80

# 在PREROUTING链上将来自8080端口上的访问转发到内网中的192.168.88.12.2上的80端口

`访问测试:`
浏览器中输入:192.168.88.136:8080

- 扩展案例:
- 配置DNAT来映射server2上的ssh服务
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 3322 -j DNAT --to-destination 192.168.12.2:22

`连接测试:`
ssh root@192.168.88.136 -p 3322
3.10、案例二:转发本地端口
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 6666 -j REDIRECT --to-port 22
# 此时连接6666端口,iptables会帮我们转发到22端口

4、firewalld

firewalld是CentOS 7.0新推出的管理netfilter的用户空间软件工具

并且支持划分区域zone,每个zone可以设置独立的防火墙规则

区域 默认策略规则
public 默认区域,对应普通网络环境。允许选定的连接,拒绝其他连接
drop 所有传入的网络包都会被直接丢弃,不会发送任何响应
block 所有传入的网络包会被拒绝,并发送拒绝信息
external 用于路由/NAT流量的外部网络环境。与public类似,更适用于网关、路由器等处理外部网络流量的设备
dmz 隔离区域,只允许选定的连接,适用于部署公开服务的网络区域,如 Web 服务器,可以最大限度地降低内部网络的风险
work 适用于工作环境,开放更多服务,如远程桌面、文件共享等。比 public 区域更加信任
home 适用于家庭环境,开放更多服务,比如默认情况下会开放一些如:3074端口(Xbox)、媒体、游戏数据等待
trusted 信任区域,允许所有连接
4.1、管理工具-firewall-cmd
参数 作用
--get-default-zone 查询默认的区域名称
--set-default-zone=<区域名称> 设置默认的区域,使其永久生效
--get-zones 显示可用的区域
--get-services 显示预先定义的服务
--get-active-zones 显示当前正在使用的区域与网卡名称
--add-source= 将源自此IP或子网的流量导向指定的区域
--remove-source= 不再将源自此IP或子网的流量导向某个指定区域
--add-interface=<网卡名称> 将源自该网卡的所有流量都导向某个指定区域
--change-interface=<网卡名称> 将某个网卡与区域进行关联
--list-all 显示当前区域的网卡配置参数、资源、端口以及服务等信息
--list-all-zones 显示所有区域的网卡配置参数、资源、端口以及服务等信息
--add-service=<服务名> 设置默认区域允许该服务的流量
--add-port=<端口号/协议> 设置默认区域允许该端口的流量
--remove-service=<服务名> 设置默认区域不再允许该服务的流量
--remove-port=<端口号/协议> 设置默认区域不再允许该端口的流量
--reload 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则
--panic-on 开启应急状况模式
--panic-off 关闭应急状况模式
--permanent 设定的当前规则保存到本地,下次重启生效
4.2、简单用法(初体验)

为了防止之前配置过的iptables规则导致与firewalld策略冲突,建议恢复快照后再开始练习

通过web服务部署一个网站,然后访问测试

[root@localhost ~]# yum -y install httpd
[root@localhost ~]# systemctl start httpd

在浏览器中输入192.168.88.136访问测试发现,我们无法访问此网站,这是因为默认情况下,firewalld是出于开启的状态,并且默认区域为public。在public区域中,除了部分系统服务,其他服务的流量一律是禁止的。

# 查看firewalld是否启用,可以看到当前是出于actice的状态
[root@localhost ~]# systemctl status firewalld firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since  2024-05-23 15:39:56 CST; 28min ago
     Docs: man:firewalld(1)
 Main PID: 6264 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─6264 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

# 查看当前所在的区域
[root@localhost ~]# firewall-cmd --get-default-zone
public
# 查看当前网卡所在的区域
[root@localhost ~]# firewall-cmd --get-zone-of-interface=ens33
public

# 查询public区域是否允许请求SSH或者HTTP协议的流量
[root@localhost ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@localhost ~]# firewall-cmd --zone=public --query-service=http
no

`可以看出,在public区域中,默认是禁止来自http协议的请求数据包的`

修改firewalld策略,使得我们可以访问到刚刚部署的网站

- 方法一:针对服务协议类型进行放行
# 临时放行
[root@localhost ~]# firewall-cmd --zone=public --add-service=http
# 可以加上--permanent实现永久放行
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=http

- 方法二:针对服务具体访问请求的端口号进行放行
[root@localhost ~]# firewall-cmd --zone=public --add-port=80/tcp
success
# 同样也可以加上--permanent实现永久放行

以上方法二选一,然后访问测试

image-104

取消放行

[root@localhost ~]# firewall-cmd --zone=public --remove-service=http --permanent
success
4.3、其他用法
[root@localhost ~]# firewall-cmd --set-default-zone=public
Warning: ZONE_ALREADY_SET: public
success
[root@localhost ~]# firewall-cmd --get-default-zone
public
[root@localhost ~]# firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources:
  services: ssh dhcpv6-client
  ports: 80/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@localhost ~]# firewall-cmd --panic-on
# 取消紧急模式
[root@localhost ~]# firewall-cmd --panic-off
# 临时生效
[root@localhost ~]# firewall-cmd --zone=public --add-service=http
success
# 永久生效,加了--permanent所进行的更改,会被写入到配置文件中,下次开机任然生效
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=http
success
# 使得最近对防火墙规则变更或者所作的修改生效
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]# firewall-cmd --zone=public --query-service=http
yes

-配置文件路径
/etc/firewalld/zones/public.xml
/etc/firewalld/direct.xml
/etc/firewalld/firewalld.conf
[root@localhost ~]# firewall-cmd --zone=public --remove-service=https --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
# 可以指定要开放端口的范围
[root@localhost ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
success
[root@localhost ~]# firewall-cmd --zone=public --list-ports
8080-8081/tcp
4.4、流量转发

通过firewalld,将用户访问服务器上6666端口的流量转发到22端口上,实现本地端口映射。我们就可以使用6666端口来远程连接到服务器

[root@localhost ~]# firewall-cmd --permanent --add-forward-port=port=6666:proto=tcp:toport=22
success
[root@localhost ~]# firewall-cmd --reload

连接测试:

C:\Users\Atopos>ssh root@192.168.88.136 -p 6666
root@192.168.88.136 password:
Last login: Thu May 23 21:20:38 2024 from 192.168.88.1
[root@localhost ~]#
可以看到我们通过6666端口成功连接到我们的虚拟机

image-105

4.5、firewalld富规则

富规则是 firewalld 提供的一种灵活且强大的防火墙规则配置方式。与简单的端口和服务规则不同,富规则支持更复杂的匹配条件和操作。

使用富规则,可以实现复杂的防火墙策略,例如:

富规则的配置方法:

firewall-cmd --permanent --add-rich-rule='<rich_rule_definition>'

需要注意的是,富规则的语法比较复杂,使用时务必仔细检查,以免引入安全隐患。同时,在修改完成后记得执行 firewall-cmd --reload 命令,让更改生效

其中rule部分的语法如下:

rule [family="<family>"] [source address="<address>"][source port="<port>"] [destination address="<address>"][destination port="<port>"] [protocol value="<protocol>"] [icmp-block-inversion][forward-port port="<port>" protocol="<protocol>" to-port="<port>"][masquerade][log [prefix="<prefix>"] [level="<level>"] [limit value="<value>"] [accept][reject][drop]

其中各个选项的含义如下:

由于firewalld中的富规则比较复杂,我们从以下几个案例中来简单学习富规则的一些用法即可

案例一:允许某个IP地址访问系统中的Web网站服务

[root@localhost ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.88.1" port port="80" protocol="tcp" accept'
[root@localhost ~]# firewall-cmd --reload

这条规则允许来自 192.168.88.1 的 IPv4 流量访问 80 端口的 Web 服务

案例二:限制某个区域内的 SSH 连接次数

[root@localhost ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.88.0/24" port port="22" protocol="tcp" limit value="3/m" accept'
[root@localhost ~]# firewall-cmd --reload

这条规则允许 192.168.88.0/24 网段内的 IPv4 流量访问 22 端口的 SSH 服务,但是限制每分钟最多 3 次连接

案例三:使用富规则配置将6666端口上的访问转发到22端口上

[root@localhost ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" forward-port port="6666" protocol="tcp" to-port="22"'
[root@localhost ~]# firewall-cmd --reload

这条规则将 6666 端口的 TCP 流量转发到 22 端口

注意:富规则的语法比较复杂,但是可以让您更精细地控制防火墙规则。通过组合不同的条件,您可以实现更复杂的防火墙策略。使用富规则时,请务必仔细检查语法和规则是否符合您的需求,以免引入安全隐患

5、服务访问控制

TCP Wrappers是一种用于网络服务访问控制的工具,它使用配置文件中的规则来决定是否允许或拒绝对特定网络服务的访问。控制列表由两个主要文件组成:/etc/hosts.allow和/etc/hosts.deny。这些文件包含服务和客户端的规则,用于控制服务的访问权限

TCP Wrappers服务的控制列表文件中常用的参数

客户端类型 示例 满足示例的客户端列表
单一主机 192.168.10.10 IP地址为192.168.10.10的主机
指定网段 192.168.10. IP段为192.168.10.0/24的主机
指定网段 192.168.10.0/255.255.255.0 IP段为192.168.10.0/24的主机
指定主机名称 www.eagleslab.com 主机名称为www.eagleslab.com的主机
指定所有客户端 ALL,* 所有主机全部包括在内

在配置TCP Wrappers服务时需要遵循两个原则:

/etc/hosts.deny:该文件包含拒绝访问网络服务的规则。如果没有在hosts.allow文件中找到允许访问的规则,TCP Wrappers将检查hosts.deny文件以确定是否拒绝访问。以下规则拒绝所有客户端访问SSH服务:

[root@localhost ~]# vim /etc/hosts.deny 
#
# hosts.deny    This file contains access rules which are used to
#        deny connections to network services that either use
#        the tcp_wrappers library or that have been
#        started through a tcp_wrappers-enabled xinetd.
#
#        The rules in this file can also be set up in
#        /etc/hosts.allow with a 'deny' option instead.
#
#        See 'man 5 hosts_options' and 'man 5 hosts_access'
#        for information on rule syntax.
#        See 'man tcpd' for information on tcp_wrappers
#
#
sshd:*
[c:\~]$ ssh root@192.168.88.136


Connecting to 192.168.88.136:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(192.168.88.136:22) at 16:35:31.

/etc/hosts.allow:该文件包含允许访问网络服务的规则。每个规则占据一行,有两个主要部分:服务和允许访问的客户端。例如,以下规则允许192.168.88.0/24网段访问SSH服务:

[root@localhost ~]# vim /etc/hosts.allow 
#
# hosts.allow    This file contains access rules which are used to
#        allow or deny connections to network services that
#        either use the tcp_wrappers library or that have been
#        started through a tcp_wrappers-enabled xinetd.
#
#        See 'man 5 hosts_options' and 'man 5 hosts_access'
#        for information on rule syntax.
#        See 'man tcpd' for information on tcp_wrappers
#
sshd:192.168.136.

6、SELinux安全子系统

SELinux 是一个强大的访问控制机制,它建立在 Linux 内核之上,为系统提供了更细粒度的安全策略控制。与传统的基于用户/组的访问控制不同,SELinux 采用基于角色(role)和类型(type)的强制访问控制(Mandatory Access Control, MAC)。简单来讲,SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)

SELinux 的主要特点包括:

  1. 基于策略的安全访问控制:SELinux 通过预先定义的安全策略来控制系统进程和资源的访问权限,而不是依赖于用户/组的身份
  2. 最小特权原则:SELinux 遵循"最小特权"的安全原则,即只授予程序运行所需的最小权限,大大降低了系统被攻击者利用的风险
  3. 灵活的策略配置:SELinux 提供了丰富的策略配置选项,可以根据系统的具体需求进行定制和调整
  4. 审计能力:SELinux 内置了强大的审计日志记录功能,可以帮助管理员快速发现和分析系统安全事件

SELinux 的主要工作模式包括:

6.1、调整SELinux的模式

临时调整:

# 查看当前SELinux的模式
[root@localhost ~]# getenforce
Enforcing

# 临时调整为Permissive
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce
Permissive
[0]为Permissive模式,只记录行为,不阻止
[1]为Enforcing模式

临时调整只在当前状态有效,如果系统重启,将会恢复为默认的Enforcing模式

永久调整:

通过编辑配置文件/etc/selinux/config中的SELINUX字段来更改SELinux的模式

[root@localhost ~]# vim /etc/selinux/config 
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
6.2、自主访问控制(DAC)

在没有使用 SELinux 的操作系统中,决定一个资源是否能被访问的因素是:某个资源是否拥有对应用户的权限(读、写、执行)

只要访问这个资源的进程符合以上的条件就可以被访问

而最致命问题是,root 用户不受任何管制,系统上任何资源都可以无限制地访问

这种权限管理机制的主体是用户,也称为自主访问控制(DAC)

6.3、强制访问控制(MAC)

在使用了 SELinux 的操作系统中,决定一个资源是否能被访问的因素除了上述因素之外,还需要判断每一类进程是否拥有对某一类资源的访问权限

这样一来,即使进程是以 root 身份运行的,也需要判断这个进程的类型以及允许访问的资源类型才能决定是否允许访问某个资源。进程的活动空间也可以被压缩到最小

即使是以 root 身份运行的服务进程,一般也只能访问到它所需要的资源。即使程序出了漏洞,影响范围也只有在其允许访问的资源范围内。安全性大大增加

这种权限管理机制的主体是进程,也称为强制访问控制(MAC)

6.4、案例说明:

假设您有一个 Web 服务器,运行着 Apache 服务。默认情况下,Apache 需要访问一些系统资源,比如网页文件、日志文件等。如果没有 SELinux 的保护,任何程序都可以访问这些资源,这可能会带来安全隐患。

但是如果开启了 SELinux,情况就不一样了。SELinux 会为 Apache 进程设置专门的安全上下文(context),限制它只能访问特定的资源。比如:

这样一来,即使 Apache 进程被黑客利用,它也只能访问预先授权的资源,无法对系统造成更大的破坏

我们比较一下自己创建的acpache目录和原本的目录的安全上下文

# 安装Apache服务,使其产生/var/www/html/
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# mkdir /html

# 查看Apache服务创建的工作目录和自己手动创建的目录的区别
[root@localhost ~]# ls -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
[root@localhost ~]# ls -Zd /html/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /html/

- 会发现由Apache创建的工作目录 /var/www/html 具有一个httpd_sys_content_t的标签,这样,SELinux就可以通过在内核中对于这个带有这个标签的文件进行限制了

字段解释:

普通目录:unconfined_u:object_r:user_home_dir_t:s0

Apache工作目录:system_u:object_r:httpd_sys_content_t:s0

6.5、semanage

用于管理SELinux策略的一个工具

如果系统中没有这个命令的话,可以通过以下命令安装一下该工具

[root@localhost ~]# yum install -y policycoreutils-python

用法:

semanage [选项] [文件]

基本选项:

案例:更改httpd网站的默认工作目录,检查能否访问,如果不能访问,则为其添加httpd_sys_content_t策略再次访问测试:

1. 部署httpd

2. 更改httpd的配置文件,将工作目录变成/data/html
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
DocumentRoot "/data/html"
# Relax access to content within /var/www.
#
<Directory "/var/www">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>

# Further relax access to the default document root:
<Directory "/data/html">

3. 在工作目录中添加一个index.html文件做为网站首页
[root@localhost ~]# echo "<h1> hello world </h1>" > /data/html/index.html

4. 浏览完访问192.168.88.136测试,发现访问被拒绝,提示403Forbidden
- 这是因为新工作目录/data/html 没有携带httpd_sys_content_t标签,所以httpd进程受到SELinux限制,无法访问该资源


4. 可以向网站新的工作目录中新添加一条SELinux安全上下文,让这个目录以及里面的所有文件能够被httpd服务程序所访问到
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t /data/html
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t /data/html/*

#使用restorecon命令来检查SELinux上下文并且递归更新
[root@localhost ~]# restorecon -Rv /data/html
restorecon reset /data/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /data/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0


5. 再次访问测试

Hello world
6.5.1、查看跟Apache(httpd)服务相关的所有标签

使用getsebool命令查询并过滤出所有与HTTP协议相关的安全策略。其中,off为禁止状态,on为允许状态。

[root@localhost ~]# getsebool -a | grep http
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off
named_tcp_bind_http_port --> off
prosody_bind_http_port --> off
[root@localhost ~]# setsebool -P httpd_enable_homedirs=on

面对如此多的SELinux域安全策略规则,实在没有必要逐个理解它们,我们只要能通过名字大致猜测出相关的策略用途就足够了。比如,想要开启httpd服务的个人用户主页功能,那么用到的SELinux域安全策略是httpd_enable_homedir

六、计划任务与日志

1、计划任务

1.1、单次调度执行at

安装at软件包:

yum install -y at

启动at服务:

[root@localhost ~]# systemctl start atd
[root@localhost ~]# systemctl enable atd        # 开机自启动
1.1.1、语法结构
at [options] time
# 1.1.1.1、选项:

或者也可以使用一下命令查看和删除

atq:查看待执行的任务

atrm:通过序号删除任务

# 1.1.1.2、timespec
  now +5min            # 从现在开始5分钟后
  teatime tomorrow  # 明天的下午16:00
  noon +4 days        # 4天后的中午
  11:20 AM            # 早上11:20
  .....
  .....

# 对于at任务的时间写法有很多,不需要记忆,用到的时候查询一下就行

示例一:5分钟后创建一个文件

[root@localhost ~]# at now +5min
at> touch /root/file2
at> <EOT>            # ctrl+D 结束任务编辑
job 1 at Fri May 31 21:03:00 2024
[root@localhost ~]# at -l        # 查看任务
1       Fri May 31 21:03:00 2024 a root

示例二:通过文件指定任务

[root@localhost ~]# vim at.jobs
useradd testuser
[root@localhost ~]# at -l
[root@localhost ~]# at now +5min -f at.jobs
job 2 at Fri May 31 21:03:00 2024
[root@localhost ~]# at -l
2       Fri May 31 21:03:00 2024 a root
1.2、循环调度执行cron

计划任务(Cron)是一种强大的工具,可以自动执行预定的任务。它非常适合定期运行脚本、备份数据、清理临时文件等一系列重复性任务。

crontab:是cron服务提供的管理工具

检查cron服务有没有启动:

[root@localhost ~]# systemctl status crond.service crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since  2024-05-31 21:30:35 CST; 3min 48s ago
 Main PID: 6225 (crond)
   CGroup: /system.slice/crond.service
           └─6225 /usr/sbin/crond -n

5月 31 21:30:35 localhost.localdomain systemd[1]: Started Command Scheduler.
5月 31 21:30:36 localhost.localdomain crond[6225]: (CRON) INFO (RANDOM_DELAY...
5月 31 21:30:36 localhost.localdomain crond[6225]: (CRON) INFO (running with...
Hint: Some lines were ellipsized, use -l to show in full.



# 启动
systemctl start crond.service

cron计划任务主要分为用户的任务和系统任务,用户任务是又具体某个用户编写的任务,而系统任务则在系统启动时始终生效

1.2.1、cron的基本语法

cron命令的基本语法如下:

crontab [-l | -r | -e | -n | -m]
# 1.2.1.1选项:
[root@localhost ~]# crontab -l        # 列出当前用户所有计划任务
[root@localhost ~]# crontab -r        # 删除当前用户计划任务
[root@localhost ~]# crontab -e        # 编辑当前用户计划任务
管理员可以使用 -u username,去管理其他用户的计划任务
[root@localhost ~]# vi /etc/cron.deny    # 这个文件中加入的用户名无法使用cron
1.2.2、cron任务的配置

每个用户可以通过crontab命令来编辑自己的任务计划。要编辑cron任务,可以使用crontab -e命令。

1.2.3、编辑cron任务

要编辑cron任务计划,可以使用以下命令打开cron编辑器:

crontab -e
1.2.4、配置cron任务的格式

cron任务的格式如下:

    星期 命令
* 表示任何数字都符合
0 2 * * * date >> date.txt    # 每天的2点
0 2 14 * * date >> date.txt    # 每月14号2点
0 2 14 2 * date >> date.txt    # 每年2月14号2点
0 2 * * 5 date >> date.txt    # 每个星期5的2点
0 2 * 6 5 date >> date.txt    # 每年6月份的星期5的2点
0 2 2 * 5 date >> date.txt    # 每月2号或者星期5的2点   星期和日同时存在,那么就是或的关系
0 2 2 6 5 date >> date.txt    # 每年6月2号或者星期5的2点

* /5 * * * * date >> date.txt    # 每隔5分钟执行一次
0 2 1,4,6 * * date >> date.txt    # 每月1号,4号,6号的2点
0 2 5-9 * * date >> date.txt        # 每月5-9号的2点

* * * * * date >> date.txt        # 每分钟
0 * * * * date >> date.txt        # 每整点
* * 2 * * date >> date.txt        # 每月2号的每分钟

其中,第一个字段表示分钟(0-59),第二个字段表示小时(0-23),第三个字段表示天(1-31),第四个字段表示月份(1-12),第五个字段表示星期(0-7)。第六个字段是要执行的命令或脚本。

例如,要每天上午10点重启系统,可以配置如下:

0 10 * * * reboot
1.2.5、查看任务存放位置
/var/spool/cron/root
[root@localhost ~]# cat /var/spool/cron/root
* * * * * date >> file.txt
1.2.6、示例

这里列举几个常见的cron任务的示例:

每天凌晨3点备份文件:

0 3 * * * /path/to/backup.sh

每周一上午8点清理临时文件:

0 8 * * 1 /path/to/cleanup.sh

每隔10分钟检查服务器状态:

*/10 * * * * /path/to/check_status.sh
1.3、cron系统任务
[root@localhost ~]# vim /etc/crontab    # 默认没有定义任何计划任务
[root@localhost ~]# ls /etc/cron.d        # 定义的计划任务每个小时会执行
0hourly  sysstat
[root@localhost ~]# cat /etc/cron.d/0hourly 
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly        # 每小时01分以root身份执行/etc/cron.hourly/目录下的所有脚本
[root@localhost ~]# ls /etc/cron.hourly/
[root@localhost ~]# cat /etc/cron.hourly/0anacron
/usr/sbin/anacron -s        # anacron是用来检查是否有错过的计划任务需要被执行
[root@localhost ~]# vi /etc/anacrontab
1 5 cron.daily nice run-parts /etc/cron.daily
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行
7 25 cron.weekly nice run-parts /etc/cron.weekly
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
©monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没有被执行,那就执行

2、日志管理

Linux系统和许多程序会产生各种错误信息、告警信息和其他的提示信息,这些各种信息都应该记录到日志文件中。Linux系统日志对管理员来说,是了解系统运行的主要途径,因此需要对Linux日志系统有详细的了解。

2.1、常见的日志文件
日志文件 解释
/var/log/messages 系统主日志文件
/var/log/secure 记录认证、安全的日志
/var/log/maillog 跟邮件postfix相关
/var/log/cron crond、at进程产生的日志
/var/log/dmesg 记录系统启动时加载的硬件相关信息日志
/var/log/yum.log yum的日志
/var/log/mysqld.log MySQL日志
var/log/xferlog 和访问FTP服务器相关
/var/log/boot.log 系统启动过程日志记录存放
/var/log/wtmp 当前登录的用户(可以直接在命令行输入w查看)
/var/log/lastlog 所有用户的登录情况(可以直接在命令行输入lastlog查看)
2.2、查看日志

有多种方法可以查看日志,可以通过cat、tail等命令来查看

但是往往日志文件中内容都是非常多的,所以对于初学者通过cat查看不是很直观。这个时候我们可以配合一些其他过滤工具来过滤日志里面的内容。如:grep,awk等等。

2.2.1、示例一:查看message日志中关于ens33网卡的信息
[root@localhost ~]# cat /var/log/messages | grep ens33
# 通过grep来过滤出跟ens33相关的内容
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9969] dhcp4 (ens33):   address 192.168.88.136
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33):   plen 24 (255.255.255.0)
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33):   gateway 192.168.88.2
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33):   lease time 5185800
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33):   nameserver '192.168.88.2'
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33):   domain name 'localdomain'
May 30 09:55:47 localhost NetworkManager[6310]: <info>  [1717034147.9970] dhcp4 (ens33): state changed unknown -> bound

image-106

2.2.2、示例二:统计远程登录信息
[root@localhost ~]# cat /var/log/secure-20240530 | grep Accepted
Apr 27 10:49:14 localhost sshd[16512]: Accepted password for root from 192.168.88.1 port 56801 ssh2
Apr 27 10:49:14 localhost sshd[16516]: Accepted password for root from 192.168.88.1 port 56818 ssh2
May 30 09:33:21 localhost sshd[7319]: Accepted password for root from 192.168.88.1 port 15675 ssh2
May 30 09:33:21 localhost sshd[7323]: Accepted password for root from 192.168.88.1 port 15676 ssh2
2.2.3、示例三:查看用户与用户组相关的信息
[root@localhost ~]# cat /var/log/secure | grep useradd
May 30 11:09:15 localhost useradd[7762]: new group: name=user1, GID=1001
May 30 11:09:15 localhost useradd[7762]: new user: name=user1, UID=1001, GID=1001, home=/home/user1, shell=/bin/bash
May 30 11:09:18 localhost useradd[7767]: new group: name=user2, GID=1002
May 30 11:09:18 localhost useradd[7767]: new user: name=user2, UID=1002, GID=1002, home=/home/user2, shell=/bin/bash
[root@localhost ~]# cat /var/log/secure | grep groupadd
May 30 11:09:29 localhost groupadd[7772]: group added to /etc/group: name=IT, GID=1003
May 30 11:09:29 localhost groupadd[7772]: group added to /etc/gshadow: name=IT
May 30 11:09:29 localhost groupadd[7772]: new group: name=IT, GID=1003
2.2.4、示例四:查看计划任务cron相关
[root@localhost ~]# cat /var/log/cron
May 30 10:15:01 localhost run-parts(/etc/cron.daily)[7516]: finished logrotate
May 30 10:15:01 localhost run-parts(/etc/cron.daily)[7504]: starting man-db.cron
May 30 10:15:01 localhost run-parts(/etc/cron.daily)[7715]: finished man-db.cron
May 30 10:15:01 localhost anacron[7492]: Job `cron.daily' terminated
May 30 10:35:01 localhost anacron[7492]: Job `cron.weekly' started
May 30 10:35:01 localhost anacron[7492]: Job `cron.weekly' terminated
May 30 10:55:01 localhost anacron[7492]: Job `cron.monthly' started
May 30 10:55:01 localhost anacron[7492]: Job cron.monthly terminated
May 30 10:55:01 localhost anacron[7492]: Normal exit (3 jobs run)
May 30 11:01:01 localhost CROND[7741]: (root) CMD (run-parts /etc/cron.hourly)
May 30 11:01:01 localhost run-parts(/etc/cron.hourly)[7741]: starting 0anacron
May 30 11:01:01 localhost run-parts(/etc/cron.hourly)[7750]: finished 0anacron
2.3、日志系统-rsyslogd
2.3.1、处理日志的进程
rsyslogd`:绝大部分日志记录,和系统操作有关,安全,认证`sshd,su`,计划任务`at,cron

httpd/nginx/mysql等等应用可以以自己的方式记录日志

[root@localhost ~]# ps aux |grep rsyslogd
root       6808  0.0  0.2 216408  5016 ?        Ssl  09:32   0:00 /usr/sbin/rsyslogd -n
root       7724  0.0  0.0 112724   988 pts/0    S+   10:39   0:00 grep --color=auto rsyslogd

日志可以存放在本地

日志可以存放在远程服务器

2.3.2、配置文件
[root@localhost ~]# rpm -qc rsyslog
/etc/logrotate.d/syslog        # 日志轮转(切割)相关
/etc/rsyslog.conf            # rsyslogd的主配置文件
/etc/sysconfig/rsyslog        # rsyslogd相关文件
[root@localhost ~]# vim /etc/rsyslog.conf
# 告诉rsyslogd进程 哪个设备(facility),关于哪个级别的信息,以及如何处理
authpriv.*                       /var/log/secure
mail.*                           /var/log/maillog
cron.*                           /var/log/cron
*.emerg                          :omusrmsg:*
authpriv.*                       *                    # 所有终端
authpriv.*                       @192.168.1.123        # UDP
authpriv.*                       @@192.168.1.123        # TCP
2.3.3、日志类型(facility)
序号 Facility 解释
0 kern (kernel) Linux内核产生的信息,大部分是硬件检测和内核功能的启用
1 user 用户层级产生的信息,例如后边介绍的通过logger产生的日志信息
2 mail 所有邮件收发的相关信息
3 daemon 系统服务产生的信息
4 auth 与认证、授权相关的信息,如loginsshsu等产生的信息
5 syslog syslogd服务产生的信息
6 lpr 打印相关的信息
7 news 新闻群组相关的信息
8 uucp Unix to Unix Copy Protocol 早期Unix系统间的数据交换协议
9 cron 周期性计划任务程序,如cronat等产生的信息
10 authpriv 与auth类似,但记录的多为帐号相关的信息,如pam模块的调用等
16~23 local0~local7 保留给本地用户使用的日志类型,通常与终端交互相关。

日志级别

级别(日志重要级别) 解释
LOG_EMERG 紧急,致命,服务无法继续运行,如配置文件丢失
LOG_ALERT 报警,需要立即处理,如磁盘空间使用95%
LOG_CRIT 致命行为
LOG_ERR(error) 错误行为
LOG_WARNING 警告信息
LOG_NOTICE 普通
LOG_INFO 标准信息
LOG_DEBUG 调试信息,排错才开,一般不建议使用
2.3.4、案例:远程管理日志

环境准备:两台服务器,其中server1模仿生产服务器,server2做为日志服务器。

实验要求:server1和server2可以通信(建议两边的虚拟网卡都调整成NAT模式)

实验目的:通过配置rsyslog,使得server1上关于ssh连接的日志发送到server2日志服务器上保存,在server2上可以查看到server1上的ssh日志

注意关闭server1和server2上的firewalld!!

systemctl stop firewalld

server1上配置:

  1. 编辑/etc/rsyslog.conf文件
# 在最下面添加如下字段
[root@localhost ~]# vim /etc/rsyslog.conf
:msg,contains,"sshd" @192.168.88.138:514

#=====字典解释=====
- msg 要发送的消息
- contains,"sshd" 过滤器,过滤所有跟sshd有关的日志
- @192.168.88.138:514  要发送到日志服务器的地址,其中@表示UDP,@@表示TCP
  1. 重启rsyslog服务
[root@localhost ~]# systemctl restart rsyslog

server2上配置:

修改配置文件

[root@localhost ~]# vim /etc/rsyslog.conf
# Provides UDP syslog reception
$ModLoad imudp                # 把前面的注释删除        加载imudp模块,启用对UDP网络接口的支持
$UDPServerRun 514            # 把前面的注释删除        用于通信的端口

$ModLoad imtcp                # tcp
$InputTCPServerRun 514        

:msg,contains,"sshd" /var/log/remote_ssh.log        # 任意位置添加规则,

# 重启rsyslog服务
[root@localhost ~]# systemctl restart rsyslog

测试:

通过MobaXterm远程连接server1

通过tail -f /var/log/remote_ssh.log来实时检测是否又日志记录发过来

2.4、日志文件归档

如果我们不管理系统产生的上述各种日志文件,那么久而久之日志就会变成“屎山”。日志文件及内容越堆越多,不仅难以查阅,还会因为单一文件过大而影响新的内容写入的效率

logrotate就是一个不错的日志处理程序,准确的说是对日志进行“归档”之类的工作

2.5、logrotate(日志轮转)
[root@localhost ~]# ll /etc/cron.daily/
-rwx------. 1 root root 219 10月 31 2018 logrotate
-rwxr-xr-x. 1 root root 618 10月 30 2018 man-db.cron

# 查看logrotate内容
[root@localhost ~]# cat /etc/cron.daily/logrotate 
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf

# 日志轮转状态/var/lib/logrotate/logrotate.status
# 日志轮转规则按照/etc/logrotate.conf中来
[root@localhost ~]# vim /etc/logrotate.conf 
weekly                         # 多久会执行一次“轮转”,这里设置的是每周一次
rotate 4                     # 轮转后会保留几个历史日志文件,这里是4,也就是说轮转后会删除编号为5的历史日志
create                         # 轮转后创建新的空白日志
dateext                     # 使用日期而非数字编号作为历史日志的标识进行轮转
include /etc/logrotate.d     # 加载/etc/logrotate.d目录下的配置文件
/var/log/wtmp {             # 对/var/log/wtmp日志的特殊设置
    monthly                 # 每月进行一次轮转
    create 0664 root utmp     # 创建的新的空白日志权限为0664,用户为root,用户组为utmp
        minsize 1M             # 原始日志文件超过1M大小才进行轮转
    rotate 1                 # 仅保留1个历史日志文件
}
/var/log/btmp {             # 对/var/log/btmp日志的特殊设置
    missingok                 # 日志轮转期间任何错误都会被忽略
    monthly                 # 每月进行一次轮转
    create 0600 root utmp     # 创建的新日志文件权限为0600,用户为root,用户组为utmp
    rotate 1                 # 仅保留1个历史日志文件
}
[root@localhost ~]# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    missingok
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

七、管道与重定向

1、I/O重定向

I/O对应系统中的输入(input)和输出(output)

其中输入可以是键盘输入,鼠标输入等等。同样输出也可以输出到终端中或者文件中

对于Linux系统,我们常见的输入输出的类型有:

image-107

1.1、File Descriptors(FD,文件描述符 )

案例切入:通过vim来追踪fd的信息

我们打开两个终端,然后在其中一个终端中使用vim打开一个文件,然后在另一个终端中查看与FD相关的文件

终端一:vim file.txt

终端二:
[root@192 fd]# ps aux | grep vim
root      16350  0.0  0.2 149432  5064 pts/1    S+   23:01   0:00 vim file1.txt
root      16360  0.0  0.0 112724   984 pts/0    S+   23:03   0:00 grep --color=auto vim
[root@192 fd]# cd /proc/16350/fd
[root@192 fd]# ll
总用量 0
lrwx------. 1 root root 64 6月   1 23:01 0 -> /dev/pts/1
lrwx------. 1 root root 64 6月   1 23:01 1 -> /dev/pts/1
lrwx------. 1 root root 64 6月   1 23:01 2 -> /dev/pts/1
lrwx------. 1 root root 64 6月   1 23:01 3 -> /root/.file1.txt.swp

# 这里有0 1 2 3
其中0表示标准输入
1表示标准正确输出
2表示标准错误输出
其他的都为输出到文件中

# 我们可以尝试通过0来向我们刚刚vim打开的文档里面输入内容
[root@192 fd]# echo hello > 0

这里也是体现Linux一切皆文件的特性,连输入输出都可以由文件来进行控制
Number Channel name Description Default connection Usage
0 stdin 标准输入 键盘 只读
1 stdout 标准输出 命令行 只写
2 stderr 标准错误 命令行 只写
3+ filename 其他文件 none 读 and/or 写

2、输出重定向(覆盖,追加)

>:覆盖重定向

>>:追加重定向

1>:覆盖重定向正确的输出数据流

1>>:追加重定向正确的输出数据流

2>:覆盖重定向错误输出数据流

2>>:追加重定向错误输出数据流

示例一:输出重定向(覆盖)

[root@localhost ~]# date 1> date.txt
[root@localhost ~]# cat date.txt

image-108

示例二:输出重定向(追加)

[root@localhost ~]# date >> date.txt
[root@localhost ~]# date >> date.txt
[root@localhost ~]# date >> date.txt
[root@localhost ~]# cat date.txt

image-109

示例三:错误输出重定向

[root@localhost ~]# touch file
[root@localhost ~]# cd file
bash: cd: file: 不是目录
[root@localhost ~]# cd file 2> log.txt
[root@localhost ~]# cat log.txt
bash: cd: file: 不是目录

image-110

示例四:正确和错误都输入到相同位置

[root@localhost ~]# ls /home/ /test
ls: 无法访问/test: 没有那个文件或目录
/home/:
user01

#将正确和错误的输出都输出的文件中
[root@localhost ~]# ls /home/ /test &> log.txt
[root@localhost ~]# cat log.txt
ls: 无法访问/test: 没有那个文件或目录
/home/:
user01

image-111

示例五:正确和错误都输入到相同位置

[root@localhost ~]# ls /home/ /test > log.txt
ls: 无法访问/test: 没有那个文件或目录
[root@localhost ~]# ls /home/ /test > log.txt 2>&1
[root@localhost ~]# cat log.txt
ls: 无法访问/test: 没有那个文件或目录
/home/:
user01

image-112

示例六:重定向到空设备/dev/null

# /dev/null是一个空设备,可以理解为一个无限大的垃圾堆,可以往里面丢任意多的垃圾进去

[root@localhost ~]# ls /home/ /test > log.txt 2>/dev/null
[root@localhost ~]# cat log.txt
/home/:
user01

[root@localhost ~]# ls /home/ /test &>/dev/null

3、输入重定向

标准输入:< 等价 0<

案例1:

[root@localhost ~]# cat < /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
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
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
user01:x:1000:1000::/home/user01:/bin/bash

案例2:

[root@localhost ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

案例3:at

[root@localhost ~]# at now +5 min
at> ping -c4 baidu.com
at> <EOT>
job 1 at Thu Dec 12 15:50:00 2019
[root@localhost ~]# vim at.txt
ping -c4 baidu.com
[root@localhost ~]# at now +1 min < at.txt 
job 2 at Thu Dec 12 15:47:00 2019

案例4:利用重定向建立多行的文件

[root@localhost ~]# cat > file2.txt <<EOF
> hello
> python
> linux
> EOF
[root@localhost ~]# cat file2.txt
hello
python
linux

4、进程管道

用法:command1 | command2 | command3 | ....

image-113

[root@localhost ~]# ll /dev/ |less
[root@localhost ~]# ps aux |grep 'sshd'
[root@localhost ~]# rpm -qa |grep 'httpd'
[root@localhost ~]# yum list |grep 'httpd'

案例1:统计出最占CPU的5个进程

[root@localhost ~]# ps aux --sort=-%cpu |head -6

案例2:过滤secure文件中跟ssh相关的内容

[root@localhost ~]# cat /var/log/secure | grep ssh

5、tee管道

image-114

[root@localhost ~]# du -h . | sort -hr | tee file_sizes.txt
44K     .
0       ./dir1
0       ./dir

使用 du 命令列出当前目录下的文件大小,然后通过管道传递给 sort 命令进行降序排序。最后使用 tee 命令将排序结果同时输出到终端和 file

评论区