Hits: 41

使用iptables封指定IP访问网站的方法

近来网站访问量异常增长,通过分析apache access_log找出了频繁访问的IP地址,确认是盗链,决定使用iptables封掉.

脚本如下:

# awk ‘{print $1}’ access_log.20110622 |sort |uniq -c |sort -nr |more
15112 183.38.186.60
5289 218.83.160.164
4566 58.61.154.18
4428 183.39.105.113
3169 121.14.162.56
2121 113.108.116.17
1971 121.14.162.46
1614 121.14.162.65
1515 192.168.39.134
1430 59.152.221.14
1391 121.14.162.47
1350 183.38.181.117
1317 183.38.189.202
1293 121.14.162.85
1285 121.14.162.117

iptables的使用方法如下:

封单个IP的命令
iptables -I INPUT -s 183.38.186.60 -j DROP

封IP段的命令
iptables -I INPUT -s 183.38.186.0/16 -j DROP

封整个段的命令
iptables -I INPUT -s 183.38.0.0/8 -j DROP

封几个段的命令
iptables -I INPUT -s 183.38.186.0/24 -j DROP
iptables -I INPUT -s 183.38.187.0/24 -j DROP

只封80端口
iptables -I INPUT -p tcp –-dport 80 -s 183.38.186.0/24 -j DROP
iptables -I INPUT -s 183.38.186.0/24 -j DROP

删除所有限制项
iptables -F

删除指定限制项

iptables -D INPUT 数字

如 iptables -D INPUT 1

查看iptables配置项
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  —  10.200.1.149         anywhere            tcp dpt:http

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
#

删除一个配置项
# iptables -D INPUT 1

复核iptables配置项
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
#

思路:

  1. 找到指定域名的ip
  2. 指定域名的ip可以通过防火墙

如何在Linux中通过命令查看域名对应的IP            https://www.jianshu.com/p/efec391beee5

iptables基于域名的访问控制         https://www.jianshu.com/p/a2098cbea498

Firewall rules based on Domain name instead of IP address

https://www.cnblogs.com/xiaofeng666/p/10952627.html     转载Linux下使用 ipset 封大量IP及ipset参数说明

 

iptables doesn't work with domains but you can create a ipset and update its content periodically. 
ipset create allowed hash:ip 
iptables rule will look like
iptables -I INPUT -p tcp --dport 5939 -j DROP
iptables -I INPUT -p tcp --dport 5939 -m set --match-set allowed src -j ACCEPT

Create a simple script that do domain lookup and update allowed list.
#!env /bin/bash
ip=`ping -c 2 PI-ROBOT.F3322.NET | head -2 | tail -1 | awk '{print $5}' | sed 's/[(:)]//g'`

ipset flush allowed
ipset add allowed $ip

And add cronjob (Every 5 min in this example)

*/5 * * * * root /path/to/myscript.sh

ping -c 2 www.linux.com | head -2 | tail -1 | awk '{print $5}' | sed 's/[(:)]//g'
ping -c 1 -t 1 ngx.hk | grep 'PING' | awk '{print $3}' | sed 's/[(,)]//g'
https://ngx.hk/2017/03/16/%E4%BD%BF%E7%94%A8shell%E5%8A%A8%E6%80%81%E6%9B%B4%E6%96%B0iptables.html   使用shell动态更新iptables
https://www.linuxdiyf.com/linux/18940.html     Shell脚本设置IPtables规则指定动态IP服务器通过访问
https://blog.csdn.net/xujiamin0022016/article/details/85864087   shell动态更新iptables

crontab执行脚本失败,手动执行成功

开始百思不得其解,后面发现发现cron的环境变量少了路径,所以以后crontab 里面的脚本命令带完整路径,或设置环境变量

记得赋予脚本文件的执行权限

ipudate
#!/bin/sh
 
get_ip=`ping -c 1 -t 1 PI-ROBOT.F3322.NET | grep 'PING' | awk '{print $3}' | sed 's/[(,)]//g'`
 
cd `dirname $0`
 
if [ -e './trust_ip.txt' ]; then
 old_ip=`tail ./trust_ip.txt -n 1`
 if ! [ "$old_ip" = "$get_ip"  ]; then 
 `/sbin/iptables -D INPUT -p tcp --dport 5939 -s $old_ip -j ACCEPT`
 `/sbin/iptables -D INPUT -p tcp --dport 5917 -s $old_ip -j ACCEPT` 
 `/sbin/iptables -I INPUT -p tcp --dport 5939 -s $get_ip -j ACCEPT`
 `/sbin/iptables -I INPUT -p tcp --dport 5917 -s $get_ip -j ACCEPT` 
  echo $get_ip >> ./trust_ip.txt
 fi
else
 `/sbin/iptables -I INPUT -p tcp --dport 5939 -s $get_ip -j ACCEPT`
 `/sbin/iptables -I INPUT -p tcp --dport 5917 -s $get_ip -j ACCEPT`
 echo $get_ip >> ./trust_ip.txt
fi

ipudate ( 小米路由器 )
#!/bin/sh
 
get_ip=`ping PI-ROBOT.F3322.NET -c 1 | sed '1{s/[^(]*(//;s/).*//;q}'`
 
cd `dirname $0`
 
if [ -e './trust_ip.txt' ]; then
 old_ip=`tail ./trust_ip.txt -n 1`
 if ! [ "$old_ip" = "$get_ip"  ]; then 
 `/usr/sbin/iptables -D INPUT -p tcp --dport 5939 -s $old_ip -j ACCEPT`
 `/usr/sbin/iptables -D INPUT -p tcp --dport 5917 -s $old_ip -j ACCEPT` 
 `/usr/sbin/iptables -I INPUT -p tcp --dport 5939 -s $get_ip -j ACCEPT`
 `/usr/sbin/iptables -I INPUT -p tcp --dport 5917 -s $get_ip -j ACCEPT`
  echo $get_ip >> ./trust_ip.txt
 fi
else
 `/usr/sbin/iptables -I INPUT -p tcp --dport 5939 -s $get_ip -j ACCEPT`
 `/usr/sbin/iptables -I INPUT -p tcp --dport 5917 -s $get_ip -j ACCEPT`
 echo $get_ip >> ./trust_ip.txt
fi

drop
iptables -I INPUT -p tcp --dport 5939 -j DROP
iptables -I INPUT -p tcp --dport 5917 -j DROP
iptables -I INPUT -p tcp --dport 8114 -j DROP
rm -rf /root/pirobot/trust_ip.txt
rm -rf /root/frp2/trust_ip.txt
/root/ipupdate

iptables -I INPUT -p tcp --dport 5939 -j DROP
iptables -I INPUT -s 192.168.31.0/24 -p tcp --dport 5939 -j ACCEPT