第三周

一、C程序编译过程

C语言程序的编译主要经过四个过程:

# 分步骤编译运行
$ gcc -E hello.c -o hello.i    # 对hello.c文件进行预处理,生成hello.i文件
$ gcc -S hello.i -o hello.s    # 对预处理文件进行编译,生成汇编文件
$ gcc -C hello.s -o hello.o    # 对汇编文件进行编译,生成了目标文件
$ gcc hello.o hello            # 对目标文件进行链接,生成了可执行文件

# 一步实现编译过程
$ gcc hello.c -o hello         # 直接编译链接成可执行目标文件

二、包管理

RedHat 使用rpm作为包管理器,软件包为后缀名是rpm文件。

Debian 使用dpgk作为包管理器,软件包为后缀名是deb文件。

软件包通常存在依赖关系,为了能够正常运行,被依赖的包必须提前安装。软件包管理器可以自动解决依赖关系并提前安装好所有额外的软件包。

自动解决依赖关系软件包管理器:

  • dnf:红帽系列rpm包管理工具

  • apt-get:deb包管理工具

  • zypper:suse的rpm管理工具

获取软件包的途径:

  • 操作系统发行版本光盘
  • 文件服务器
  • 镜像站点

包管理命令

Action RedHat Debian
配置文件 /etc/yum.repos.d/*.repo /etc/apt/sources.list
日志 /var/log/dnf.log /var/log/dpkg.log
按名安装包 dnf install apt install
按名移除包 dnf remove apt remove
通过软件名、描述、简短描述来搜索包 dnf search apt search
查看可更新的包 dnf list --upgrades apt list --upgradable
升级包 dnf upgrade apt upgrade
清除本地缓存 dnf clean all apt autoclean
移除不再需要的依赖 dnf autoremove apt autoremove
将作为依赖安装的包指定为手动/依赖安装 dnf mark install | remove apt-mark manual | auto
仅下载而不安装包 dnf download apt download
显示指定包的信息 dnf info apt show
显示指定本地包信息 rpm -qi dpkg -s
显示本地包提供的文件 rpm -ql dpkg -L
显示远程包提供的文件 dnf repoquery -l apt-file list
查询提供某个文件的包(installed only) rpm -qf dpkg -S
查询提供某个文件的包(everything) dnf provides apt-file search
列出仓库所有的包 dnf list apt list
列出已经安装的包 dnf list --installed apt list --installed
显示本地所有的包 rpm -qa dpkg -l

三、搭建私有yum仓库

软件包存储在成为仓库(repository)的服务器上,基于C/S架构。可以利用Linux本地的软件包管理器(dnf,apt)来访问,在其搜索新的软件包,或是更新系统中已安装的软件包。

yum服务器的仓库可以多种形式存在:

  • file:// 本地路径

  • http://

  • https://

  • ftp://

搭建私有yum库

服务器:

# 安装http服务器
$ yum -y install httpd
# 创建仓库目录
$ mkdir -p /var/www/html/centos/8
# 将光盘的内容拷贝到仓库目录
$ mkdir /media/sr0
$ mount /dev/sr0 /media/sr0
$ cp -ar /media/sr0/* /var/www/html/centos/8

# 下载extras和epel源的包和元数据
$ yum reposync --repoid=extras --download-metadata -p /var/www/html/centos/8
$ yum reposync --repoid=epel --download-metadata -p /var/www/html/centos/8 
# 下载密钥
$ wget https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8 -P /var/www/html/centos/8/

# 启动httpd服务
$ systemctl enable --now httpd

客户端:

$ vim redhat.repo
[baseos]
name=baseos
baseurl=http://172.16.20.10/centos/8/BaseOS
enable=1
gpgcheck=1
gpgkey=http://172.16.20.10/centos/8/RPM-GPG-KEY-redhat-release

[appstream]
name=appstream
baseurl=http://172.16.20.10/centos/8/AppStream
enable=1
gpgcheck=1
gpgkey=http://172.16.20.10/centos/8/RPM-GPG-KEY-redhat-release

[extras]
name=extras
baseurl=http://172.16.20.10/centos/8/extras
enable=1
gpgcheck=0

[epel]
name=epel
baseurl=http://172.16.20.10/centos/8/epel
enable=1
gpgcheck=1
gpgkey=http://172.16.20.10/centos/8/RPM-GPG-KEY-EPEL-8

$ yum repolist 
repo id                   repo name                          status
appstream                 appstream                          4,795
baseos                    baseos                             1,662
extras                    extras                             38
epel                      epel                               8,955

四、常用初始化步骤

  1. 关闭SELinux

  2. 关闭防火墙

  3. 设置IP地址

  4. 设置yum仓库

  5. 安装常用软件包

    bash-completion vim-enhanced tree autofs gcc make git wget lrzsz sysstat psmisc tcpdump rsync lsof zip unzip bzip2 
    

五、一键安装http脚本

解读脚本

#!/bin/bash
#********************************************************************
#Author:            wangxiaochun
#QQ:                29308620
#Date:              2021-12-22
#FileName:          install_httpd.sh
#URL:               http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2021 All rights reserved
#********************************************************************
## 定义变量
# 获取cpu核心数
CPUS=`grep -c  processor /proc/cpuinfo`      
# httpd版本
HTTPD_VERSION=2.4.52    
# 安装目录
INSTALL_DIR=/apps/httpd    
# 设置颜色
COLOR="echo -e  \E[32;1m"         
END="\E[0m"

. /etc/os-release       # 导入文件 

# 如果ID是rocky或者centos,就执行下面的语句,否则就执行elif语句
if [ $ID = 'rocky' -o $ID = "centos" ];then
    # 关闭防火墙
    systemctl disable --now firewalld
    # 下载编译器、依赖包等工具
    yum -y install gcc make apr-devel apr-util-devel openssl-devel pcre-devel redhat-rpm-config bzip2
# 如果ID是ubuntu,就执行后面的语句,否则就打印"不支持此系统"并退出脚本。
elif  [ $ID = 'ubuntu' ];then
    # 升级包
    atp update
    # 安装编译器、依赖包
    apt -y  install  libapr*  libpcre3* libssl-dev make
else
    $COLOR"不支持此系统"$END
    exit
fi

# 进入目录
cd /usr/local/src
# 查询系统中是否存在wget包,如果不存在就下载wgwt
rpm -q wget || yum -y install wget
# 下载httpd源码,如果下载失败就打印"下载失败,退出"并退出脚本
wget https://dlcdn.apache.org//httpd/httpd-${HTTPD_VERSION}.tar.bz2  || { $COLOR "下载失败,退出" $END;exit ; }

# 解压包
tar xf httpd-${HTTPD_VERSION}.tar.bz2
# 进入解压后的目录
cd httpd-${HTTPD_VERSION}
# 执行configure脚本
./configure --prefix=${INSTALL_DIR} --enable-ssl  --disable-status
# 开始编译,然后生成相应目录文件
make -j $CPUS && make install
# 创建软链接
ln -s /apps/httpd/bin/apachectl  /usr/local/bin/
# 启动apachectl,如果启动成功就打印"安装成功"
apachectl start && $COLOR"安装成功!"$END
# 打印主页url
$COLOR"请访问:http://`hostname -I`"$END

一键安装httpd脚本

#!/bin/bash
Download_DIR=/usr/local/src
Install_DIR=/apps/httpd
Httpd_VERSION=$1
CPU=$(cat /proc/cpuinfo | grep -c processor)
[ -d $Install_DIR ] || mkdir -p $Install_DIR

download () {
  . /etc/os-release
  if [ $ID == "rocky" -o $ID == "centos" ];then
	  rpm -q wget &> /dev/null || dnf -y install wget
	  yum -y install gcc make apr-devel apr-util-devel openssl-devel pcre-devel redhat-rpm-config
  elif [ $ID == "ubuntu" ];then
	  dpkg -s wget || apt -y install wget
	  apt -y  install  libapr*  libpcre3* libssl-dev make
  else 
	  echo "不支持该系统,退出"
	  exit
  fi
  
  systemctl disable --now firewalld &> /dev/null
  wget https://archive.apache.org/dist/httpd/httpd-${Httpd_VERSION}.tar.gz -P ${Download_DIR} || { echo "下载失败,退出脚本";exit;  }
}

install () {
  cd $Download_DIR
  tar xf httpd-${Httpd_VERSION}.tar.gz
  cd httpd-${Httpd_VERSION}
  ./configure --prefix=${Install_DIR} --enable-ssl  --disable-status
  make -j $CPU && make install
  ln -s ${Install_DIR}/bin/* /usr/local/bin/
}

start () {
  apachectl start && echo "安装成功"
  echo "请访问:http://$(hostname -I | awk '{print $1}')"  
}

download

install

start

六、OSI参考模型

基本单位 功能 协议
应用层 报文 为应用程序提供服务并制定应用程序中通信的相关细节 HTTP,TLS,FTP,DNS,SMTP
表示层 报文 负责格式的转换,压缩与解压缩,加密与解密
会话层 报文 负责建立与断开通信连接
传输层 报文分组 提供端到端的、可靠的或不可靠的传输 TCP,UDP
网络层 数据包 负责IP寻址,路由选择,IP分包和组包 IPv4,IPv6,ARP,ICMP,IPSec
数据链路层 数据帧 负责MAC寻址,将比特流转换为具有意义的数据帧 Ethernet,PPP,PPPoE,HDLC
物理层 比特 负责比特流与高低电平之间的转换 IEEE802.3,FDDI

七、 调整动态端口

Q:调整动态端口范围为20000-60000

查看端口范围:

$ cat /proc/sys/net/ipv4/ip_local_port_range
32768	60999

修改端口范围:

# 临时修改
$ sysctl net.ipv4.ip_local_port_range="20000 60000"

# 永久生效
$ sysctl net.ipv4.ip_local_port_range="20000 60000" >> /etc/sysctl.conf

八、TCP

TCP首部结构

   +-------------------------------+-------------------------------+
   |          Source Port          |       Destination Port        |
   +-------------------------------+-------------------------------+
   |                        Sequence Number                        |
   +---------------------------------------------------------------+
   |                    Acknowledgment Number                      |
   +-------+-----------+-+-+-+-+-+-+-------------------------------+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-------+-----------+-+-+-+-+-+-+-------------------------------+
   |           Checksum            |         Urgent Pointer        |
   +-------------------------------+---------------+---------------+
   |                    Options                    |    Padding    |
   +-----------------------------------------------+---------------+
   |                             data                              |
   +---------------------------------------------------------------+
字段 长度(bit) 含义
Source Port 16 源端口,标识哪个应用程序发送
Destination Port 16 目的端口,标识哪个应用程序接收
Sequence Number 32 序列号。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号
Acknowledgment Number 32 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效
Data Offset 4 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节
Reserved 6 保留,必须填0
URG 1 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
ACK 1 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效
PSH 1 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付
RST 1 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接
SYN 1 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求
FIN 1 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接
Window 16 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端期望接收的字节数。窗口最大为65535字节
Checksum 16 校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部
Urgent Pointer 16 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)
Options 可变 选项字段
Padding 可变 填充字段,用来补位,使整个首部长度是4字节的整数倍
data 可变 TCP负载

TCP三次握手

TCP四次挥手

九、主机到主机的包的传递过程

主机A的IP地址为10.0.0.1/24,主机B为10.0.0.2/24。

下面是主机A向主机B发起ping请求的过程:

由于两台主机处于同一个网络中,主机A向主机B发起ARP请求报文,然后主机B向主机A返回自己的MAC地址。主机A封装ICMP报文,源MAC是自己,目的MAC是主机B,源IP是自己,目的IP是主机B。主机B收到数据包后进行解包,发现源MAC是自己,继续解包,再次看到目的IP是自己,然后封装ICMP报文返回给主机A。至此双方完成一次通信。

十、IP地址的分类

IP地址=网络位+主机位,全1为网络位,全0为主机位。

A类:1 - 126

Lo: 127

B类:128 - 191

C类:192 - 223

D类:224 - 239

E类:240 - 255

十一、掩码计算

Q:201.222.200.111/18 主机数?子网掩码?

11111111.11111111.11000000.00000000    => 255.255.192.0

网络地址和广播地址不可用,所以可容纳2^14 - 2=16382台主机

子网掩码是255.255.192.0

十二、如何判断是否在同一个网段

Q:当A(10.0.1.1/16)与B(10.0.2.2/24)通信,A如何判断是否在同一个网段?A和B能否通信?

假设两台主机在同一个广播域中

  1. A向B发起ping请求,首先A用自己的掩码与B的IP地址做与运算:
11111111.11111111.00000000.00000000
00001010.00000000.00000010.00000010
00001010.00000000.00000000.00000000  ==> 10.0
  1. 得到的结果与自己的网络位(10.0)一样,所以A就判断和B是在同一个网段。然后A就会发送ARP请求报文获取B的MAC地址。由于A和B在同一个广播域中,B自然会收到A的ARP请求。

  1. 当B收到A的ARP请求后,就会向A回应自己的MAC地址。A获取到B的MAC后,接着向B发送ICMP包,源IP是自己,目的IP是B。

  2. B收到数据包后,用自己的掩码与目的(A)IP地址做与运算:

11111111.11111111.11111111.00000000
00001010.00000000.00000001.00000001
00001010.00000000.00000001.00000000  ==> 10.0.1
  1. 得到的结果与自己的网络位(10.0.2)不一样,由于B主机没有设置网关,所以将包丢弃。

所以,当两台主机在同一个广播域,A不能与B通信。

十三、将10.0.0.0/8划分32个子网

8位子网掩码换算成二进制如下:

11111111.00000000.00000000.00000000

由于2的5次方是32,所以网络位需要向主机位借5位:

11111111.11111000.00000000.00000000 ==> 255.248.0.0 

所以每个子网的掩码是:255.248.0.0 。

每个子网可容纳2^19-2=524286台主机。

十四、设置IP地址

# 为一个设备名为eth0的网卡添加一个名为eth0的网卡名
$ nmcli connection add con-name eth0 ifname eth0 type ethernet 
Connection 'eth0' (3c3ceeac-ec30-438d-8404-ccaf6dc9b4bf) successfully added.
# 设置eth0网卡,IP地址设置为手动,依此设置IP地址,网关,dns
$ nmcli connection modify eth0 ipv4.method manual ipv4.addresses 172.16.20.80/24 ipv4.gateway 172.16.20.254 ipv4.dns 172.16.20.254
# 开启网卡
$ nmcli connection up eth0 
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/132)
# 查看网卡状态
$ nmcli connection show 
NAME                UUID                                  TYPE      DEVICE     
eth0                3c3ceeac-ec30-438d-8404-ccaf6dc9b4bf  ethernet  eth0  
# 测试
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=72.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=72.7 ms

十五、网卡配置文件解析

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 
TYPE=Ethernet          # 设备类型
PROXY_METHOD=none      # 代理
BROWSER_ONLY=no        # 仅浏览器
BOOTPROTO=none         # IP地址获取方式
DEFROUTE=yes           # 默认路由
IPV4_FAILURE_FATAL=no    # 是否开启错误检查
NAME=eth0                # 网卡逻辑名
UUID=e2af7ace-b863-4605-9db1-5d4ab83fb4a5   # UUID标识
DEVICE=eth0              # 设备名
ONBOOT=yes               # 开机自动激活
IPADDR=172.16.20.80      # IP地址
PREFIX=24                # 掩码
GATEWAY=172.16.20.254    # 网关
DNS1=172.16.20.254       # DNS服务器

十六、配置bind0

# 添加bond0设备,模式为轮询
$ nmcli connection add con-name bond0 ifname bond0 type bond bond.options mode=0
Connection 'bond0' (67d29733-8f6c-482b-83f0-be30e138bbac) successfully added.
# 将eth1添加至bond0
$ nmcli connection add con-name bond-port1 ifname eth1 type ethernet slave-type bond master bond0 
Connection 'bond-port1' (678095af-017c-4612-b868-4f1efb61aac6) successfully added.
# 将eth2添加至bond0
$ nmcli connection add con-name bond-port2 ifname eth2 type ethernet slave-type bond master bond0 
Connection 'bond-port2' (2a9d7639-1e3c-4d6e-a9a9-cf9f6f4a8866) successfully added.
# 设置bond0地址
$ nmcli connection modify bond0 ipv4.addresses 172.16.20.100/24
# 启动bond0设备
$ nmcli connection up bond0

测试:

关闭一个网卡

$ ip link set eth1 down

没有影响

[C:\~]$ ping 172.16.20.100 -t

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

十七、shell

17.1 通过ifconfig命令查找IP

$ ifconfig | grep "inet " | awk '{print $2}' 
172.17.0.1
172.16.20.81
127.0.0.1

17.2 扫描主机

#!/bin/bash
NET=172.16.20
for i in {1..254};do 
	{ 
		ping -c1 -W1 172.16.20.$i &> /dev/null && echo "172.16.20.$i is up" || echo "172.16.20.$i is down" 
	}&
done
wait

17.3 计算所有用户ID的和

#!/bin/bash
ALL_UID=0
while read line;do 
    let UID_ALL+=$(echo $line | awk -F: '{print $3}')
done < /etc/passwd
echo $ALL_UID
posted @ 2023-01-15 23:10  fengkm  阅读(165)  评论(0编辑  收藏  举报