首页 > 解决方案 > 当最后一个值只有 2 位数字时,如何从 404 awk 报告中隐藏 IP

问题描述

我有一个在我的访问日志中查找 404 HTTP 状态代码的脚本。但是,安全团队有一个脚本正在搜索导致我的日志中有 100 个 404 条目的漏洞。我过滤掉他们测试盒的 IP 地址以避免误报。但是他们最近添加了一个新服务器。问题是这个新服务器的 IP 地址的最后一部分只有 2 位数字。(即 10.1.1.18 - 这不是 IP,但你明白了)。

如何让 awk 或 grep 忽略以 18 结尾的 IP,而不是我需要搜索的有效 IP 180-189?

对于那些不熟悉 HTTP 访问日志内容的人,我举这个例子:

10.1.1.18 - - [12/May/2018:01:25:07 -0600]“GET /xampp/cgi.cgi HTTP/1.1”404 909

我尝试引用 IP 地址以包含 18 之后的空格,如下所示:

猫访问.log | grep -v "10.10.10.230" | grep -v "10.10.11.116" | grep -v "10.1.1.18" | awk -f report_errors.awk

但是我没有从 awk 脚本中得到任何输出。为什么在引用的 grep 排除中有一个空格会导致 awk 死亡?当我从最后删除 awk 命令时,我确实得到了 access.log 的正确内容(这意味着测试服务器条目已被正确删除。)

我不知道我做错了什么。下面是 report_errors.awk 文件:

BEGIN {
  FS = "\""
  title = "HTTP sslaccess_log:\n"
  flag = 0
  error = 0
  error400 = 0
  error408 = 0
  error500 = 0
  site = 0
  separator = ""
  allERRORS = ""
}
function qsortA(array,min,max) {
  if (min > max) {
    return
  }

  m = min
  for (knx = (min + 1) ; knx <= max ; knx++) {
    if (array[knx] < array[min]) {
      swap(array,++m,knx)
      swap(array,min,m)
    }
  }
  qsortA(array,min,(m - 1))
  qsortA(array,(m + 1),max)
}

function swap(array,ind1,ind2) {
 sw = array[ind1]
 array[ind1] = array[ind2]
 array[ind2] = sw
}

$3 ~ / 404 / {
  printf( "%s", title)
  if ( $2 ~ /site/ || $2 ~ /dot.gif/ || $2 ~ /maintenance/ || $2 ~ /graypixel.gif/ || $2 ~ /.css/ || $2 ~ /crossdomain.xml/  || $2 ~ /OPTIONS/ )
  {
    split( $2, name, " " )
    msg = substr(name[1],0,1) " " name[2]
    if ( index( allERRORS, msg) == 0 )
    {
      allERRORS = allERRORS separator msg
      separator = ","
    }
    arrCOUNT[msg]++
    site=1
  }
  else
  {
    print " - " $0
    error++
  }
  title = ""
  flag++
}
$3 ~ / 400 / {
  error400++
}
$3 ~ / 408 / {
  error408++
}
$3 ~ / 500 / {
# printf( "%s", title)
# print " - " $0
  error500++
# title = ""
# flag++
}
END {
  if (flag > 0) {
    if (error > 0) {
      printf("---- %4d: basic errors\n", error)
      printf("---- %4d: 400 errors\n", error400)
      printf("---- %4d: 408 errors\n", error408)
      printf("---- %4d: 500 errors\n", error500)
    }
    if (site = 1)
    {
      split( allERRORS, arrERRORS, "," )
      jnx = 0
      for ( inx in arrERRORS )
      {
        arrNew[++jnx] = arrERRORS[inx]
      }
      qsortA(arrNew,1,jnx)
      inx = 0
      while ( inx < jnx )
      {
        printf("---- %4d: %s\n",arrCOUNT[arrNew[++inx]],arrNew[inx])
      }
    }
    printf("---- %4d: Total 404 Errors\n",flag)
  }
}

有什么建议吗?

标签: bashawkgrep

解决方案


跳过以 2 位数字结尾的 IP 地址:

/^([0-9]+\.){3}[0-9]{2}[[:space:]]/ { next }

顺便说一句:

cat access.log | grep -v "10.10.10.230" | grep -v "10.10.11.116" | grep -v "10.1.1.18 " | awk 'foo'

需要转义其 RE 元字符:

cat access.log | grep -v "10\.10\.10\.230" | grep -v "10\.10\.11\.116" | grep -v "10\.1\.1\.18 " | awk 'foo'

实际上应该写成:

awk '/10\.10\.10\.220|10\.10\.11\.116|10\.1\.1\.18 /{next} foo' access.log

但我怀疑你真正想要的可能是:

awk '/^10\.(10\.10\.(220|116)|1\.1\.18[[:space:]])/{next} foo' access.log

推荐阅读