防火墙
程序员文章站
2022-06-11 09:53:40
...
2006-06-12
http://forum.iteye.com/viewtopic.php?t=20177&postdays=0&postorder=asc&start=15
防火墙
不是什么防火墙,其实就是用Java写了一个脚本,定期扫描netstat状态,检测80端口的连接IP数量和状态,当超过一个阀值,就调用iptables ban掉它,30分钟之后才解除*。其实这种脚本用perl/python/ruby去写可能更好,但是我比较熟悉Java,就用Java写了一个,主要是为了解决对网站的恶意访问的,例如使用webzip之类工具抓网站,非IP伪装类的DOS攻击,都有比较好的效果。当然有时候也会误杀一些IP(例如公司里面很多人访问javaeye,都喜欢一下点开很多页面导致超过阀值)。
控制服务的脚本ban.sh
http://forum.iteye.com/viewtopic.php?t=20177&postdays=0&postorder=asc&start=15
防火墙
不是什么防火墙,其实就是用Java写了一个脚本,定期扫描netstat状态,检测80端口的连接IP数量和状态,当超过一个阀值,就调用iptables ban掉它,30分钟之后才解除*。其实这种脚本用perl/python/ruby去写可能更好,但是我比较熟悉Java,就用Java写了一个,主要是为了解决对网站的恶意访问的,例如使用webzip之类工具抓网站,非IP伪装类的DOS攻击,都有比较好的效果。当然有时候也会误杀一些IP(例如公司里面很多人访问javaeye,都喜欢一下点开很多页面导致超过阀值)。
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; /** * @author Robbin Fan * */ public class IPBanner { public static final String NETSTAT = "netstat -nt"; public static final String IP_INSERT = "iptables -I INPUT -i eth0 -j DROP -p tcp --dport 80 -s "; public static final String IP_DEL = "iptables -D INPUT -i eth0 -j DROP -p tcp --dport 80 -s "; public static final String HOST_IP = "61.129.70.239:80"; public static final long BAN_TIMEOUT = 30 * 60 * 1000L; public static final long BAN_INTERVAL = 30 * 1000L; public static final int CONCURRENT = 80; public static final int SYN_CONCURRENT = 8; public static final Map banMap = new HashMap(); public static void ban() throws Exception { Set banList = dynamicBanIP(); System.out.println(); System.out.println("Time: " + new Date()); Runtime runtime = Runtime.getRuntime(); List expiredIPList = new ArrayList(); for (Iterator iter = banMap.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next(); if ((System.currentTimeMillis() - ((Long) entry.getValue()).longValue()) > BAN_TIMEOUT) { expiredIPList.add(entry.getKey()); } } for (int i = 0; i <expiredIPList.size(); i++) { runtime.exec(IP_DEL + expiredIPList.get(i)); System.out.println("DEL IP: " + expiredIPList.get(i)); banMap.remove(expiredIPList.get(i)); } for (Iterator iter = banList.iterator(); iter.hasNext();) { String ip = (String) iter.next(); if (!banMap.containsKey(ip)) { runtime.exec(IP_INSERT + ip); banMap.put(ip, new Long(System.currentTimeMillis())); System.out.println("BAN IP:" + ip); } } System.out.println("---ban ip list---"); for (Iterator iter = banMap.keySet().iterator(); iter.hasNext();) { String ip = (String) iter.next(); System.out.println(ip); } } public static Set dynamicBanIP() throws Exception { String ipstat = null; Set banList = new HashSet(); List ipList = new ArrayList(); List countList = new ArrayList(); List synCountList = new ArrayList(); List finCountList = new ArrayList(); Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(NETSTAT); InputStream input = process.getInputStream(); InputStreamReader inputReader = new InputStreamReader(input); BufferedReader reader = new BufferedReader(inputReader); reader.readLine(); reader.readLine(); while ((ipstat = reader.readLine()) != null) { StringTokenizer token = new StringTokenizer(ipstat); while (token.hasMoreTokens()) { token.nextToken(); token.nextToken(); token.nextToken(); String originalIP = token.nextToken(); String ip = token.nextToken().split(":")[0]; String status = token.nextToken(); if (HOST_IP.equals(originalIP)) { if (!ipList.contains(ip)) { ipList.add(ip); countList.add(new Integer(1)); if ("SYN_RECV".equals(status)) { synCountList.add(new Integer(1)); } else { synCountList.add(new Integer(0)); } if ("FIN_WAIT1".equals(status)) { finCountList.add(new Integer(1)); } else { finCountList.add(new Integer(0)); } } else { int index = ipList.indexOf(ip); countList.set(index, new Integer(((Integer) countList.get(index)).intValue() + 1)); if ("SYN_RECV".equals(status)) { synCountList.set(index, new Integer(((Integer) synCountList.get(index)).intValue() + 1)); } if ("FIN_WAIT1".equals(status)) { finCountList.set(index, new Integer(((Integer) finCountList.get(index)).intValue() + 1)); } } } } } reader.close(); inputReader.close(); input.close(); process.destroy(); for (int i = 0; i < ipList.size(); i++) { if (((Integer) countList.get(i)).intValue() > CONCURRENT) banList.add(ipList.get(i)); if (((Integer) synCountList.get(i)).intValue() > SYN_CONCURRENT) banList.add(ipList.get(i)); if (((Integer) finCountList.get(i)).intValue() > SYN_CONCURRENT) banList.add(ipList.get(i)); } return banList; } public static void main(String[] args) throws Exception { while (true) { ban(); Thread.sleep(BAN_INTERVAL); } } }
控制服务的脚本ban.sh
#!/bin/sh cd /root/bin case "$1" in start) nohup /usr/local/jdk1.5.0_05/bin/java -client IPBanner > ban.log 2>&1 & echo $! > ban.pid ;; stop) kill `cat ban.pid` rm -rf ban.pid ;; restart) $0 stop sleep 1 $0 start ;; *) echo "Usage: ban.sh {start|stop|restart}" ;; esac exit 0
上一篇: PHP连接access数据库_php技巧