Use um loop while
em vez de for
e emita várias colunas de awk
.
while read x y; do
echo $y $x
done << EOF
example one
example two
EOF
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
Estou tentando bloquear endereços IP que tentaram mais de 2000 solicitações. Na verdade, o código acima é uma combinação de duas seções.
Primeiro,
cat /var/www/vhosts/example.com/statistics/logs/access_log.processed | awk '{print $1}' | sort | uniq -c | sort -nr
Eu entro, classifico e conto todos os endereços IP. Abaixo está um exemplo de resultado
4565 8.8.8.8
3245 7.7.7.7
Depois, faço uma iteração sobre cada resultado e verifico se o número da tentativa é maior que 2000.
awk {'if ($1 > 2000) print $2'}
$1
é o número da tentativa e $2
é o IP.
Portanto, $2
é salvo como $x
e pode ser usado dentro de loop. Mas como também posso usar $1
dentro do loop for?
Use um loop while
em vez de for
e emita várias colunas de awk
.
while read x y; do
echo $y $x
done << EOF
example one
example two
EOF
Ambos bash
e awk
possuem suas próprias variáveis configuradas. $1
in awk
difere a forma $1
in bash
por significado e valor. No seu caso, você pode passar "$1 $2"
array para $x
e depois dividi-lo dentro de um loop
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
Por que reinventar a roda quando o fail2ban já pode fazer o que você quer (e muito mais)?
Com fail2ban
, você pode criar uma regra personalizada que corresponda a qualquer solicitação a um determinado site (ou a todos os sites hospedados) e defina o maxretry
dessa regra como 2000.
Você também pode definir bantime
para essa regra como quiser (por exemplo, bantime=86400
para bloquear esse IP por um dia).
Por padrão, ele também registra todos os blocos e ações de bloqueio, por exemplo em /var/log/fail2ban.log
.
BTW, você pode querer repensar seu objetivo. 2000 pedidos de um único IP não são realmente muitos pedidos, especialmente se cada "página" que você servir contém numerosas imagens, arquivos css, arquivos javascript, etc. Ou se esse endereço IP é um proxy (por exemplo, executando squid
) para dezenas ou centenas de máquinas em uma escola ou rede corporativa. ou para um ISP.
Tags bash shell-script