[size=18][color=red]2006-06-12[/color]
[/size]
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
[/size]
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