个人博客
https://blog.youkuaiyun.com/cPen_web
传输层的作用
IP层提供点到点的连接 (网络层)
传输层提供端到端的连接 (端口)
端到端 --> 端口到端口
程序 --> 进程 --> 占用一个端口 --> 对外提供服务
QQ (应用层)
我们的电脑安装的qq的客户端 58759 ----> QQ服务器端:8000
客户 ----> 商家
传输层的协议
HTTP 采用TCP (追求稳定可靠,数据不能丢失)
QQ 采用UDP
即时通信 --> 速度 --> 效率高 --> udp
dns --> 域名解析服务 --> 平常的域名解析 --> 速度快 --> udp
主域名服务器和从域名服务器之间复制数据 --> 可靠性 --> tcp
TCP
源端口号 目标端口号 (重点)
序列号
确认号
序列号:给每个发送的数据段进行编号的
确认号:告诉对方哪个数据段之前的数据都收到了
6个控制位(标志位)
紧急位 urg 与16位紧急指针配合使用
确认位 ack 1表明该数据包包含确认信息
完成位 finish 为1时,数据发送完毕,请求断开连接
同步位 syn 为1时,请求建立连接
push 通知接收端立即将数据提交给用户进程,不在缓存中停留,等待更多的数据
重置位 reset 为1时,请求重新建立TCP连接
窗口大小
窗口大小 滑动窗口的大小,指明本地可接收数据的字节数
窗口 --> window --> 表示本机可以接受多少数据,这个值是可以变化的,主要是告诉对方,防止对方发送过多的数据过来,表示数据处理不了,丢失数据
端口号的范围:0~65535
一般用到的是1到65535,其中0不使用,1-1023为系统端口,也叫BSD保留端口;
1024-65535为用户端口,又分为 BSD临时端口(1024-5000)和BSD服务器(非特权)端口(5001-65535).
0-1023 BSD保留端口,也叫系统端口,这些端口只有系统特许的进程才能使用;
1024-5000 BSD临时端口,一般的应用程序使用1024到4999来进行通讯;
5001-65535 BSD服务器(非特权)端口,用来给用户自定义端口.
tcp:可靠,面向连接 --> 效率低
三次握手、四次断开 --> 面向连接
各种计时器 --> 可靠
udp:不可靠,无连接 --> 速度快,效率高
窗口 --> window -->
表示本机可以接受多少数据,这个值是可以变化的,主要是告诉对方,防止对方发送过多的数据过来,表示数据处理不了,丢失数据
三次握手、四次断开
tcp方式在正式传送数据之前,必须要建立连接(3次握手)
[root@cPen_A ~]# netstat -anplut
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 710/rpcbind
LISTEN 监听
ESTABLISHED 建立连接 --> 3次握手完成就是ESTABLISHED
netstat 是用来查看网络的状态 --> 开放的网络端口的情况
[root@cPen_A ~]# netstat -anplut
选项 | 解释 |
---|---|
-a | 显示所有的内容 all |
-n | 以数字的形式显示 number |
-u | udp相关的 |
-t | tcp相关的 |
-l | 处于listen状态的内容 listen |
-p | 相关程序的名字 program |
TCP的连接 – 三次握手
tcp方式在正式传送数据之前,必须要建立连接(3次握手)
2台电脑,hostA (client)、hostB (server)。大多数情况,客户机优先访问服务器,除非一些木马病毒、弹窗广告
HostA Chrome浏览器访问百度 HostB,HostA向HostB 发送简历连接的请求,因为SYN号(同步位)置为1
HostB回复。这时HostB ack号(确认号)是101,告诉HostA 当时编号是100的已经收到了,此时SYN号置为1(请求建立连接),ACK号(确认号)置为1
这时HostA收到回复,ack号为301,告诉HostB当时300的已经收到了;在ACK位(确认位)置为1,第2次发包时,SYN号就不需要置为1了,因为已经确认建立连接了
TCP的四次断开
HostA向HostB 发送断开请求;FIN位 置为1,ACK位 置为1;序列号假设为101,ack号假设为301……;client端状态变成FIN_WAIT_1
HostB发送2个包(ACK、FIN),序列号都为301,ack号为102,ACK位 置为1……;;client端状态变成FIN_WAIT_2;客户端会进入CLSOE_WAIT --> LAST-ACK状态
HostA发送确认包,序列号102,ack号302,ACK位置为1;client端状态 TIME-WAIT --> TIME-WAIT ;server端状态CLOSED
是谁先发起断开的请求?(四次断开)
答:client和server都可以
为什么要等2个MSL? (报文最大生存时间)
答:防止最后发的确认包在网络上丢掉,会重传一次
Time-wait状态(2MSL)一些理解
https://blog.youkuaiyun.com/overstack/article/details/8833894
nginx服务器
time-wait比较多,是什么原因?
说明nginx服务器主动大量的断开客户端的连接
谁发起断开请求,time-wait状态就在哪边
last-ack是出现在被断开的一方
last-ack 非常多说明出现了什么问题?
说大量的客户端和服务器断开连接
示例:模拟大量访问请求
[root@cPen-client ~]# vim test.sh
for i in {1..10000} #注:瞬间起1万个进程去访问
do
curl http://192.168.1.5:80 & #注:curl访问结束后,会主动发起断开
done
keepalive timeout 65 检测死连接 (NGINX服务,web业务 有超时的设置,服务器会主动断开连接;用户超时65s)
用户点网页的x,客户端主动断开连接
TCP的差错控制
校验和
确认
超时
确认 就是 各种计时器
TCP的计时器
体现 可靠性
重传计时器 --> 重新发送一次数据,确保数据可以收到
坚持计时器 --> 为了防止零窗口死锁
保活计时器 --> 防止两个TCP之间的连接长时间的空闲
时间等待计时器 --> 连接终止期间使用的
在发送了最后一个ACK后,不立即关闭连接,而是等待一段时间(2MSL),保证能接收到重复的FIN数据段。
在TCP中如何防止数据段的丢失?
答:重传计时器
如果接收方的缓存已经满了,接收方会向发送方发送什么样的确认信息?发送信方收到后会怎么处理?
答:接收方 发送窗口值为0的消息。发送方 发送坚持计时器,防止零窗口死锁
TCP的流控机制
TCP的流控机制 - 滑动窗口
滑动窗口是2台电脑之间的信息传递 --> 2台电脑能收发的数据量
TCP的流控机制 - 拥塞控制
拥塞控制 --> 整个2台电脑之间的链路可以传递多少数据的问题,是否拥塞的问题--> 看中间传输网络可以传输的数据量
四个算法为"慢启动,拥塞避免,拥塞发生时算法和快速恢复"
拥塞控制算法
https://zhuanlan.zhihu.com/p/114463223
https://blog.youkuaiyun.com/lishanmin11/article/details/77165077
https://baijiahao.baidu.com/s?id=1664395039305097355&wfr=spider&for=pc
TCP的应用
服务 | 端口 |
---|---|
http | 80 |
https | 443 |
ftp | 21 |
dns | 53 |
ssh | 22 |
mysql | 3306 |
示例:常见的服务对应的端口
[root@cPen_aliyun ~]# cat /etc/services
[root@cPen_aliyun ~]# cat /etc/services |egrep "^ntp" #注:网络时间服务
ntp 123/tcp
ntp 123/udp # Network Time Protocol
UDP
UDP服务器端的端口号
server 端口 | 协议 | 说明 |
---|---|---|
69 | TFTP | 简单文件传输协议 |
53 | DNS | 域名服务 |
123 | NTP | 网络时间协议 |
111 | RPC | 远程过程调用 |
8000 | ||
67 | DHCP | 动态主机配置协议 |
QQ消息没有发生出去,它是如何知道的呢?为什么QQ消息传递时仍然采用采用udp?
答:怎么做差错控制?通过上层协议解决(应用层 QQ本身解决);QQ可以应用层上去弥补
示例:查看哪些服务/协议采用的端口号
[root@cPen_A ~]# cat /etc/services
[root@cPen_A ~]# cat /etc/services |grep http
tcp和udp的区别
TCP面向连接 --> 三次握手、四次断开(挥手)
可靠 --> 各自计时器、差错控制
UDP的封装格式里有16位UDP校验和,所以UDP可以提供差错控制,但是没有各种计时器,没有tcp可靠
相关工具
dstat
dstat监控工具 查看网络流量(带宽) (Python写的)
[root@cPen_A ~]# yum install dstat -y #注:安装dstat
[root@cPen_A ~]# dstat #注:运行dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
2 2 91 5 0 0| 682k 332k| 0 0 | 0 0 | 386 854
#注:net recv 接收了多少数据;send 发送了多少数据
#注:带宽是否跑满,dstat可以查看
选项:-am 显示内存的使用
[root@cPen_A ~]# dstat -am #注:显示内存的使用,a更多 all;m 内存
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- ------memory-usage-----
usr sys idl wai hiq siq| read writ| recv send| in out | int csw | used buff cach free
1 2 94 3 0 0| 477k 232k| 0 0 | 0 0 | 297 631 | 182M 2108k 210M 3376M
#注:usr用户进程所消耗的cpu;sys系统进程……;idl空闲的;paging 交换分区的使用
[root@cPen_A ~]# dstat --help #注:查看帮助手册
[root@cPen_A ~]# dstat -am -N ens33,ens37 #注:查看ens33和ens37网卡的流量(带宽) -N
----total-cpu-usage---- -dsk/total- -net/ens33---net/ens37- ---paging-- ---system-- ------memory-usage-----
usr sys idl wai hiq siq| read writ| recv send: recv send| in out | int csw | used buff cach free
1 1 96 2 0 0| 286k 139k| 0 0 : 0 0 | 0 0 | 214 424 | 181M 2108k 210M 3377M
0 0 100 0 0 0| 0 0 | 120B 1154B: 0 0 | 0 0 | 91 116 | 181M 2108k 210M 3377M
机器里开放的端口越多越好,还是越少越好?
答:越少越好
端口 --> 进程 --> 服务 --> 程序 --> 漏洞、bug、安全上的不足
netstat
本机开放了哪些端口
开放的所有的端口
[root@nginx1 ~]# yum install net-tools -y
[root@nginx1 ~]# netstat -anplut
lsof
查看哪个端口被哪个进程占用了
查看某个进程打开了哪些文件
或者是哪个文件夹被哪个进程打开
[root@cPen_A ~]# yum install lsof -y
示例:哪个端口被哪个进程占用了
[root@cPen_A ~]# lsof -i:22 #注:查看单个端口
示例:查看哪个文件夹被哪个进程打开
[root@cPen_A ~]# lsof /root/ #注:接文件夹
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 1568 root cwd DIR 253,0 4096 33574977 /root
vim 1816 root cwd DIR 253,0 4096 33574977 /root
lsof 1817 root cwd DIR 253,0 4096 33574977 /root
示例:查看某个进程打开了哪些文件、加载库、依赖关系
[root@cPen_A ~]# ps aux|grep vim
root 1816 0.0 0.1 149624 5180 pts/1 S+ 14:51 0:00 vim c.txt
root 1820 0.0 0.0 112824 976 pts/0 S+ 14:52 0:00 grep --color=auto vim
[root@cPen_A ~]# lsof -p 1816 #注:-p 接pid号(进程号)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
vim 1816 root cwd DIR 253,0 4096 33574977 /root
vim 1816 root rtd DIR 253,0 4096 64 /
vim 1816 root txt REG 253,0 2337192 51039749 /usr/bin/vim
示例:本机上,查看端口是否被占用 (可以写进脚本)
[root@cPen_C ~]# lsof -i:8080
[root@cPen_C ~]# echo $? #注:端口未被占用的话,$?为1
1
[root@cPen_C ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1255 root 6u IPv4 20454 0t0 TCP *:http (LISTEN)
nginx 1258 lihu 6u IPv4 20454 0t0 TCP *:http (LISTEN)
[root@cPen_C ~]# echo $? #注:端口未被占用的话,$?为1
0
lsof netstat 都是在本机上看的,如何知道别人的机器开启了哪些端口? (扫描工具)
答:nc、nmap
如何知道别的机器上开放了80端口?
1. nc #注:扫描嗅探其他的机器开放了哪个端口
2. curl等浏览器访问
-z 不进行数据交换,只是检测连接状态 zero
curl
示例:curl
[root@cPen_A ~]# curl 192.168.1.6
……
[root@nginx1 ~]# echo $?
0
nc
示例:nc
[root@cPen_A ~]# yum install nc -y
[root@cPen_A ~]# nc -z 192.168.1.6 80 #注:探测192.168.1.6是否开放80端口
[root@cPen_A ~]# echo $? #注:通过看$?,如果返回值为0 表示开放
0
[root@cPen_A ~]# nc -z 192.168.1.6 22
[root@cPen_A ~]# echo $? #注:非0 表示未开放
1
nmap
示例:namp
#注:探测一台机器或者整个局域网里机器开放了哪些端口(更广些)
[root@cPen_A ~]# yum install nmap -y
[root@cPen_A ~]# nmap 192.168.1.6
[root@cPen_A ~]# nmap 192.168.1.0/24 #注:扫描整个局域网
glances
glances 看一些网络流量 (CPU、内存、交换分区、网卡流量、磁盘IO)(python写的),跟dstat很像,比dstat好,跟windows里任务管理器很像
[root@cPen_A ~]# yum install epel-release
[root@cPen_A ~]# yum install glances -y
[root@cPen_A ~]# glances
#注:按q退出
tcpdump
如何知道用户访问过来了,还是没有访问过来?
答: 1. 看日志;2. 抓包
示例:看日志
[root@cPen_A ~]# cd /var/log/nginx/
[root@cPen_A nginx]# ls
access.log error.log
[root@cPen_A nginx]# tail -f access.log
示例:抓包 如下
tcpdump 字符界面的抓包工具
tcpdump - dump traffic on a network #注:导出网络流量的工具
https://www.cnblogs.com/lvdongjie/p/10911564.html
https://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html
[root@cPen_C ~]# yum install tcpdump -y
[root@cPen_C ~]# tcpdump -i ens33 -p tcp and port 80 #注:-i 接口 ;-p 协议;port 端口号
[root@cPen_C ~]# tcpdump -i ens33 -p tcp and port 80 -n #注:-n 以数字形式展示
示例:抓ping包
[root@cPen_A ~]# ping 192.168.1.6 -c4
[root@cPen_C ~]# tcpdump -i ens33 -p icmp -n
参数 | |
---|---|
src host | 源主机 --> 源ip source |
dst host | 目的主机 --> 目的ip destination |
src net | 源网段 192.168.10.0/24 |
dst net | 目的网段 |
[root@cPen_A ~]# tcpdump -i ens33 host 192.168.0.100 #注:接ip
[root@cPen_A ~]# tcpdump -i ens33 src host 192.168.0.100 #注:源ip
[root@cPen_A ~]# tcpdump -i ens33 dst host 192.168.0.100 #注:目的ip
[root@cPen_A ~]# tcpdump -i ens33 src host 192.168.0.100 and dst port 80 #注:源ip 目的端口
#注:源ip为192.168.0.100 访问本机80端口的数据包
抓包时关注
协议: tcp、udp、icmp、arp等网络层和传输层
-p tcp
-p icmp
-p arp
ip地址:源ip和目的ip
端口号:源端口和目的端口
src port
dst port
mac地址:源mac和目的mac
[root@cPen_A ~]# tcpdump -i ens33 -p arp #注:抓arp协议
选项:-w
# -w ./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析
[root@cPen_A ~]# tcpdump -i ens33 src host 192.168.0.100 and tcp dst port 80 -w feng.cap
选项:-v或 -vv 显示的信息更加详细
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
# 1.使用tcpdump抓包从ens33接口接入的来自192.168.99.1这台电脑访问本机80端口的数据包
[root@cPen_A ~]# tcpdump -i ens33 src host 192.168.99.1 and dst port 80
# 2.抓取所有的从ens33接口进来的ping包
[root@cPen_A ~]# tcpdump -i ens33 -p icmp
# 3.抓取所有从ens3接口进来的arp包
[root@cPen_A ~]# tcpdump -i ens33 -p arp
# 4.使用tcpdump抓包从ens33接口接入的来自192.168.33.1这台电脑访问本机3306端口的数据包
[root@cPen_A ~]# tcpdump -i ens33 src host 192.168.33.1 and dst port 3306
网络方面的攻击 攻击类型
dos
DoS是Denial of Service的简称,即拒绝服务攻击
ddos
DDOS攻击一般指分布式拒绝服务攻击
分布式拒绝服务(Distributed Denial of Service)
cc
攻击者借助代理服务器生成指向受害主机的合法请求,实现DDOS和伪装就叫:CC(Challenge Collapsar)
解决方法
1. 封ip
- 1.1 iptables
[root@cPen_firewall ~]# vim deny_ip.sh
#!/bin/bash
#获取访问量最大的5个ip地址
for i in $(cat /var/log/nginx/access.log|awk '{print $1}'|sort |uniq -c|sort -rn|head -5|awk '{print $2}')
do
iptables -A INPUT -s $i -p tcp --dport 80 -j DROP
done
- 1.2 nginx里可以限制连接数,下载速度
2. 加服务器
3. 购买专业的流量清洗服务
4. 报警