1、tcpdump抓包
文章图片
文章图片
# -nn ,表示不解析抓包中的域名(即不反向解析)、协议以及端口号。
$ tcpdump -nn udp port 53 or host 35.190.27.188
$ tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap
$ scp host-ip/path/ping.pcap .
# 直接使用域名抓包
tcpdump -nn host example.com -w web.pcap计算丢包率
capinfos viaLB.pcap
tshark -n -q -r viaLB.pcap -z "io,stat,0,tcp.analysis.retransmission"
==========================================================
| IO Statistics|
||
| Interval size: 297.6 secs (dur)|
| Col 1: Frames and bytes|
|2: tcp.analysis.retransmission|
|--------------------------------------------------------|
||1|2|
| Interval| Frames |Bytes| Frames |Bytes|
|--------------------------------------------------------|
|0.0 <> 297.6 |88792 | 115995270 |2350 | 3093460 |
==========================================================
#查看网络连接
watch --diff netstat -s
netstat -ant |awk '{++a[$6]} END{for (i in a) print i, a[i]}'
ss -ant | awk '{++s[$1]}END{for(k in s) print k,s[k]}'
watch -d ethtool -S ens33
# 查看抓包文件的状态码详情
tshark -r lesson17-in-shorten.pcap -T fields -e http.response.code |
grep -v ^$ | sort | uniq -c | sort -r
2、syn攻击 2.1、服务端启动nginx监听80端口
# 运行Nginx服务并对外开放80端口
# --network=host表示使用主机网络(这是为了方便后面排查问题)
$ docker run -itd --name=nginx --network=host nginx
2.2、在其他终端用curl测试
# -w表示只输出HTTP状态码及总时间,-o表示将响应重定向到/dev/null
$ curl -s -w 'Http code: %{http_code}\nTotal time:%{time_total}s\n' -o /dev/null http://192.168.0.30/
...
Http code: 200
Total time:0.002s
2.3、模拟dos攻击
# -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80
# -i u10表示每隔10微秒发送一个网络帧
$ hping3 -S -p 80 -i u10 192.168.0.30
现在,再回到终端一,你就会发现,现在不管执行什么命令,都慢了很多。不过,在实践时要注意:
- 如果你的现象不那么明显,那么请尝试把参数里面的 u10 调小(比如调成 u1),或者加上–flood
选项; - 如果你的终端一完全没有响应了,那么请适当调大 u10(比如调成 u30),否则后面就不能通过 SSH 操作 VM1。
2.4、模拟正常请求
# --connect-timeout表示连接超时时间
$ curl -w 'Http code: %{http_code}\nTotal time:%{time_total}s\n' -o /dev/null --connect-timeout 10 http://192.168.0.30
...
Http code: 000
Total time:10.001s
curl: (28) Connection timed out after 10000 milliseconds
2.5、查看网络数据包情况
$ sar -n DEV 1
08:55:49IFACErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil
08:55:50docker00.000.000.000.000.000.000.000.00
08:55:50eth022274.00629.001174.6437.780.000.000.000.02
08:55:50lo0.000.000.000.000.000.000.000.00
从这次 sar 的输出中,你可以看到,网络接收的 PPS 已经达到了 20000 多,但是 BPS 却只有 1174 kB,这样每个包的大小就只有 54B(1174*1024/22274=54)。
2.6、tcpdump抓包
# -i eth0 只抓取eth0网卡,-n不解析协议名和主机名
# tcp port 80表示只抓取tcp协议并且端口号为80的网络帧
$ tcpdump -i eth0 -n tcp port 80
09:15:48.287047 IP 192.168.0.2.27095 > 192.168.0.30: Flags [S], seq 1288268370, win 512, length 0
09:15:48.287050 IP 192.168.0.2.27131 > 192.168.0.30: Flags [S], seq 2084255254, win 512, length 0
09:15:48.287052 IP 192.168.0.2.27116 > 192.168.0.30: Flags [S], seq 677393791, win 512, length 0
09:15:48.287055 IP 192.168.0.2.27141 > 192.168.0.30: Flags [S], seq 1276451587, win 512, length 0
09:15:48.287068 IP 192.168.0.2.27154 > 192.168.0.30: Flags [S], seq 1851495339, win 512, length 0
...
这个输出中,Flags [S] 表示这是一个 SYN 包。大量的 SYN 包表明,这是一个 SYN Flood 攻击。如果你用上一节讲过的 Wireshark 来观察,则可以更直观地看到 SYN Flood 的过程:
2.7、netstat查看网络连接情况
# -n表示不解析名字,-p表示显示连接所属进程
$ netstat -n -p | grep SYN_REC
tcp00 192.168.0.30:80192.168.0.2:12503SYN_RECV-
tcp00 192.168.0.30:80192.168.0.2:13502SYN_RECV-
tcp00 192.168.0.30:80192.168.0.2:15256SYN_RECV-
tcp00 192.168.0.30:80192.168.0.2:18117SYN_RECV-
...
2.8、统计syn
netstat -ant | awk '{++a[$6]} END {for (i in a) print i,a[i]}'
$ netstat -n -p | grep SYN_REC | wc -l
193
2.9、使用iptables防御dos
$ iptables -I INPUT -s 192.168.0.2 -p tcp -j REJECT
hping3 命令中,–rand-source 选项,来随机化源 IP
可以用以下两种方法,来限制 syn 包的速率:
# 限制syn并发数为每秒1次
$ iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT# 限制单个IP在60秒新建立的连接数为10
$ iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT
默认的半连接容量只有 256:
$ sysctl net.ipv4.tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 256
换句话说, SYN 包数再稍微增大一些,就不能 SSH 登录机器了。 所以,你还应该增大半连接的容量,比如,你可以用下面的命令,将其增大为 1024:
$ sysctl -w net.ipv4.tcp_max_syn_backlog=1024
net.ipv4.tcp_max_syn_backlog = 1024
另外,连接每个 SYN_RECV 时,如果失败的话,内核还会自动重试,并且默认的重试次数是 5 次。你可以执行下面的命令,将其减小为 1 次:
$ sysctl -w net.ipv4.tcp_synack_retries=1
net.ipv4.tcp_synack_retries = 1
除此之外,TCP SYN Cookies 也是一种专门防御 SYN Flood 攻击的方法。SYN Cookies 基于连接信息(包括源地址、源端口、目的地址、目的端口等)以及一个加密种子(如系统启动时间),计算出一个哈希值(SHA1),这个哈希值称为 cookie。
后,这个 cookie 就被用作序列号,来应答 SYN+ACK 包,并释放连接状态。当客户端发送完三次握手的最后一次 ACK 后,服务器就会再次计算这个哈希值,确认是上次返回的 SYN+ACK 的返回包,才会进入 TCP 的连接状态。
因而,开启 SYN Cookies 后,就不需要维护半开连接状态了,进而也就没有了半连接数的限制。
注意,开启 TCP syncookies 后,内核选项 net.ipv4.tcp_max_syn_backlog 也就无效了。你可以通过下面的命令,开启 TCP SYN Cookies:
$ sysctl -w net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syncookies = 1
注意,上述 sysctl 命令修改的配置都是临时的,重启后这些配置就会丢失。所以,为了保证配置持久化,你还应该把这些配置,写入 /etc/sysctl.conf 文件中。比如:
$ cat /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_max_syn_backlog = 1024
【运维笔记|Linux性能优化——使用 tcpdump 和 Wireshark 分析网络流量】写入 /etc/sysctl.conf 的配置,需要执行 sysctl -p 命令后,才会动态生效。
推荐阅读
- 网络|Linux网络抓包分析工具
- Linux|Linux 抓包分析(Tcpdump + Wireshark 的完美组合)
- Linux基础使用|Linux 运行和控制 shell 脚本
- Linux|shell编程--四种流程控制语句
- 配置|Docker Desktop上启用k8s流程
- redis|docker-compose、k8s部署单机版redis
- 翻车!误删/usr/lib/引发的血案,从棺材边成功抢救的过程分享。
- 容器技术(docker|容器 & k8s——Kubernetes详解 & 集群部署 & Metrics-Server)
- Linux|容器 & k8s——kubernetes kubectl工具使用