tcpdump抓包分析业务是否在用

一、安装tcptump抓包工具、tmux后台工具以及nmap端口扫描工具

yum install -y tcpdump tmux nmap-ncat

二、创建抓包目录及脚本

mkdir /root/net
vi /root/net/net.sh
  • 抓包脚本内容(只抓取本地监听端口以及目标监听端口并统计访问次数)

    #!/bin/bash
    
    ########################
    # 基本配置
    ########################
    OUT_DIR="/root/net"
    DATE=$(date +%F)
    # 获取本机主机名
    HOSTNAME_STR=$(hostname)
    mkdir -p "$OUT_DIR"
    
    # 探测超时时间(秒)
    SCAN_TIMEOUT=1
    
    ########################
    # 获取真实对外 IP
    ########################
    LOCAL_MAIN_IP=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}')
    if [[ -z "$LOCAL_MAIN_IP" ]]; then
      LOCAL_MAIN_IP=$(ip addr | awk '/inet / && $2 !~ /^127/ {print $2}' | cut -d/ -f1 | head -n1)
    fi
    
    # 修改后的文件名:包含 IP、主机名和日期
    CSV="$OUT_DIR/${LOCAL_MAIN_IP}_${HOSTNAME_STR}_$DATE.csv"
    echo "direction,src_ip,dst_ip,dst_port,count" > "$CSV"
    
    ########################
    # 内存统计与缓存结构
    ########################
    declare -A COUNT
    declare -A CHECKED_PORTS  # 格式: [IP:PORT]=status (1为开放, 0为关闭)
    
    LOCAL_IPS=$(ip addr | awk '/inet /{print $2}' | cut -d/ -f1)
    
    get_listen_ports() {
      ss -lntu | awk 'NR>1 {print $5}' | awk -F: '{print $NF}' | sort -n | uniq
    }
    LISTEN_PORTS=$(get_listen_ports)
    
    ########################
    # 端口验证函数
    ########################
    check_remote_port() {
      local ip=$1
      local port=$2
      local key="${ip}:${port}"
    
      if [[ -n "${CHECKED_PORTS[$key]}" ]]; then
          return "${CHECKED_PORTS[$key]}"
      fi
    
      # 探测对端端口
      if nc -z -w "$SCAN_TIMEOUT" "$ip" "$port" &>/dev/null; then
          CHECKED_PORTS["$key"]=1
          return 1
      else
          CHECKED_PORTS["$key"]=0
          return 0
      fi
    }
    
    ########################
    # 抓包并统计
    ########################
    tcpdump -l -nn -i any '(tcp or udp)' 2>/dev/null | while read -r line; do
    
      if [[ $line =~ ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.([0-9]+)\ \>\ ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.([0-9]+) ]]; then
          SRC_IP=${BASH_REMATCH[1]}
          DST_IP=${BASH_REMATCH[3]}
          DST_PORT=${BASH_REMATCH[4]}
    
          IS_SRC_LOCAL=0
          IS_DST_LOCAL=0
    
          for ip in $LOCAL_IPS; do
              [[ "$SRC_IP" == "$ip" ]] && IS_SRC_LOCAL=1
              [[ "$DST_IP" == "$ip" ]] && IS_DST_LOCAL=1
          done
    
          # IN:外部 -> 本机
          if [[ $IS_DST_LOCAL -eq 1 && $IS_SRC_LOCAL -eq 0 ]]; then
              if echo "$LISTEN_PORTS" | grep -qw "$DST_PORT"; then
                  KEY="IN,$SRC_IP,$DST_IP,$DST_PORT"
                  ((COUNT["$KEY"]++))
              fi
          fi
    
          # OUT:本机 -> 外部(仅抓取对端开放的端口)
          if [[ $IS_SRC_LOCAL -eq 1 && $IS_DST_LOCAL -eq 0 ]]; then
              check_remote_port "$DST_IP" "$DST_PORT"
              if [[ $? -eq 1 ]]; then
                  KEY="OUT,$LOCAL_MAIN_IP,$DST_IP,$DST_PORT"
                  ((COUNT["$KEY"]++))
              fi
          fi
      fi
    
      # 定期落盘
      if (( RANDOM % 100 == 0 )); then
          {
              echo "direction,src_ip,dst_ip,dst_port,count"
              for k in "${!COUNT[@]}"; do
                  echo "$k,${COUNT[$k]}"
              done
          } > "$CSV"
      fi
    done

    三、赋予脚本执行权限并执行脚本

  • 授权脚本

    chmod +x /root/net/net.sh
  • 新建tmux

    tmux new -s net
  • 执行抓包脚本(执行后按ctrl + B 后按D后台运行tmux)

    /root/net/net.sh
  • 进入tmux(抓包结束后ctrl + C 结束脚本,然后ctrl + D 退出tmux)

    tmux attach -t net
  • 观察脚本CPU使用率

    ps -eo pid,ppid,cmd,%cpu --sort=-%cpu | head -n 11

    四、分析CSV文件的流量访问情况

  • 源端是否公网IP
    =IF(OR(LEFT(B2,3)="10.",LEFT(B2,8)="192.168.",LEFT(B2,4)="127.",AND(VALUE(LEFT(B2,FIND(".",B2)-1))=172,VALUE(MID(B2,FIND(".",B2)+1,2))>=16,VALUE(MID(B2,FIND(".",B2)+1,2))<=31)),"内网IP","公网IP")

  • 目的端是否为公网IP
    =IF(OR(LEFT(C2,3)="10.",LEFT(C2,8)="192.168.",LEFT(C2,4)="127.",AND(VALUE(LEFT(C2,FIND(".",C2)-1))=172,VALUE(MID(C2,FIND(".",C2)+1,2))>=16,VALUE(MID(C2,FIND(".",C2)+1,2))<=31)),"内网IP","公网IP")

评论区: