我想根据速率或连接限制动态阻止使用相同 IP 地址的特定连接。使用 Solaris/IPF 或某些 sendmail 扩展可以实现这一点吗?我想限制 sendmail 登录尝试以防止暴力攻击。
在 Linux 中,iptables 防火墙层可以轻松处理此问题,但我无法找到使用 ipf 在防火墙层限制此问题的方法。Sendmail 具有内置速率限制和连接限制,但它似乎适用于所有用户,因此如果我们遇到 DOS 或 DDOS,它会阻止所有用户,而不仅仅是攻击者。
答案1
看看这里,这些是基于 sendmail 的指令,可以防止洪水和不良行为,也许这对你有帮助: http://www.acme.com/mail_filtering/sendmail_config.html
我自己使用这些配置:
FEATURE(`greet_pause',2)
define(`confTO_ICONNECT', `15s')dnl
define(`confTO_CONNECT', `3m')dnl
define(`confTO_HELO', `2m')dnl
define(`confTO_MAIL', `1m')dnl
define(`confTO_RCPT', `1m')dnl
define(`confTO_DATAINIT', `1m')dnl
define(`confTO_DATABLOCK', `1m')dnl
define(`confTO_DATAFINAL', `1m')dnl
define(`confTO_RSET', `1m')dnl
define(`confTO_QUIT', `1m')dnl
define(`confTO_MISC', `1m')dnl
define(`confTO_COMMAND', `1m')dnl
define(`confTO_STARTTLS', `2m')dnl
define(`confTO_IDENT', `0s')dnl
define(`confTO_RESOLVER_RETRANS', `7s')dnl
define(`confTO_RESOLVER_RETRY', `4')dnl
define(`confMAX_RCPTS_PER_MESSAGE', `15')dnl
define(`confMAX_DAEMON_CHILDREN',`256')dnl
define(`confCONNECTION_RATE_THROTTLE',`8')dnl
define(`confBAD_RCPT_THROTTLE', `1')dnl Sendmail v8.12+
define(`confQUEUE_LA', `10')dnl
define(`confREFUSE_LA', `30')dnl
此外,您可以搜索名为 greypit 的实现。我不太了解该主题,但 greypit 应该有 ip 基础连接限制,也许有 solaris 版本。
另一种方法如下。检查您的日志中是否存在大量 dos 活动或虚假登录,并在 access 中使用greetpause。如果您发现恶意行为,请在您的 access 中插入如下一行并重新生成您的 access.db
GreetPause:bad.ip.dos.attacker.com 100
从现在开始,来自 ip 或主机名的每个请求都必须等待 100 秒才能获得 helo。
我以相反的方式使用了此功能,但它也可以用于阻止不需要的连接。
执行这些条目的脚本只是一个 cron 脚本,但要注意,它只是为了获得良好的流量而采取的另一种方式,您必须手动重新创建 access.db:
#!/bin/sh
declare -a a
let count=0
accessmap="/tmp/access.test"
logfiles="/var/log/mail.log"
mailfile="/tmp/tmpmail.mail"
email="[email protected]"
## hole alle IP Eintraege aus sendmail access und packe sie in ein array mit prefix und postfix
for x in $(echo $(grep -e "^GreetP" $accessmap | cut -f 2 -d ":" | cut -f 1 -d " ")); do
a[$count]=$(echo "^"$x"|");
((count++));
done
echo Number of elements: ${#a[@]} > $mailfile
#entferne whitespaces
#entferne | am ende der Zeile
b=$(echo ${a[@]} | sed "s/ //g"| sed "s/|$//")
#nun steht in der Variable den string den wir zum filtern wollen!
#echo $b
buffer=0
buffer_changed=0
datum=$(date +%Y.%m.%d__%H:%M:%S)
for x in $(grep authid $logfiles |grep "AUTH=server"|cut -f 3 -d "[" | cut -f 1 -d "-" | sort | uniq |egrep -v -e "$b" | sed "s/ (may be forged)//"|sed "s/]//"|sed "s/, authid=/#/"
if [ $buffer -eq 0 ]; then
buffer=1
echo >> $accessmap
echo "#Eintraege vom $datum" >> $accessmap
echo >> $accessmap
buffer_changed=1
fi
echo "GreetPause:$x"| sed "s/#/ \t\t0\t#/" >> $accessmap
done
if [ $buffer -eq 1 ]; then
echo "Command: zgrep with filter $b" >> $mailfile
echo >> $mailfile
echo >> $mailfile
echo "accessmap GreetingPause:">> $mailfile
cat $accessmap | grep -B 2 "GreetPause" >> $mailfile
echo >> $mailfile
mail -s "Acessmap changed" $email < $mailfile
fi