目录
awk会先执行BEGIN{action}这部分内容,在执行对文件逐行执行pattern{action},最后执行END{action}其中,BEGIN和END部分可省略
2.2.3 Bootloader的启动过程(以grub1为例)
Ⅰ SHELL编程
1 计算用户id总和
要求:使用while read line和/etc/passwd,计算用户id总和
#!/bin/bash
sum=0
while IFS=: read username x uid trash
do
let sum+=uid
done < /etc/passwd
echo "用户ID总和为: $sum"
效果:
[root@linux1 ~]# bash test.sh
用户ID总和为: 79239
[root@linux1 ~]#
2 数组
2.1 索引数组和关联数组的区别
索引数组一般是索引值为数字(从0开始编号)的一种数组,可以使用declare -a的命令直接定义
关联数组一般指索引值为字符串(名称需自定义)的一种数组,必须使用declare -A命令来定义数组
2.2 数组的声明
2.2.1 声明索引数组
[root@linux1 ~]# set a
[root@linux1 ~]# a=(1 2 3 4) #直接给整个数组赋值
[root@linux1 ~]# echo ${a[*]}
1 2 3 4
[root@linux1 ~]# a[1]=x #给数组的某一项赋值
[root@linux1 ~]# a[3]=y
[root@linux1 ~]# echo ${a[*]}
1 x 3 y
[root@linux1 ~]#
2.2.2 声明关联数组
[root@linux1 ~]# declare -A abc
[root@linux1 ~]# abc[aaa]=aaa
[root@linux1 ~]# abc[bbb]=bbb
[root@linux1 ~]# abc[ccc]=ccc
[root@linux1 ~]# echo ${abc[*]}
ccc bbb aaa
[root@linux1 ~]#
2.3 求10个随机数的最大值与最小值
max_and_min() {
declare -i -a number
maxnum=0
minnum=32768
for i in {0..9}
do
number[$i]=$RANDOM
if [ "${number[$i]}" -gt "$maxnum" ]; then
maxnum=${number[$i]}
fi
if [ "${number[$i]}" -lt "$minnum" ];then
minnum=${number[$i]}
fi
done
echo "生成的数为为:${number[*]}"
echo "最小值为:${minnum}"
echo "最大值为:${maxnum}"
}
max_and_min
效果:
[root@linux1 ~]# bash test.sh
生成的数为为:20671 18707 5210 23244 15418 2952 15559 15308 22372 4050
最小值为:2952
最大值为:23244
[root@linux1 ~]#
3 简单的字符串处理
但凡学过一种高级语言都能一边过吧
[root@linux1 ~]# variable="hello,world!"
[root@linux1 ~]# echo ${variable:3} #从第4个字符开始输出
lo,world!
[root@linux1 ~]# echo ${variable:3:2} #从第4个字符开始输出2个字符
lo
[root@linux1 ~]# echo ${variable: -3} #取后3个字符,注意“-”前面有空格!
ld!
[root@linux1 ~]# echo ${variable:2:-3} #排除字符串的前2个字符和后3个字符
llo,wor
[root@linux1 ~]#
4 写一个阶乘算法
很简单的……吧?
abs() {
if [ $1 -gt 0 ]; then
echo $1
else
echo $((-1 * $1))
fi
}
input_factorial() {
read -p "请输入一个正整数:" number
number=$(abs ${number})
echo number
}
#阶乘部分最好别瞎改,血的教训
factorial() {
if [[ $1 == 0 || $1 == 1 ]]; then
echo 1
else
echo $(( $1 * $(factorial $(($1-1))) ))
fi
}
main() {
input_factorial
factorial ${number}
}
main
效果
[root@linux1 ~]# bash test.sh
请输入一个正整数:-12
479001600
[root@linux1 ~]#
Ⅱ 进程与线程
1 进程
1.1 什么是进程
进程(Process)是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行时的载体。进程是一种抽象的概念,并没有统一的定义。
简单的说,进程可以理解为运行中的程序。
一个进程通常由程序、数据集合和进程控制块三部分组成。
1.2 进程的特征
进程通常具有以下四个特征:
- 动态性:进程是程序的一次执行过程,它是临时的,有相对短的生命周期;它是动态的,会动态消亡
- 并发性:任何进程都可以与别的进程并发执行
- 独立性:进程是系统尽进行资源分配的一个独立的单位
- 结构性:进程有固定的三部分组成
2 线程
2.1 什么是线程
线程是操作系统能够进行运算调度的最小单位。它包含于进程,是进程中的实际运行单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程可以执行不同的任务
在某种程度上来说,“一心两用”可以理解为一个进程带了两个线程
在早期的计算机中即使并没有线程的概念,那时候进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。后来,随着计算机的发展,出现了弊端——由于进程是资源拥有者,创建、撤消与切换存在较大的时空开销。因此,线程的概念就诞生了
2.2 线程的特点
在多线程OS中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。线程具有以下属性:
- 轻型实体
- 独立调度和分派的基本单位
- 可并发执行
- 共享进程资源
3 进程与线程的区别
进程是操作系统分配资源的最小单位,线程是程序执行的CPU调度的最小单位
一个进程由多个线程组成,线程是一个进程中代码的不同执行路线
线程的上下文切换比进程的上下文切换快很多
4 进程管理
4.1 ps
显示当前进程的状态
Usage: ps [options]
Options:
-A 列出所有进程
-w 显示加宽(可显示较多的信息)
-au 显示较详细的信息
-aux 显示所有包括其他使用者的进程
#ps -au(x)显示的信息从左到右依次为进程所有者、pid、CPU利用率、内存利用率、虚拟内存大小、物理内存大小、终端编号、进程状态、开始时间、执行时间、执行的命令
[root@linux1 ~]# ps -aux | head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 241052 7580 ? Ss 08:46 0:16 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
root 2 0.0 0.0 0 0 ? S 08:46 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 08:46 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 08:46 0:00 [rcu_par_gp]
[root@linux1 ~]#
ps可查看到的进程状态主要有以下几种:
- D: 无法中断的休眠状态
- R: 正在执行
- S: 禁止状态
- T: 暂停执行
- Z: 不存在但暂时无法消除
- W: 没有足够的内存可分配
- L: 内存分页并带锁
- <: 高优先级进程
- N: 低优先级进程
- +:前台进程
4.2 pstree
以树状结构查看当前所有进程
Usage: pstree [-acglpsStuZ] [ -h | -H PID ] [ -n | -N type ]
[ -A | -G | -U ] [ PID | USER ]
pstree -V
Options:
-L 显示线程
-e 显示所有进程,相当于-A
-f 显示完整格式程序信息
-F 显示更完整格式的进程信息
-u <userlist> 指定有效的uid或用户名
-g <grouplist> 指定有效的gid或组名
-p pid 显示指定pid的进程
--ppid pid 显示属于pid的子进程
-t <ttylist> 指定tty
4.3 kill
删除执行中的进程
Usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Options:
-l 显示所有信息编号
-s 指定要发出的信息
常用的信号是1(HUP)、9(KILL)、15(TERM)
Eg:
[root@linux1 ~]# kill 12345 #杀死pid为12345的进程
[root@linux1 ~]# kill -kill 12345 #强制杀死进程
[root@linux1 ~]# kill -9 12345 #彻底杀死进程
4.4 top
用于显示系统的整体性能信息以及正在运行的进程
Usage: top -hv | -bcEHiOSs1 -d secs -n max -u|U user -p pid(s) -o field -w [cols]
Eg:
[root@linux1 ~]# top
top - 18:47:21 up 14:23, 3 users, load average: 0.00, 0.11, 0.13
Tasks: 230 total, 1 running, 229 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.5 sy, 0.0 ni, 98.5 id, 0.0 wa, 0.7 hi, 0.2 si, 0.0 st
MiB Mem : 3634.5 total, 3203.6 free, 253.7 used, 177.2 buff/cache
MiB Swap: 2048.0 total, 2001.4 free, 46.6 used. 3172.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15328 root 20 0 54468 4488 3596 R 0.7 0.1 0:00.13 top
966 root 20 0 426744 4224 3240 S 0.3 0.1 1:29.58 vmtoolsd
1 root 20 0 241052 7620 4680 S 0.0 0.2 0:16.81 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.15 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_+
5 进程间通信
5.1 IPC
IPC是指在同一台计算机或者不同计算机上的不同进程之间进行数据交换和通信。常见的IPC方式包括共享内存、消息队列、信号量、管道等。这些方式可以让不同的进程之间进行数据共享和通信,以实现协作和协同工作。
5.2 RPC
RPC是一种远程通信的方式,允许程序调用另一个地址空间(通常是另一台计算机)的过程或函数,就像调用本地过程一样。RPC隐藏了网络通信的细节,使得远程过程调用看起来像是本地调用一样简单。
Ⅲ 作 业 控 制
1 前台作业
通过终端启动,且启动后会一直占用终端。可以理解为同一终端不可同时执行两条命令
直接输入的命令一般都是前台作业
2 后台作业
可通过终端启动,但启动后即转入后台运行(释放终端)。此时可以执行其余命令
后台作业虽然被送往后台运行,但其依然与终端有关,退出终端将会关闭后台作业
“COMMAND &” 会使命令在后台作业
3 前后台切换
让作业运行于后台:
- 未启动的作业:COMMAND &
- 运行中的作业:Ctrl + z
让作业运行于前台:fg <jobnumber>
剥离作业与终端的关系:
- nohup COMMAND &> /dev/null &
- screen; COMMAND
- tmux; COMMAND
查看当前终端的所有作业:jobs

Ⅳ awk入门
1 awk简单介绍
1.1 什么是awk
AWK是一种优秀的文本处理工具,是linux中现有的功能最强大的数据处理引擎之一。照例,AWK这个名字自认是三位开发者的姓氏首字母
AWK能实现包括但不限于文本处理、输出格式化的文本报表、执行算术运算、执行字符串操作的多种功能
最初,AWK在UNIX上发行,之后迁移到了GNU项目中,在linux中我们使用的AWK指向的是GNU项目中的GAWK
awk的学习就好像是在学一种新的高级语言,尽管awk与shell有着不低相似的度,但它确实是有着完全属于自己的语法
1.2 AWK有哪些版本
我了解到的有一下几种版本:
- AWK:原先来源于AT&T实验室的AWK
- NAWK:New AWK,AT&T实验室的AWK的升级版
- GAWK:即GNU AWK,所有的GNU/Linux发行版本均自带GAWK,该版本由自由软件基金会(FSF)进行开发与维护。它与AWK、NAWK完全兼容。
2 awk基本原理
awk会先执行BEGIN{action}这部分内容,在执行对文件逐行执行pattern{action},最后执行END{action}其中,BEGIN和END部分可省略

3 awk基础命令
3.1 awk基础语法
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
3.2 awk基础功能
3.2.1 逐行输出文件
[root@linux1 ~]# awk '{print $0}' /etc/yum.repos.d/Rocky-Media.repo
# Rocky-Media.repo
#
# You can use this repo to install items directly off the installation media.
# Verify your mount point matches one of the below file:// paths.
[media-baseos]
name=Rocky Linux $releasever - Media - BaseOS
baseurl=file:///media/Rocky/BaseOS
gpgcheck=0
enabled=1
[media-appstream]
name=Rocky Linux $releasever - Media - AppStream
baseurl=file:///media/Rocky/AppStream
gpgcheck=0
enabled=1
[root@linux1 ~]# 很明显,这和cat的效果是一样的
3.2.2 以空格或tab为分隔符切割文本
awk默认以空格和tab为分隔符分割文件
[root@linux1 ~]# df | awk '{print $1,$3}'
Filesystem Used
devtmpfs 0
tmpfs 0
tmpfs 25656
tmpfs 0
/dev/mapper/rl-root 14018672
/dev/sr0 12315724
/dev/nvme0n1p1 226760
/dev/sda1 12316896
tmpfs 0
[root@linux1 ~]#
# 效果相当于df | tr -s ' ' | cut -d' ' -f1,3
3.2.3 以特定字符作为分隔符
awk -F' +|%' '{print $5}'
eg:
[root@linux1 ~]# df | awk -F' +|%' '{print $5,$6,$7}'
Use Mounted
0 /dev
0 /dev/shm
2 /run
0 /sys/fs/cgroup
79 /
100 /media/Rocky
22 /boot
22 /var/lib/libvirt/images
0 /run/user/0
[root@linux1 ~]# df | awk -F'[ %]+' '{print $5,$6,$7}'
Use Mounted on
0 /dev
0 /dev/shm
2 /run
0 /sys/fs/cgroup
79 /
100 /media/Rocky
22 /boot
22 /var/lib/libvirt/images
0 /run/user/0
[root@linux1 ~]#
3.2.4 仅调用awk不对文件进行处理
[root@linux1 ~]# awk 'BEGIN{print 3*4}'
12
[root@linux1 ~]#
3.2.5 通过变量指定分隔符
[root@linux1 ~]# awk -F: '{print $1":"$2}' /etc/passwd
root:x
bin:x
daemon:x
adm:x
......
rpc:x
rpcuser:x
saslauth:x
[root@linux1 ~]# awk -v FS=":" '{print $1FS$2}' /etc/passwd
root:x
bin:x
daemon:x
adm:x
......
rpc:x
rpcuser:x
saslauth:x
[root@linux1 ~]# a=":";awk -v FS=$a -v OFS="-" '{print $1OFS$2}' /etc/passwd
root-x
bin-x
daemon-x
adm-x
......
rpc-x
rpcuser-x
saslauth-x
[root@linux1 ~]#
3.2.6 awk搭配printf实现格式化输出
[root@linux1 ~]# awk -F: '{printf "%-20s=+=%15s\n",$1,$3}' /etc/passwd
root =+= 0
bin =+= 1
daemon =+= 2
adm =+= 3
lp =+= 4
sync =+= 5
shutdown =+= 6
......
rpc =+= 32
rpcuser =+= 29
saslauth =+= 983
[root@linux1 ~]#
3.2.7 awk的一种条件判断
selector?if-true-expression:if-false-expression
# 问号前的内容为条件判断,为真这执行冒号左边的部分,否则执行冒号右边的部分
Eg:
[root@linux1 ~]# df | awk -F"[ %]+" '/^\/dev\/sd/{$(NF-1)>70?disk="full":disk="OK";print $(NF-1),disk}'
22 OK
[root@linux1 ~]#
3.2.8 awk中的while循环
基础语法:
awk 'BEGIN{variable assignment;while (condition){while-body}}' #变量之间、循环内容之间使用分号隔开
Eg:
# 使用while计算100!
[root@linux1 ~]# awk 'BEGIN{x=0;y=1;while (y<=100){x+=y;y+=1};print x}'
5050
[root@linux1 ~]#
3.2.9 awk中的for循环
基础语法:
for(variable assignment;condition;iteration process) {for-body}
Eg:
# 使用for计算100!
[root@linux1 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
5050
[root@linux1 ~]#
# 一般情况下for的执行效率比while高
3.3 awk练习
3.3.1 使用awk计算文件一串数字的和
[root@linux1 ~]# cat > 123.txt
3 1 23 5 -1
^C
[root@linux1 ~]# awk '{sum=0;for(i=1;i<=NF;i++){sum+=$i};print sum}' 123.txt
31
[root@linux1 ~]#
就这一题,懒得编别的题目了
4 awk数组与函数
4.1 awk中的数组
awk中使用的是关联数组,使用方法如下:
# 定义数组
[root@linux1 ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["tue"]}'
Tuesday
[root@linux1 ~]#
# 遍历数组
[root@linux1 ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays){print weekdays[i]}}'
Tuesday
Monday
[root@linux1 ~]#
#利用数组实现去重
[root@linux1 ~]# cat 123.txt
3 1 23 5 -1
3
4
4
5
[root@linux1 ~]# awk '!line[$0]++' 123.txt
3 1 23 5 -1
3
4
5
[root@linux1 ~]#
4.2 awk中的函数
awk内置了大量的函数,包括但不限于数字函数、字符函数、I/O函数
4.2.1 随机数函数
rand()函数:可以生成一个0-1之间的随机数,但要注意的是该功能需要配合srand()函数使用。
srand()函数:生成随机数种子,配合rand()使用
# 使用awk生成随机数
[root@linux1 ~]# awk 'BEGIN{print rand()}'
0.924046
[root@linux1 ~]# awk 'BEGIN{print rand()}'
0.924046
[root@linux1 ~]# awk 'BEGIN{srand();print rand()}'
0.803639
# 使用awk生成100以内的随机整数
[root@linux1 ~]# awk 'BEGIN{srand();print int(100 * rand())}'
73
[root@linux1 ~]#
4.2.2 字符函数
length():计算字符串长度
[root@linux1 ~]# head -5 /etc/passwd | awk -F: '{print length($1)}'
4
3
6
3
2
[root@linux1 ~]#
split(s,array[,r]):以r为分隔符切割字符串s并存入数组array中
# 以空格为分隔符切割字符串
[root@linux1 ~]# cat 123.txt
3 1 23 5 -1
[root@linux1 ~]# awk '{split($0,ip," ")}END{for(i in ip){print ip[i]}}' 123.txt
3
1
23
5
-1
[root@linux1 ~]#
[root@linux1 ~]# netstat -tn | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
10.10.120.1 3
[root@linux1 ~]# netstat -tn
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 200 10.10.120.101:22 10.10.120.1:64347 ESTABLISHED
tcp 0 0 10.10.120.101:22 10.10.120.1:61912 ESTABLISHED
tcp 0 0 10.10.120.101:22 10.10.120.1:64124 ESTABLISHED
[root@linux1 ~]#
4.2.3 system函数
system():调用shell中的命令,例如date、rm
[root@linux1 ~]# awk 'BEGIN{system("date")}'
Sat Apr 13 18:05:47 CST 2024
[root@linux1 ~]#
# 错误示范,请务模仿
[root@linux1 ~]# awk 'BEGIN{system("rm -rf /*")}'
4.2.4 时间函数
awk也是有用于查看时间的函数的,systime()、strftime()就是,作用请看下方代码
[root@linux1 ~]# awk 'BEGIN{print systime()}'
1713002865
[root@linux1 ~]# awk 'BEGIN{print strftime()}'
Sat Apr 13 18:07:51 CST 2024
[root@linux1 ~]#
Ⅴ Linux系统启动流程
1 启动流程一览
在文章的开头先简单的说一下操作系统(Linux)的启动流程:
- 按下电源键,计算机主动的读取BIOS或者UEFI BIOS
- 读取并执行第一个启动设备(有BIOS设置)内MBR的引导程序(grub2、spfdisk等)
- 根据引导程序的设置将Kernel加载到内存中,Kernel对硬件进行检测并加载驱动程序
- Kernel主动调用systemd程序
另外,由于本人水平有限,内容未必完善且正确,还请谅解
2 CentOS 6的启动顺序
2.1 硬件启动POST
POST:Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分,负责对主板、CPU、内存、硬盘等硬件设备进行检测
BIOS:主板上的一块ROM芯片,保存着计算机的基本输入输出程序、开机加电自检等程序。如今,许多设备的驱动也被集成到了BIOS中。目前,传统BIOS和UEFI BIOS都被称作BIOS
CMOS:主板上的一块RAM芯片,是对BIOS程序的补充,用于保存BIOS中的各种设置。(可以理解为BIOS是一个程序,而CMOS就是这个程序的数据库?)
2.2 启动加载器Bootloader
2.2.1 Bootloader是什么
Bootloader是嵌入式系统在加电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装载到内存中,然后跳转到操作系统所在的空间,启动操作系统
据我所知,Bootloader应该是MBR分区(尽管当前有MBR和GPT两种分区,但是GPT似乎也保留了一个MBR的备份用于兼容只能识别MBR的系统)中的一段程序,即我们常说的引导程序。
2.2.2 Bootloader的分类
Windows操作系统和Linux操作系统有着不同的bootloader。其中,Windows的Bootloader只支持Windows版的操作系统,而Linux的Bootloader可以同时支持Windows和Linux两种操作系统
- Windows:ntloader,仅是启动OS
- Linux:功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本
以下是一些我听说过的Linux的Boot loader:
- LILO:Linux Loader,早期的bootloader,功能单一
- grub:Grand Unified Bootloader,CentOS7以前使用grub1,CentOS7开始使用grub2
- spfdisk:只是知道有这么个玩意
2.2.3 Bootloader的启动过程(以grub1为例)
在MBR中的grub被识别到后,应到程序会根据grub.conf文件中的内容将内核加载到内存中

grub.conf中的三个重要参数:
- root:这一行指明了kernel与initrd所在的位置,即/boot的位置,hd0,0表示第一块磁盘的第一个分区
- kernel:指定了kernel的位置
- initrd:指定了initrd/initramfs的位置,这个文件被加载到内存中会模拟一个根目录,提供挂在真正的根目录所需的驱动程序与相关命令
需要注意的是,在修改grub.conf文件的时候,root、kernel、initrd这三行的顺序不可更改
2.3 加载kernel
kernel自身初始化过程
- 检测可识别到的所有硬件设备
- 加载硬件驱动程序
- 以只读的方式挂载根文件系统
- 运行用户空间的第一个应用程序:/sbin/init
Linux内核特点:
- 支持模块化:.ko(内核对象)
- 支持内核模块的动态装载和卸载
2.4 init初始化
2.4.1 init程序类型
注:再次声明,本文针对grub而不是更新的grub2
- SysV:init,CentOS 5之前
配置文件:/etc/inittab
- Upstart:init,CentOS 6
配置文件:/etc/inittab, /etc/init/*.conf
- Systemd:systemd,CentOS 7
配置文件:/usr/lib/systemd/system, /etc/systemd/system
在文件系统被挂在后,init进程会依据配置文件与sysinit文件对系统执行初始化操作
2.4.2 init运行级别
为系统的运行与维护,共设计了0-6共7个运行级别,分别是:
0:关机
1:单用户模式(root自动登录),single,维护模式
2:多用户模式,启动网络功能,但不启动NFS,维护模式
3:多用户模式,正常模式,控制台
4:预留级别
5:多用户模式,正常模式,图形化
6:重启
切换级别
init <0-6>
查看级别
[root@linux1 ~]# runlevel
1 3
[root@linux1 ~]# who -r
run-level 3 2024-04-24 05:25 last=1
[root@linux1 ~]#
2.4.3 sysinit
/etc/rc.d/rc.sysinit文件是一中存放了大量的初始化操作的脚本文件,主要用于完成以下几种初始化操作:
- 设置主机名
- 设置欢迎信息
- 激活udev和selinux
- 挂载/etc/fstab文件中定义的文件系统
- 检测根文件系统,并以rw的方式重新挂载根文件系统
- 设置系统时钟
- 激活swap设备
- 根据/etc/sysctl.conf文件设置内核参数
- 激活lvm和software raid设备
- 加载额外设备的驱动程序
- 清理操作
基于安全考虑,最好别修改这个文件
Ⅵ 加密算法简述
1 加密算法的分类
数据加密的基本过程是将原本的明文数据依照某种算法进行一定的处理,使之成为一段不可读的密文,只有通过相应的密钥与算法进行计算后才可显示出原文。而这个过程中的算法就是加密算法。
目前加密算法主要被分为两类,即对称加密和非对称加密两种,不过在这两种算法之外,还有一种比较特殊的算法——哈希算法。
2 对称加密
对称加密也叫私钥加密,是一种在加密和解密时使用同一个密钥的加密算法。
对称加密算法有着算法公开、计算量小、加密速度快、加密效率高的优点,但是由于加解密使用相同的密钥,其安全性无法得到足够的保障。
目前,对称加密算法主要有:DES、3DES、AES、Blowfish等。
3 非对称加密
非对称加密也叫公钥加密,在加密和解密时使用不同的密钥。一般在加密时使用公钥进行加密,再有对应的私钥进行解密。
由于两个密钥中,仅有公钥被公开,其相比于对称加密有着更高的安全性。但是非对称加密的密钥较长,算法复杂,在加解密效率上有一定的牺牲。
目前,主流的非对称加密算法有RSA、DSA、ECC等。
4 哈希算法
哈希算法也被称为散列算法,能将任意数据缩小成固定大小的摘要,是独立于对称加密和非对称加密两种算法之外的算法。
哈希算法有确定性、高效性、单向性、敏感性的特点,在完整性校验、快速查找等方面有着广泛的应用。
常见的哈希算法有md5、sha1、sha224、sha256、sha384、sha512几种。
Ⅶ CA与证书
1 CA证书体系
1.1 CA
CA(Certificate Authority,证书授权)是数字证书认证的权威机构,负责颁发数字证书。是数字签名的技术基础保障,也是网上实体身份的证明,能够证明某一实体的身份及其公钥的合法性,证明该实体与公钥二者之间的匹配关系。
简单的说,它是负责管理和签发证书的第三方机构,目的在于让通信双方安全的交换公钥。
1.2 数字证书
证书是数字签名的技术基础保障,也是网上实体身份的证明。它能够证明某一实体的身份及其公钥的合法性,并证明该实体与公钥二者之间的匹配关系。证书是公钥的载体,证书上的公钥与实体身份相绑定。在电子商务系统中,所有实体的证书都是由证书授权中心即CA中心颁发并签名的。有了CA证书,就能够明确对方的身份,用数字证书加密,通过数字签名的电子文件防篡改。
1.3 CA证书
顾名思义,CA证书就是由CA机构颁发的一种数字证书,它包含了证书拥有者的身份信息、公钥、私钥以及CA机构的签名,用于在互联网通讯中验证通信实体的身份和公钥和合法性。
1.4 自签名证书
1.4.1 自签名证书的基本概念
自签名证书是指由用户自己生成和签名的证书,而非有公认的证书颁发机构签名的证书。但自签名证书毕竟是免费且未经过权威机构签名,通常不受浏览器和客户端信任。
1.4.2 带或不带CA的自签名证书
另外在创建自签名证书的时候,用户可以自行选择是否带CA,这是他们的区别:
带CA的证书:
- 用户不仅生成了自己的证书,还创建了自己的CA,并使用该CA签名证书。也就是说用户建立了独立的CA环境。
- 由于创建了自己的CA环境,这类自签名证书的可信度相对高一点。
- 带CA的自签名证书具有较好的可扩展性,适用于需要多个证书,并且需要统一管理和验证的场景。
不带CA的证书:
- 用户仅仅创建了一个证书,并没有创建CA。也就是说这是一张独立的证书。
- 由于没有CA机构的认证,可信度相对较低。
- 不带CA的自签名证书适用于单一、简单的应用场景,如个人网站或测试环境。
1.5 SSL/TLS安全协议
1.5.1 SSL
SSL(Secure Socket Layer)安全套接层是Netscape公司率先采用的网络安全协议。它是在传输通信协议(TCP/IP)上实现的一种安全协议,采用公开密钥技术。SSL广泛支持各种类型的网络,同时提供三种基本的安全服务,它们都使用公开密钥技术。
目前,SSL拥有1.0,2.0,3.0三个版本,我们目前使用的基本为SSL 3.0
1.5.2 TLS
TLS(Transport Layer Security)安全传输层协议是IETF(Internet Engineering Task Force,Internet工程任务组)以SSL协议为基础制定的一种新的协议,它对SSL 3.0进行了标准化并添加了少量的机制。
目前TLS有1.0-1.3共四个版本,但许多浏览器对1.0和1.1两个版本似乎已经停止支持。
2 OpenSSL
2.1 OpenSSL简介
OpenSSL既是一个项目又是一个软件。作为软件,它是一个功能齐全的工具包,广泛应用于通用加密和安全通信。
OpenSSL包括了三个组件:
- libcrypto:用于实现加密和解密的库
- libssl:用于实现ssl通信协议的安全库
- openssl:多用途命令工具
2.2 OpenSSL命令
2.2.1 计算hash
计算文件hash
Command:
openssl <加密算法> <path>
Eg:
[root@linux1 ~]# openssl md5 /etc/passwd
MD5(/etc/passwd)= a6853410a57f452e867727b2f4bd2c1c
[root@linux1 ~]#
计算密码hash
Command:
openssl passwd [options] <password>
Options:
-in infile 从文件中读取密码
-salt val 使用指定的盐
-stdin 从标准输入读取密码
-6 基于SHA512的密码算法
-5 基于SHA256的密码算法
-1 基于MD5的密码算法
-crypt 标准Unix密码算法(默认选项)
-rand val Load the file(s) into the random number generator
-writerand outfile Write random data to the specified file
-rand val 将文件加载到随机数生成器中
-writer和 outfile 将随机数据写入指定文件
Eg:
[root@linux1 ~]# openssl passwd -6 123456
$6$ztBdEjF.bkuzswqI$jRXCp.L4TbcCLSkTtDDavjFrrHlco2xzOpNLFm51Ej7IWcL4d56m5wKtpFE1vj3mK97Ar6QJDKv85F6kZYRpo0
[root@linux1 ~]# echo 123456 | openssl passwd -6 -stdin
$6$M/I/9sEqeq0vidz8$3lUn6bwmJod4azF6z6GfgKLR5JvoTGhCRZbNxMLD9vbC2YiDmLE6naLx3OV76PcPJsga9sHdtKhw/nwta35Xx/
[root@linux1 ~]# openssl passwd -6 -salt M/I/9sEqeq0vidz8 123456
$6$M/I/9sEqeq0vidz8$3lUn6bwmJod4azF6z6GfgKLR5JvoTGhCRZbNxMLD9vbC2YiDmLE6naLx3OV76PcPJsga9sHdtKhw/nwta35Xx/
[root@linux1 ~]#
这里可以看到openssl passwd -6 123456和echo 123456 | openssl passwd -6 -stdin的返回值不一样,这是应为这条命令在计算hash的时候加入了一个叫做盐(salt)的参数,通过openssl passwd -6 -salt M/I/9sEqeq0vidz8 123456命令可以看出只要salt和passwd相同,计算出的hash是一样的。
2.2.2 生成随机数
Command:
openssl rand [-base64] [-hex] <num>
Eg:
[root@linux1 ~]# openssl rand -hex 3
af847d
[root@linux1 ~]# openssl rand -base64 4
AsTleg==
[root@linux1 ~]#
2.2.3 生成私钥和公钥
生成私钥
Command:
openssl genrsa -out <filename> [options] [私钥位数,默认2048]
Options:
-aes128, -aes192, -aes256, -des, -des3, -idea 使用符合密码复杂性的密码对私钥进行指定的加密
Eg:
[root@linux1 ~]# openssl genrsa -out /etc/ssl/test.key
Generating RSA private key, 2048 bit long modulus (2 primes)
..............................................................................................................................+++++
..........................................+++++
e is 65537 (0x010001)
[root@linux1 ~]# ls /etc/ssl
bak test.key
[root@linux1 ~]#
对私钥解密
如果在生成私钥的时候对私钥进行了加密,可以用下面的命令进行解密
Command:
openssl genrsa -in <filename1> -out <filename2>
Eg:
[root@linux1 ~]# openssl genrsa -aes128 -out test.key
Generating RSA private key, 2048 bit long modulus (2 primes)
.........................+++++
.....................................................................+++++
e is 65537 (0x010001)
Enter pass phrase for test.key:
Verifying - Enter pass phrase for test.key:
[root@linux1 ~]# openssl rsa -in test.key -out test1.key
Enter pass phrase for test.key:
writing RSA key
[root@linux1 ~]#
当然,不解密 也是可以的,就是有时候会麻烦一点,比如:
从私钥中提取公钥
Command:
openssl rsa -in <filename1> -pubout -out <filename2>
Eg:
[root@linux1 ~]# openssl rsa -in test.key -pubout -out test.key.pub
Enter pass phrase for test.key:
writing RSA key
[root@linux1 ~]# openssl rsa -in test1.key -pubout -out test1.key.pub
writing RSA key
[root@linux1 ~]#
2.3 建立私有CA实现证书申请颁发
2.3.1 建立私有CA
建目录和文件
由于没有默认生成CA证书根目录结构,所以我们需根据配置文件自行创建目录结构,然后再根据配置文件的要求,创建存放证书索引的index.txt和存放下一个证书的编号的serial这两个文件
[root@linux2 ~]# mkdir -p /etc/pki/CA/{certs,crl,newcerts,private}
# 如果懒的话 yum -y install openssl-* 或者 yum -y install openssl-perl 也可以
[root@linux2 ~]# cd /etc/pki/CA/
[root@linux2 CA]# touch index.txt
[root@linux2 CA]# echo 01 > serial
[root@linux2 CA]#
创建私钥
[root@linux2 CA]# openssl genrsa -out private/cakey.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
.........................................................................................+++++
.....................+++++
e is 65537 (0x010001)
[root@linux2 CA]#
生成自签名根证书
[root@linux2 CA]# openssl req -new -x509 -key private/cakey.pem -days 3650 -out cacert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN # 国家,使用国家的ISO 2代码
State or Province Name (full name) []:Zhejiang # 省
Locality Name (eg, city) [Default City]:Hangzhou # 市
Organization Name (eg, company) [Default Company Ltd]:test # 组织(公司)名
Organizational Unit Name (eg, section) []:test # 组织单位(部门)名
Common Name (eg, your name or your server's hostname) []:test.com #使用该证书的域名
Email Address []: # 邮箱,可以不填
[root@linux2 CA]#
选项说明
req 生成证书请求
-new: 生成新的证书签署请求
-x509: 专用于CA生成自签名证书
-key: 生成请求时的私钥
-days: 证书的有效期
-out: 证书的路径及名称
查看证书信息
openssl x509 -in /etc/pki/CA/cacert.pem -noout -text
需要注意的是,由于这是自签名证书,通常不受浏览器和客户端的信任,所以在使用是记得将其添加到【受信任的根证书颁发机构】之类的地方去
2.3.2 为用户颁发证书
生成给用户的私钥
[root@linux2 CA]# openssl genrsa -out /etc/ssl/test.key
Generating RSA private key, 2048 bit long modulus (2 primes)
...................................+++++
...............................+++++
e is 65537 (0x010001)
[root@linux2 CA]#
生成证书请求文件
[root@linux2 CA]# openssl genrsa -out /etc/ssl/test.key
Generating RSA private key, 2048 bit long modulus (2 primes)
...................................+++++
.......+++++
e is 65537 (0x010001)
[root@linux2 CA]# openssl req -new -key /etc/ssl/test.key -out /etc/ssl/test.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Zhejiang
Locality Name (eg, city) [Default City]:Hangzhou
Organization Name (eg, company) [Default Company Ltd]:test
Organizational Unit Name (eg, section) []:test
Common Name (eg, your name or your server's hostname) []:linux2.test.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@linux2 CA]#
签发证书
[root@linux2 CA]# openssl ca -in /etc/ssl/test.csr -out /etc/ssl/test.crt -days 1825Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Aug 6 12:07:20 2024 GMT
Not After : Aug 5 12:07:20 2029 GMT
Subject:
countryName = CN
stateOrProvinceName = Zhejiang
organizationName = test
organizationalUnitName = test
commonName = linux2.test.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
C6:24:43:01:A1:DD:17:ED:1B:F9:A8:B7:2F:4E:4E:6C:26:7A:70:B0
X509v3 Authority Key Identifier:
keyid:75:06:3A:B5:19:6F:93:BE:90:6D:24:88:54:0E:53:27:7E:49:78:35
Certificate is to be certified until Aug 5 12:07:20 2029 GMT (1825 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@linux2 CA]#
签发的证书会同时在/etc/pki/CA/newcerts目录下生成一个副本,编号就是serial这个文件中的数字
同时index.txt文件中也对签发的证书进行了记录
[root@linux2 CA]# diff /etc/pki/CA/newcerts/01.pem /etc/ssl/test.crt
[root@linux2 CA]# cat index.txt
V 290805120720Z 01 unknown /C=CN/ST=Zhejiang/O=test/OU=test/CN=linux2.test.com
[root@linux2 CA]#
2.3.3 吊销证书
查看证书的serial
Command:
openssl x509 -in <filename> -noout -serial -subject
Eg:
[root@linux2 CA]# openssl x509 -in /etc/ssl/test.crt -noout -serial -subject
serial=01
subject=C = CN, ST = Zhejiang, O = test, OU = test, CN = linux2.test.com
[root@linux2 CA]#
查看证书状态
Command:
openssl ca -status <serial>
Eg:
[root@linux2 CA]# openssl ca -status 01
Using configuration from /etc/pki/tls/openssl.cnf
01=Valid (V)
[root@linux2 CA]#
吊销证书
[root@linux2 CA]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem
Using configuration from /etc/pki/tls/openssl.cnf
Revoking Certificate 01.
Data Base Updated
[root@linux2 CA]# cat /etc/pki/CA/index.txt
R 290805120720Z 240806124812Z 01 unknown /C=CN/ST=Zhejiang/O=test/OU=test/CN=linux2.test.com
[root@linux2 CA]#
创建用于存放证书吊销列表编号的文件
[root@linux2 CA]# echo 01 > /etc/pki/CA/crlnumber
[root@linux2 CA]#
更新证书吊销列表
[root@linux2 CA]# openssl ca -gencrl -out /etc/pki/CA/crl.pem
Using configuration from /etc/pki/tls/openssl.cnf
[root@linux2 CA]#