刚才抽空搞了一下脚本,可以用下面的语句找出有问题的域名:
```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 记录。