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
형태로 나타납니다. 귀하의 경우 배열을 전달한 다음 루프 내에서 분할 할 수 있습니다$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
특정 웹 사이트(또는 모든 호스팅 웹 사이트)에 대한 모든 요청과 일치하는 사용자 정의 규칙을 만든 다음 maxretry
규칙 값을 2000으로 설정할 수 있습니다.
bantime
원하는 대로 규칙을 설정할 수도 있습니다 (예: bantime=86400
이 IP를 하루 동안 차단).
기본적으로 와 같은 모든 차단 및 차단 해제 작업도 기록합니다 /var/log/fail2ban.log
.
그런데 목표를 다시 생각해 보고 싶을 수도 있습니다. 단일 IP에서 2000개의 요청은 실제로 많은 요청이 아닙니다. 특히 제공하는 각 "페이지"에 많은 이미지, CSS 파일, 자바스크립트 파일 등이 포함되어 있는 경우에는 더욱 그렇습니다. 또는 해당 IP 주소가 squid
예를 들어 수십 또는 수백 개의 프록시가 실행되는 학교 또는 회사 네트워크의 시스템인 경우. 또는 ISP의 경우.