访问辅助变量

访问辅助变量
for x in `cat /var/www/vhosts/example.com/statistics/logs/access_log.processed | awk '{print $1}' | sort | uniq -c | sort -nr | awk {'if ($1 > 2000) print $2'}`; 
do
    #Works        
    printf "$x"     

    #Does not work
    printf "$1"
done

我正在尝试阻止尝试超过 2000 个请求的 IP 地址。实际上上面的代码是两部分的组合。

第一的,

cat /var/www/vhosts/example.com/statistics/logs/access_log.processed | awk '{print $1}' | sort | uniq -c | sort -nr

我收集、排序并统计所有 IP 地址。下面是一个示例结果

4565 8.8.8.8
3245 7.7.7.7

然后我迭代每个结果并检查尝试次数是否超过 2000。

awk {'if ($1 > 2000) print $2'}

$1是尝试次数,$2是IP。

so$2被另存为$x并且可以在 for 循环中使用。但我怎样才能$1在 for 循环内部使用呢?

答案1

使用while循环而不是for,并从 发出多列awk

while read x y; do
  echo $y $x
done << EOF
example one
example two
EOF

答案2

bash都有awk自己的变量集。其意义和价值都有$1不同awk的形式。在您的情况下,您可以将数组传递给然后将其拆分在循环内$1bash"$1 $2"$x

for x in `cat /var/www/vhosts/example.com/statistics/logs/access_log.processed | awk '{print $1}' | sort | uniq -c | sort -nr | awk {'if ($1 > 2000) print $1, $2'}`; do  
  IFS=" " read first second <<< "$x"
  #now $first=$1, $second=$2  
done

答案3

为什么要重新发明轮子失败2禁止已经可以做你想做的事了(以及更多)?

使用fail2ban,您可以创建一个自定义规则,使任何对给定网站(或所有托管网站)的请求都匹配,然后maxretry将该规则的设置为 2000。

您还可以将该bantime规则设置为您想要的任何内容(例如,bantime=86400阻止该 IP 一天)。

默认情况下,它还会记录每个阻止和取消阻止操作,例如在/var/log/fail2ban.log.

顺便说一句,您可能需要重新考虑您的目标。来自单个 IP 的 2000 个请求实际上并不是很多请求,特别是如果您提供的每个“页面”包含大量图像、css 文件、javascript 文件等。或者如果该 IP 地址是squid数十或数百个代理(例如正在运行)学校或公司网络上的机器。或对于 ISP。

相关内容