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アドレスをブロックしようとしています。実際、上記のコードは2つの部分の組み合わせです。
まず、
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
形で現れます。あなたの場合、配列を渡してループ内で分割することができます$1
bash
"$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
特定のWebサイト(またはすべてのホスティングWebサイト)に対するすべての要求に一致するカスタムルールを作成し、ルールmaxretry
値を2000に設定できます。
bantime
必要に応じてルールを設定することもできます(たとえば、bantime=86400
このIPを1日中ブロックします)。
デフォルトでは、などのすべてのブロックおよびブロック解除操作も記録されます/var/log/fail2ban.log
。
ところで、目標を考え直してみたいかもしれません。単一のIPで2000の要求は実際には多くの要求ではありません。特に提供する各「ページ」に多くのイメージ、CSSファイル、JavaScriptファイルなどが含まれている場合にはさらにそうです。または、そのIPアドレスが、squid
たとえば数十または数百のプロキシが実行される学校または企業ネットワークのシステムである場合。またはISPの場合。