AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 521043
Accepted
Asad Moeen
Asad Moeen
Asked: 2013-07-06 01:56:23 +0800 CST2013-07-06 01:56:23 +0800 CST 2013-07-06 01:56:23 +0800 CST

tcpdump - 如何检查数据包的速率?

  • 772

我正在使用这个脚本来实际检查传入数据包的速率,如果速率达到 5mbps 或更高,它就会被触发。然后将数据包记录到 tcpdump 文件中。

interface=eth0
dumpdir=/tmp/

while /bin/true; do
  pkt_old=`grep $interface: /proc/net/dev | cut -d :  -f2 | awk '{ print $2 }'`
  sleep 1
  pkt_new=`grep $interface: /proc/net/dev | cut -d :  -f2 | awk '{ print $2 }'`

  pkt=$(( $pkt_new - $pkt_old ))
  echo -ne "\r$pkt packets/s\033[0K"

  if [ $pkt -gt 5000 ]; then
    echo -e "\n`date` Under attack, dumping packets."
    tcpdump -n -s0 -c 2000 -w $dumpdir/dump.`date +"%Y%m%d-%H%M%S"`.cap
    echo "`date` Packets dumped, sleeping now."
    sleep 300
  fi
done

输出类似于捕获的 2000 个数据包。过滤器接收到 XXX 个数据包,内核丢弃了 XXX-(减号)2000。

现在我想知道的是,输出文件实际上不会告诉我攻击的速率,比如它是 300mbps 还是什么?那么过滤器接收的XXX数据包是每秒吗?如果没有,我该如何检查,因为我的端口有时会饱和。

更新:

我使用一个程序通过上述脚本从捕获的文件中捕获统计信息。这是我得到的:

root@$:/tmp/dumps# capinfos dump.20130621-174506.cap
File name:           dump.20130621-174506.cap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Linux cooked-mode capture
Number of packets:   2000
File size:           2065933 bytes
Data size:           2033909 bytes
Capture duration:    43 seconds
Start time:          Fri Jun 21 17:45:06 2013
End time:            Fri Jun 21 17:45:49 2013
Data byte rate:      46968.49 bytes/sec
Data bit rate:       375747.94 bits/sec
Average packet size: 1016.95 bytes
Average packet rate: 46.19 packets/sec

我相信攻击可能只持续了 15-20 秒,而捕获的信息是 43 秒,所以这里的数据比特率可能是这个总时间的平均值。这里可能有帮助的是,如果有人可以编辑上面的原始脚本,而不是捕获 2000 个数据包并丢弃其余数据包,而是在达到阈值时捕获所有数据包持续时间为 5 秒。

更新:

如上所述更改脚本后,当我在 Wireshark 中阅读时,文件看起来已损坏,上面写着“捕获文件似乎在数据包中间被剪短了”。这是 capinfos 的输出:

capinfos: An error occurred after reading 3085 packets from `"dump.20130710-215413.cap": Less data was read than was expected.

在第二次尝试中,只有在脚本控制台中按 Ctrl+C 时,我才能读取该文件:

capinfos dump.20130710-215413.cap
File name:           dump.20130710-215413.cap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Linux cooked-mode capture
Number of packets:   18136
File size:           2600821 bytes
Data size:           2310621 bytes
Capture duration:    591 seconds
Start time:          Wed Jul 10 21:54:13 2013
End time:            Wed Jul 10 22:04:04 2013
Data byte rate:      3909.73 bytes/sec
Data bit rate:       31277.83 bits/sec
Average packet size: 127.41 bytes
Average packet rate: 30.69 packets/sec

注意捕获持续时间 591 秒。我相信'sleep 300'在这里有一些事情要做,因为我看到了控制台输出。此输出带有“-c 2000”选项:

./Log.sh
10275 packets/s
Wed Jul 10 12:41:31 MSD 2013 Under attack, dumping packets.
tcpdump: listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
2000 packets captured
100012 packets received by filter
98003 packets dropped by kernel
Wed Jul 10 12:42:34 MSD 2013 Packets dumped, sleeping now.

现在这是使用“sleep 5”修改脚本后的输出:

./Log.sh
24103 packets/s
Wed Jul 10 21:54:13 MSD 2013 Under attack, dumping packets.
tcpdump: listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
Wed Jul 10 21:54:18 MSD 2013 Packets dumped, sleeping now.
1620 packets/sroot@nl:~# 18136 packets captured
1850288 packets received by filter
1832106 packets dropped by kernel
^C

请注意,我按下了 Ctrl+C 来打破我猜想这使得读取文件成为可能的睡眠功能。

tcpdump
  • 2 2 个回答
  • 27962 Views

2 个回答

  • Voted
  1. Best Answer
    quanta
    2013-07-10T11:21:11+08:002013-07-10T11:21:11+08:00

    capinfos是您正在寻找的:

    $ capinfos ddos.cap
    File name:           ddos.cap
    File type:           Wireshark/tcpdump/... - libpcap
    File encapsulation:  Ethernet
    Packet size limit:   file hdr: 65535 bytes
    Number of packets:   1000000
    File size:           189073212 bytes
    Data size:           173073188 bytes
    Capture duration:    2 seconds
    Start time:          Fri Jul  5 16:35:04 2013
    End time:            Fri Jul  5 16:35:07 2013
    Data byte rate:      69839025.27 bytes/sec
    Data bit rate:       558712202.18 bits/sec
    Average packet size: 173.07 bytes
    Average packet rate: 403523.08 packets/sec
    SHA1:                34d758e6445061855ca4397729098f469f411fe3
    RIPEMD160:           14f430231fc2962cd86ddb8edb8daf75a5d07af8
    MD5:                 5893809fb02d1a20997629a9a501842b
    Strict time order:   False
    

    注意数据比特率。


    这里可能有帮助的是,如果有人可以编辑上面的原始脚本,而不是捕获 2000 个数据包并丢弃其余数据包,而是在达到阈值时捕获所有数据包持续时间为 5 秒。

    这个怎么样:

    tcpdump -n -s0 -w $dumpdir/dump.`date +"%Y%m%d-%H%M%S"`.cap &
    sleep 5 && pkill -HUP -f /usr/sbin/tcpdump
    
    • 6
  2. Gabriel Staples
    2022-07-13T23:32:23+08:002022-07-13T23:32:23+08:00

    如何使用tcpdump纳秒分辨率时间戳测量数据包速率(频率)

    快速总结:

    对于下面显示的两个选项,在这些“单线”命令 blob 中更新num_packets值和命令是全部:tcpdump

    选项1:

    这总是有效并且非常好:

    num_packets="25"; \
    time_start_sec="$(date +"%s.%N")"; \
    time sudo tcpdump -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)"; \
    time_end_sec="$(date +"%s.%N")"; \
    dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    packet_rate_hz="$(bc <<< "scale=20; $num_packets / $dt_sec")"; \
    printf "\n%s%.3f\n\n" "packet_rate_hz = " "$packet_rate_hz"
    

    选项 2 [最佳]:

    这适用于大多数(如果不是全部)不包含标志的tcpdump命令,并且更好!:-t

    num_packets="10"; \
    time sudo tcpdump -l -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)" \
        | tee tcpdump.txt; \
    time_start_sec="$(grep -o \
        '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
        "tcpdump.txt" \
        | head -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    time_end_sec="$(grep -o \
        '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
        "tcpdump.txt" \
        | tail -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    packet_rate_hz="$(bc <<< "scale=20; ($num_packets-1) / $dt_sec")"; \
    printf "\n%s%.4f\n\n" "packet_rate_hz = " "$packet_rate_hz"
    

    选项 1:使用来自的纳秒分辨率时间戳手动计时整个过程date

    这工作正常。我只是告诉tcpdump抓取一定数量的数据包,对整个事情进行计时,然后计算数据包速率:

    num_packets="25"; \
    time_start_sec="$(date +"%s.%N")"; \
    time sudo tcpdump -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)"; \
    time_end_sec="$(date +"%s.%N")"; \
    dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    packet_rate_hz="$(bc <<< "scale=20; $num_packets / $dt_sec")"; \
    printf "\n%s%.3f\n\n" "packet_rate_hz = " "$packet_rate_hz"
    

    这是一个bash“单线”。一次复制并粘贴整个块。请务必num_packets先将变量更新为您想要捕获的数据包数量,然后更新您的tcpdump行以仅过滤您感兴趣的数据包。换句话说,根据您的需要修改这两行:

    num_packets="25"; \
    
    time sudo tcpdump -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)"; \
    

    它将在最后打印出数据包速率,如下所示(真正的数据包速率为 10.00 Hz):

    packet_rate_hz = 9.418
    

    请注意,由于tcpdump原样启动的一些开销,显示的计算频率(在本例中为 9.698 Hz)偏低了一点。我知道它的实际频率是 10.00 Hz(是的,> 2 个零精度),因为我编写了发送数据包的代码并使用精确计时来执行此操作——请参阅我的答案以了解该代码的计时部分:如何使用软实时调度程序和纳秒级延迟,在 Linux 中以任何频率(例如:高达 10 KHz~100 KHz)轻松运行高分辨率、高精度的周期性循环

    因此,对于选项 1,使用更大的数据包计数(设置num_packets为更大的值,例如25to50或更多)更好,因为它减少了由启动开销引入的错误tcpdump,我们将其包括在我们的计时中,但不要想要。

    真实数据的完整命令和输出示例:

    $ num_packets="25"; \
    > time_start_sec="$(date +"%s.%N")"; \
    > time sudo tcpdump -i any -c "$num_packets" \
    >     "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)"; \
    > time_end_sec="$(date +"%s.%N")"; \
    > dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    > packet_rate_hz="$(bc <<< "scale=20; $num_packets / $dt_sec")"; \
    > printf "\n%s%.3f\n" "packet_rate_hz = " "$packet_rate_hz"
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
    11:58:36.181547 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.281798 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.381547 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.481842 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.581581 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.681724 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.781734 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.881735 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:36.981637 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.081633 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.181585 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.281661 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.381456 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.481732 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.581709 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.681696 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.781710 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.881603 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:37.981751 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.081860 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.181669 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.281727 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.381457 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.481574 IP localhost.40000 > localhost.40001: UDP, length 44
    11:58:38.581724 IP localhost.40000 > localhost.40001: UDP, length 44
    25 packets captured
    50 packets received by filter
    0 packets dropped by kernel
    
    real    0m2.651s
    user    0m0.016s
    sys 0m0.017s
    
    packet_rate_hz = 9.418
    

    选项 2 [最好——在可能的情况下使用它!]:从tcpdump输出中提取第一个和最后一个数据包时间戳,并使用它们来确定数据包速率

    对于这种技术,我们需要做一些事情:

    1. 首先,始终在此处使用-l(破折号小写 L,而不是破折号)标志tcpdump来使 stdout 输出行缓冲,以便在脚本运行时看到它定期更新。如果你不使用这个标志,tcpdump如果输出很短,你只会在命令的最后看到一次输出,或者如果输出很长,每次标准输出缓冲区完全填满时,你只会看到一次巨大的周期性块。
    2. 将输出通过管道传输到teeA) 将其保存到一个文件中,然后您可以从中提取时间戳,然后B ) 将其打印到标准输出,以便您可以实时查看。

    这里是“单线”。请注意,该time部分是可选的。它只是在最后打印出总时间,我认为这很好。同样,根据您的需要更新num_packets值和tcpdump命令。num_packets您可以使用的最小值是2。此技术具有如此高的准确性,您无需使用较大num_packets的值即可使其正常工作。只收集2数据包会产生良好的效果,而10数据包会产生极好的结果。

    num_packets="10"; \
    time sudo tcpdump -l -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)" \
        | tee tcpdump.txt; \
    time_start_sec="$(grep -o \
        '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
        "tcpdump.txt" \
        | head -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    time_end_sec="$(grep -o \
        '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
        "tcpdump.txt" \
        | tail -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    packet_rate_hz="$(bc <<< "scale=20; ($num_packets-1) / $dt_sec")"; \
    printf "\n%s%.4f\n\n" "packet_rate_hz = " "$packet_rate_hz"
    

    同样,根据您的需要修改这两行(如下所示),记住以下几点:

    1. 对于该tcpdump行,请务必保留-l和| tee tcpdump.txt,如上所述。
    2. 此外,使用-twithtcpdump意味着“不要在每个转储行上打印时间戳。”,如果使用,将导致该技术无法工作,因为它依赖于这些时间戳。但是,上面的选项 1 仍然可以正常工作。
    3. 如果您正在使用嵌入式 Linux 开发板,请考虑以下事项:
      1. 它可能有一个主要是只读的文件系统,在这种情况下,您需要将tee输出强制写入文件系统可写部分的文件中,例如可能/var/log/tcpdump.txt或/tmp/tcpdump.txt不只是tcpdump.txt在当前目录中。
        1. 如果默认情况下文件系统的任何部分都不可写,那么您可能需要先将其卸载并重新挂载为可读写 ( rw),如下所示。然后,运行tcpdump上面的命令。完成后,您可以将其挂载为只读 ( ro),如下所示:
          # Remount your root dir (/) as read-writable (rw)
          mount -o remount,rw /
          # Remount your root dir (/) as read-only (ro)
          mount -o remount,ro /
          
      2. 您的嵌入式 Linux 主板可能没有该sudo命令,在这种情况下,您需要直接以 root 身份登录主板,并从上面的命令中删除该sudo单词。tcpdump
    num_packets="10"; \
    
    time sudo tcpdump -l -i any -c "$num_packets" \
        "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)" \
        | tee tcpdump.txt; \
    

    最后打印的示例数据包速率(真正的数据包速率为 10.00 Hz):

    packet_rate_hz = 10.0003
    

    真实数据的完整命令和输出示例。请注意,当使用 对输出进行行缓冲时-l,stderr输出(例如指示捕获、接收和丢弃多少数据包的行)会意外地与stdout输出的其余部分混合。没关系。这是不理想的,但我们无能为力。所以,这很正常。

    $ num_packets="10"; \
    > time sudo tcpdump -l -i any -c "$num_packets" \
    >     "(src 127.0.0.1 and port 40000) and (dst 127.0.0.1 and port 40001)" \
    >     | tee tcpdump.txt; \
    > time_start_sec="$(grep -o \
    >     '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
    >     "tcpdump.txt" \
    >     | head -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    > time_end_sec="$(grep -o \
    >     '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*' \
    >     "tcpdump.txt" \
    >     | tail -n 1 | grep -o '[0-9][0-9]\.[0-9]*')"; \
    > dt_sec="$(bc <<< "scale=20; $time_end_sec - $time_start_sec")"; \
    > packet_rate_hz="$(bc <<< "scale=20; ($num_packets-1) / $dt_sec")"; \
    > printf "\n%s%.4f\n\n" "packet_rate_hz = " "$packet_rate_hz"
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
    11:59:35.481669 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:35.581440 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:35.681468 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:35.781661 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:35.881649 IP localhost.40000 > localhost.40001: UDP, length 44
    10 packets captured
    28 packets received by filter
    0 packets dropped by kernel
    11:59:35.981540 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:36.081669 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:36.181423 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:36.281595 IP localhost.40000 > localhost.40001: UDP, length 44
    11:59:36.381638 IP localhost.40000 > localhost.40001: UDP, length 44
    
    real    0m1.098s
    user    0m0.021s
    sys 0m0.009s
    
    packet_rate_hz = 10.0003
    

    选项 1 与选项 2

    如果上面的选项 2 好得多并且产生了更好的结果,我们为什么要使用选项 1?

    好吧,如果您曾经将-t标志与tcpdump,一起使用,man tcpdump则表示它意味着:

    -t     Don't print a timestamp on each dump line.
    

    因此,如果您使用该标志,选项 2 显然不起作用,因为它依赖于这些时间戳。但是,选项 1 在那里仍然可以正常工作!

    If any other scenarios or possible tcpdump commands come up which don't work well with Option 2, you can use Option 1, which always works. But, whenever possible, use Option 2, as it produces much more accurate and precise output!

    References

    1. To help me come up with my regular expressions in grep: https://regex101.com/
    • 0

相关问题

  • tcpdump 显示流量,直到我使用过滤器

  • openvpn双重安装(客户端和服务器)路由问题

  • 如何以友好的格式读取 pcap 文件?

  • 使用 tcpdump 在代理上转储主机的原始数据

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve