Hab mich heute mal mit dem Thema befasst...
Und das ist dabei rausgekommen:
1. Lösungsweg:
Der Ansatz kam von http://wiki.x-wrt.org/index.php/HowT...cking_dropbear, anschließend noch Fehler rausgemacht und ASUS tauglich umgeschrieben...
in der /usr/local/sbin/post-firewall folgendes einfügen:
Code:
#Stop Dropbear Hacking
iptables -N STOPDROPBEARHACKRULE
iptables -A INPUT -s 192.0.2.0/24 -j STOPDROPBEARHACKRULE
iptables -A FORWARD -s 192.0.2.0/24 -j STOPDROPBEARHACKRULE
iptables -A STOPDROPBEARHACKRULE -m limit --limit 2/second -j LOG --log-level info --log-prefix "BRUTE FORCE HACK -- DENIED"
iptables -A STOPDROPBEARHACKRULE -j DROP
Via Cron wird dann noch aller einer Minute folgendes Script ausgeführt:
Code:
#!/bin/sh
######################################################
# Inhalt von /opt/etc/cron.1mins/StopDropbearhack.sh #
######################################################
MAX_ATTEMPTS="5"
CHAINNAME="STOPDROPBEARHACKRULE"
WHITELIST="192.168.1.2 192.168.1.3 192.168.1.100 192.168.1.200 192.168.1.101 192.168.1.201 192.168.1.110 192.168.1.210 192.168.1.120 192.168.1.220"
cat /tmp/syslog.log|grep -e "bad password attempt" -e "login attempt for nonexistent user"|awk '{print $FN}'|awk '{n=split($0,fn,":"); print fn[7]}'|sort|uniq -c|sort -n|sed "s/[ [:space:]]*//"|while read i
do
IP=`echo $i | cut -d" " -f 2`
MEMBERFOUND="false"
for MEMBER in $WHITELIST
do
if [ "$MEMBER" = "$IP" ]; then
MEMBERFOUND="true"
fi
done
if [ "$MEMBERFOUND" != "true" ]; then
iptables -n -L INPUT|grep -e "^$CHAINNAME[^[:alnum:]_]"|grep -q "$IP"
EXITCODE=$?
if [ "$EXITCODE" -eq '1' ]; then
COUNT=`echo $i | cut -d" " -f1`
if [ "$COUNT" -ge "$MAX_ATTEMPTS" ]; then
iptables -I INPUT -s $IP -j $CHAINNAME
iptables -I FORWARD -s $IP -j $CHAINNAME
logger "BRUTE FORCE ALERT -- $IP was blocked"
fi
fi
fi
done
Nach einem SSH-Brute Force steht dann im SysLog dies hier drin:
Code:
Jul 22 21:58:45 dropbear[1018]: login attempt for nonexistent user from ::ffff:201.116.1.18:48862
Jul 22 21:58:46 dropbear[1018]: exit before auth: Disconnect received
Jul 22 21:58:46 dropbear[1019]: Child connection from ::ffff:201.116.1.18:49003
Jul 22 21:58:48 dropbear[1019]: login attempt for nonexistent user from ::ffff:201.116.1.18:49003
Jul 22 21:58:49 dropbear[1019]: exit before auth: Disconnect received
Jul 22 21:58:50 dropbear[1020]: Child connection from ::ffff:201.116.1.18:49150
Jul 22 21:58:52 dropbear[1020]: login attempt for nonexistent user from ::ffff:201.116.1.18:49150
Jul 22 21:58:53 dropbear[1020]: exit before auth: Disconnect received
Jul 22 21:58:53 dropbear[1021]: Child connection from ::ffff:201.116.1.18:49291
Jul 22 21:58:55 dropbear[1021]: bad password attempt for 'root' from ::ffff:201.116.1.18:49291
Jul 22 21:58:56 dropbear[1021]: exit before auth (user 'root', 1 fails): Disconnect received
Jul 22 21:58:56 dropbear[1022]: Child connection from ::ffff:201.116.1.18:49428
Jul 22 21:58:59 dropbear[1022]: bad password attempt for 'root' from ::ffff:201.116.1.18:49428
Jul 22 21:59:00 dropbear[1022]: exit before auth (user 'root', 1 fails): Disconnect received
Jul 22 21:59:01 dropbear[1023]: Child connection from ::ffff:201.116.1.18:49608
Jul 22 21:59:01 /opt/sbin/cron[1025]: (root) CMD (run-parts /opt/etc/cron.1mins # aller einer Minute)
Jul 22 21:59:03 root: BRUTE FORCE ALERT -- 201.116.1.18 was blocked
Laut "iptables --list" wurde diese IP dann auch tatsächlich gesperrt.
Einen Nachteil hat dieses Script jedoch... Der Angreifer hat genau eine Minute Zeit sein unwesen zu treiben.
2. Lösungsweg:
/usr/local/sbin/post-firewall:
Code:
#!/bin/sh
#SSH
iptables -D INPUT -j DROP
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -t nat -A PREROUTING -i vlan1 -p tcp --dport 22 -j DNAT --to-destination $4:22
iptables -A INPUT -j DROP
iptables -D INPUT -j DROP
iptables -A INPUT -p tcp --dport 81 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i $1 -p tcp --dport 80 -j DNAT --to-destination $4:81
# This we know...
WANIF=$1
LANIP=$4
# insert necessary modules
insmod ipt_recent
insmod ipt_psd
# Drop previous offenders
iptables -N BANDITDROP
iptables -A INPUT -m recent --rcheck --name BANDIT -j BANDITDROP
iptables -A FORWARD -m recent --rcheck --name BANDIT -j BANDITDROP
iptables -A BANDITDROP -m recent --update --seconds 3600 --rttl --name BANDIT \
-j LOG --log-prefix "Bandit DROP " --log-tcp-sequence --log-tcp-options --log-ip-options
iptables -A BANDITDROP -j REJECT --reject-with icmp-net-unreachable
# Detect port scan
iptables -N PORTSCANDROP
iptables -A INPUT -i ${WANIF} -m psd -j PORTSCANDROP
iptables -A PORTSCANDROP -m recent --set --name BANDIT
iptables -A PORTSCANDROP -m recent --update --seconds 3600 --rttl --name BANDIT \
-j LOG --log-prefix "Port_Scan DROP " --log-tcp-sequence --log-tcp-options --log-ip-options
iptables -A PORTSCANDROP -j REJECT --reject-with icmp-net-unreachable
# SSH server with brute force prevention
iptables -N SSHFORCEDROP
iptables -N SSHACCEPT
iptables -A INPUT -m tcp -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 2 -j SSHACCEPT
iptables -A INPUT -m tcp -p tcp --dport 22 -j SSHFORCEDROP
iptables -A SSHFORCEDROP -m recent --set --name BANDIT
iptables -A SSHFORCEDROP -m recent --update --seconds 3600 --rttl --name BANDIT \
-j LOG --log-prefix "SSH_Brute_Force DROP " --log-tcp-sequence --log-tcp-options --log-ip-options
iptables -A SSHFORCEDROP -j REJECT --reject-with icmp-proto-unreachable
iptables -A SSHACCEPT -j LOG --log-prefix "SSH ACCEPT " --log-tcp-sequence \
--log-tcp-options --log-ip-options
iptables -A SSHACCEPT -j ACCEPT
iptables -t nat -A PREROUTING -i ${WANIF} -p tcp --dport 22 -j DNAT --to-destination ${LANIP}:22
iptables -A INPUT -j DROP
Hat den Vorteil, dass der Router nicht immer aller einer Minute das SysLog durchgehen muss.
Dumm ist nur, dass ich den 2. Lösungsweg erst nach der Fertigstellung des 1. auf http://www.macsat.com/forum/index.php?topic=206.0 entdeckt habe...
Werde trotzdem den 2. Lösungsweg wählen
Ciao