刚才抽空搞了一下脚本,可以用下面的语句找出有问题的域名:
grep query /var/log/dnsmasq.log|awk '{if(substr($9,1,2)!="10"){print $7}}'|awk -F"." '{if(NF==3){print $2"."$3}}'|sort|uniq -c|sort -n
能得到这样的结果:
一堆正常的
6900 web-175.com
209091 scr888.com
把那哥们的脚本简化了一下:
#!/bin/bash
create_iptables(){
name=$1
string=$( echo $name|awk -F '.' '{for(i=1;i<=NF;i++){printf("|%02d|%s",length($i),$i)}}')
string="$string|00|"
echo -e "rule for \e[1;32m $name \e[mquery:"
eval 'echo "iptables -t raw -A PREROUTING -p udp --dport 53 -m string --hex-string \"$string\" --algo bm -j LOG --log-prefix \"drop an dns query \""'
eval 'echo "iptables -t raw -A PREROUTING -p udp --dport 53 -m string --hex-string \"$string\" --algo bm -j DROP"'
}
for domain in $@
do
echo "DROP $domain rule:"
create_iptables $domain
done
这样需要经常执行脚本得到恶意解析的域名,然后再用上面的脚本来加 iptables,效果还是不错的,日志里看到不少 drop 掉的请求:
/var/log/messages:Oct 25 13:40:53 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=19.181.62.199 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=237 ID=50750 DF PROTO=UDP SPT=25649 DPT=53 LEN=49
/var/log/messages:Oct 25 13:40:53 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=106.105.134.235 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=234 ID=60038 DF PROTO=UDP SPT=22975 DPT=53 LEN=49
/var/log/messages:Oct 25 13:40:56 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=98.80.54.16 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=230 ID=3894 DF PROTO=UDP SPT=63664 DPT=53 LEN=49
后续再有必要的话,就把脚本再完善一下,整合成一个脚本,扔 crontab 里1小时跑一次,把解析数量超级多的全都干掉,然后清 dnsmasq.log。
PS,我那个 !="10" 的判断是忽略内部 IP 的 query 记录。
1
Siril 2016-10-24 17:52:46 +08:00
如果 dnsmasq 不是跑在路由上那种,(没有严格的资源限制)
可以考虑 换 bind 9.10 简单点直接 docker pull ventz/bind 然后可以用其自带的 rate-limit 之。 |
2
EricInBj OP @Siril rate-limit 是针对固定来源 ip 的吧?像我碰到的这样的,随机产生的二级域名,随机的来源 IP ,好像不行?
|
3
EricInBj OP 刚才抽空搞了一下脚本,可以用下面的语句找出有问题的域名:
```shell grep query /var/log/dnsmasq.log|awk '{if(substr($9,1,2)!="10"){print $7}}'|awk -F"." '{if(NF==3){print $2"."$3}}'|sort|uniq -c|sort -n ``` 能得到这样的结果: ```shell 一堆正常的 6900 web-175.com 209091 scr888.com ``` 把那哥们的脚本简化了一下: ```shell #!/bin/bash create_iptables(){ name=$1 string=$( echo $name|awk -F '.' '{for(i=1;i<=NF;i++){printf("|%02d|%s",length($i),$i)}}') string="$string|00|" echo -e "rule for \e[1;32m $name \e[mquery:" eval 'echo "iptables -t raw -A PREROUTING -p udp --dport 53 -m string --hex-string \"$string\" --algo bm -j LOG --log-prefix \"drop an dns query \""' eval 'echo "iptables -t raw -A PREROUTING -p udp --dport 53 -m string --hex-string \"$string\" --algo bm -j DROP"' } for domain in $@ do echo "DROP $domain rule:" create_iptables $domain done ``` 这样需要经常执行脚本得到恶意解析的域名,然后再用上面的脚本来加 iptables ,效果还是不错的,日志里看到不少 drop 掉的请求: ```shell /var/log/messages:Oct 25 13:40:53 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=19.181.62.199 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=237 ID=50750 DF PROTO=UDP SPT=25649 DPT=53 LEN=49 /var/log/messages:Oct 25 13:40:53 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=106.105.134.235 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=234 ID=60038 DF PROTO=UDP SPT=22975 DPT=53 LEN=49 /var/log/messages:Oct 25 13:40:56 ip-172-133-15-130 kernel: drop an dns query IN=eth0 OUT= MAC=d0:0d:0d:0b:e5:9e:50:e5:49:33:70:e8:08:00 SRC=98.80.54.16 DST=172.133.15.130 LEN=69 TOS=0x00 PREC=0x00 TTL=230 ID=3894 DF PROTO=UDP SPT=63664 DPT=53 LEN=49 ``` 后续再有必要的话,就把脚本再完善一下,整合成一个脚本,扔 crontab 里 1 小时跑一次,把解析数量超级多的全都干掉,然后清 dnsmasq.log 。 PS ,我那个 !="10" 的判断是忽略内部 IP 的 query 记录。 |