Виктор Шумаков wrote:
Здравствуйте товарищи очень нужна ваша помощь...

В последние время очень участились SYN_RECV атаки на мой сервер, а именно на 
411 и на 80 -тые порты, сама атака выглядит так:
netstat -n
tcp 0 38 80.222.225.25:411 212.92.221.111:1941 SYN_RECV
и так может быть до 1-2 тысяч конектов, после чего сервер не успевает 
обрабатывать запросы от другиг и тупо обрабатывает только SYN_RECV с одного или 
несколькольких айпишников...

интересует вопрос как это заглушить, может кто поможет со скриптом, я вот думал сделать некий скрипт типа netstat -n |grep SYN_RECV если от одного айпи больше 10 syn_recv пакетов то этот айпи вносить в текстовый файл, а текстовый файл, а iptables заставить раз с этого файла брать айпи и дропать их, по истечению некоторого времени файл автоматически чистить, всё это можно сделать с помощью крон таб но как... и может кто подскажет более проше и умнее выход...
Стандартно, отбрасывать пакеты с помощью модуля limit. Можете попробовать приспособить мой скрипт для блокировки атак на ssh, если поймёте как он работает.

#!/bin/bash

# file for crackersip
ipfile="/etc/crackersip"
# command to restart firewall 
cmdfirewallrestart="/bin/firewall"
# For debug
wd="${0%${0##*/}}"; [ -z "$wd" ] && wd="$PWD"
# timeout between connentions into attack in seconds
timeofout=$((15*60))
# minimum connections per attack in times
timesperout=$((50))
# out of ban period in seconds
outofban=$((15*24*60*60))
periodoflog=$((1*24*60*60))

cronfile="/etc/cron.hourly/${0##*/}"
log="/var/log/syslog/messages"
version="0.1.0"
TEST=0


for str in $@; do
    case "$str" in
        --help)
            cat <<-EOF
${0##*/}, version $version
usage:

${0##*/} [option]
        
option are:
--help          this message
--version       version
--install       install the programm
--uninstall     uninstall the programm
EOF
            exit 0
            ;;
        --version)
            cat <<-EOF
${0##*/}, version $version
Please, send bugreport to [email protected]
EOF
            exit 0
            ;;
        --test)
            #log="$wd/messages"
            TEST=1
            ;;
        --install)
            if (( UID != 0 )); then
                echo "${0##*/}: install: you need root permission"
                exit 1;
            fi
            install -m 755 "$0" /bin/${0##*/}
            chown root:root /bin/${0##*/}
            cat > "$cronfile" <<-EOF
#!/bin/sh
exec /bin/${0##*/}
EOF

            chown root:root "$cronfile"
            chmod 755 "$cronfile"
            exit 0
            ;;
        --uninstall)
            if (( UID != 0 )); then
                echo "${0##*/}: uninstall: you need root permission"
                exit 1;
            fi
            rm -f "$cronfile"
            exec rm -f /bin/${0##*/}
            exit 0
            ;;
        *)
            echo "${0##*/}: $str: unknown option"
            exit 1;
            ;;
    esac
done

temp1="$(mktemp /tmp/crackers1.XXXXXX)"
temp2="$(mktemp /tmp/crackers2.XXXXXX)"
temp3="$(mktemp /tmp/crackers3.XXXXXX)"
temp4="$(mktemp /tmp/crackers4.XXXXXX)"

bzcat "$log.1.bz2" | cat - "$log" | egrep 
'sshd.*[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' > "$temp2"
preline=0
line=1
endline=$(sed -n '$=' "$temp2")
curdate=$(date "+%s")
while (( $preline != $line )); do
    date=$(date --date="$(tail -n $line "$temp2" | sed -n '1p' | sed 
's/sshd.*//;s/[[:space:]]*$//;s/[[:alnum:]]*$//')" "+%s")
    if (( $((curdate-periodoflog))<$date )); then 
        mark="line++"
        if (( $preline>$line )); then
            mark="int"; ((tline=line)); line=$(( (preline+line)/2 )); 
((preline=tline));
        else
            mark="ext"; ((tline=line)); line=$(( line+(line-preline)*2 )); 
((preline=tline));
        fi
    else
        mark="line--"
        if (( $preline>$line )); then
            mark="ext"; ((tline=line)); line=$(( line-(preline-line)/2 )); 
((preline=tline));
        else
            mark="int"; ((tline=line)); line=$(( (preline+line)/2 )); 
((preline=tline));
        fi
    fi
    ((TEST)) && echo $line
    (( line<1 )) && ((line=1))
    (( line>endline )) && ((line=$endline))
#    (( preline == line )) && break   
done

tail -n $line "$temp2" >"$temp1"

((TEST)) && echo "Source" | cat - "$temp1" | less
((TEST)) && wc -l "$temp1"
# extract date
sed 's/sshd.*//;s/[[:space:]]*$//;s/[[:alnum:]]*$//' "$temp1" > "$temp2"
((TEST)) && echo "Date" | cat - "$temp2" | less
((TEST)) && wc -l "$temp2"
date --file="$temp2" "+%s" > "$temp3";
((TEST)) && wc -l "$temp3"
#echo | cat - "$temp3" | sed "s/$/\n/" | sed '1d;' | cat -n | sed '1d;n;d;' > 
"$temp2"
sed "s/^/\n/" "$temp3" | cat -n | sed '1d;n;d;' > "$temp2"
((TEST)) && echo "Numeric date even" | cat - "$temp2" | less
((TEST)) && wc -l "$temp2"
# extract ip
#cat "$temp1" | while read str; do str="$(echo "$str" | sed 
'h;s/\[[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\]/aaaaa&bbbbb/;ta;h;bb;:a;s/.*aaaaa//;s/bbbbb.*//;:b;s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/aaaaa&bbbbb/;s/.*aaaaa//;s/bbbbb.*//;')";
 [ -z "$str" ] && exit; done;
sed 
'h;s/\[[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\]/aaaaa&bbbbb/;ta;h;bb;:a;s/.*aaaaa//;s/bbbbb.*//;:b;s/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/aaaaa&bbbbb/;s/.*aaaaa//;s/bbbbb.*//;s/$/\n/'
 "$temp1" | cat -n | sed 'n;d;' > "$temp3"
((TEST)) && echo "Numeric IP odd" | cat - "$temp3" | less
((TEST)) && wc -l "$temp3"
# mixing
cat "$temp2" "$temp3" | sort --numeric-sort --ignore-leading-blanks | sed 
's/^[[:space:]]*//;s/^[[:digit:]]*//;s/^[[:space:]]*//;' | sed '$!N;s/\n/ /' > 
"$temp1"
((TEST)) && echo "Done" | cat - "$temp1" | less
: > "$temp3"
str1=
sort "$temp1" | while read str; do
    if [ -z "$str1" ]; then str1="$str"; preip="${str%[[:space:]]*}"; 
pretime="${str#*[[:space:]]}"; echo "$ip1" > "$temp2"; continue; fi
    if [ "${str%[[:space:]]*}" == "$preip" ]; then 
        if (( ${str#*[[:space:]]}-$pretime<$timeofout )); then
            echo "${str%[[:space:]]*}" >> "$temp2";
            pretime="${str#*[[:space:]]}";
            continue;
        fi
    fi
    lines="$(wc -l "$temp2")"
    str1=
    if (( ${lines%%[[:space:]]*}+0>=$timesperout )); then echo "$preip" >> 
"$temp3"; fi
done
((TEST)) && echo "***Detected IP" | cat - "$temp3" | less
# Removing old IP
:>"$temp1"
date=$(date +%s)
[ -f "$ipfile" ] || touch "$ipfile"
cat "$ipfile" | while read str; do
    strd="$(echo "$str" | sed 's/#.*//;s/[[:space:]]\+$//;s/^[[:space:]]\+//;')"
    strd="${strd#${strd%[[:space:]]*}}";
    if [ -z "$strd" ] || (( "$strd">$date )); then echo "$str" >> "$temp1"; fi
done 
((TEST)) && echo "***Removing duplicate IP"
:>"$temp2"
:>"$temp4"
#sed 's/#.*//;s/^[[:space:]]\+//;s/[[:space:]].*//;' "$temp1" | cat - "$temp3" 
>"$temp4"
cat "$temp1" | while read str; do
    strd="$(echo "$str" | sed 's/#.*//;s/^[[:space:]]\+//;s/[[:space:]]\+$//;')"
    # strd="${strd#${strd%[[:space:]]*}}";
    if [ -z "${strd#${strd%[[:space:]]*}}" ]; then echo "$str" >> "$temp2"; 
continue; fi
    strd="${str%%[[:space:]]*}"
    if ! grep -q "^$strd$" "$temp3" && ! grep -q "^$strd$" "$temp4" ; then echo 
"$str" >> "$temp2"; fi
    echo "$strd" >>"$temp4"
done
((TEST)) && echo "***Adding IP"
dates=$(( $(date +%s)+$outofban ))
dates=$(date +%s)
dates=$(( $dates+$outofban ))
cat "$temp3" | while read str; do
    echo -e "$str\t$dates\t# added by ${0##*/} at $(date) #$line" >> "$temp2";
    # echo -e "$str\t$date\t# added by ${0##*/} at $(date)"
done

sed 
's/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/aaaaa&bbbbb/;s/.*aaaaa//;s/bbbbb.*//;'
 "$temp2" | sort | uniq > "$temp1";
lines1="$(md5sum "$temp1")"; lines1="${lines1%%[[:space:]]*}"
sed 
's/[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/aaaaa&bbbbb/;s/.*aaaaa//;s/bbbbb.*//;'
 "$ipfile" | sort | uniq > "$temp1"
lines2="$(md5sum "$temp1")"; lines2="${lines2%%[[:space:]]*}"

if [ "$lines1" != "$lines2" ]; then
    ((TEST)) || [ -x "$cmdfirewallrestart" ] && "$cmdfirewallrestart" 2>&1 
1>/dev/null
    cat "$temp3" | while read str; do
        logger -t "${0##*/}[$$]" "added crackers IP [$str] to $ipfile"
    done
fi
cat "$temp2" > "$ipfile"

rm -f "$temp1" "$temp2" "$temp3" "$temp4"

exit
_______________________________________________
Sysadmins mailing list
[email protected]
https://lists.altlinux.org/mailman/listinfo/sysadmins

Ответить