怎么做ip过滤

问题

为了防止您的网站被恶意攻击,你会对系统设置一个ip黑名单来挡住那些恶意攻击的的ip。怎样才能实现一个高效的ip过滤呢。
发散思维的方式写一个ip过滤的

方案一:布隆过滤器

布隆过滤器

  • 创建一个位图(java用bitset实现,生成中应该用的是redis的位图)。
  • 一个ip用N种hash算法生成N种int值,分别赋值到位图中。
  • 新来个ip直接在用这N种hash算出int值,在位图种查找判断是否存在。若都存在就认为这ip是要过滤的ip。

public class BloomIp {
    /**
     * bitSet只能是正数设个size保证hash算的是正数
     */
    private static final int SIZE = 1<<24;
    BitSet bitSet=new BitSet(SIZE);
    Hash[] hashs=new Hash[3];
    private static final int seeds[]=new int[]{3,5,7};
    public static void main(String[] args) {
        String ip="192.168.1.1";
        BloomIp bloomDemo=new BloomIp();
        System.out.println(ip+"是否在列表中: "+bloomDemo.contains(ip));
        bloomDemo.add(ip);
        System.out.println(ip+"是否在列表中: "+bloomDemo.contains(ip));
        ip="192.168.1.2";
        System.out.println(ip+"是否在列表中: "+bloomDemo.contains(ip));
        bloomDemo.add("255.255.255.255");

    }
    public BloomIp(){
        for (int i = 0; i < seeds.length; i++) {
            hashs[i]=new Hash(seeds[i]);
        }
    }
    public void add(String string){
        for(Hash hash:hashs){
            bitSet.set(hash.getHash(string),true);
        }
    }
    public boolean contains(String string){
        boolean have=true;
        for(Hash hash:hashs){
            have&=bitSet.get(hash.getHash(string));
        }
        return have;
    }
    class Hash{
        public int getSeed() {
            return seed;
        }

        private int seed = 0;
        public Hash(int seed){
            this.seed=seed;
        }
        public int getHash(String string){
            int val=0;
            int len=string.length();
            for (int i = 0; i < len; i++) {
                val = val * seed + string.charAt(i);
            }
            return val&(SIZE-1);
        }
    }

}

局限性

1.假如ipA在位图中是[2,5,8],ipB在位图中是[3,5,9],一个不应该被过滤的ipC在位图是[3,5,8],就会涉及到二次过滤白名单的解决方案。
2.ip黑明单的ip增加是没有问题,但是减少;ip就没法做,例如ipA在位图中是[2,5,8],ipB在位图中是[3,5,9]删除ipB会很麻烦。
只能全量重新编译位图或要涉及很多计算判断。

方案二 ip转int + 位图实现。

ip是什么0-255.0-255.0-255.0-255
单看0-255 说白了就是2^8就能表示。
0-255.0-255.0-255.0-255也就是(2^8)* (2^8)* (2^8)* (28)*=232。
int占4个字节32位正好也是2^32.
一个ip完全可以转成一个int。

public class BitIp {
    /**
     * int 范围是 -2^31——2^31-1
     * bitset只能存正数0-2^31-1,所以要两个bitset
     */
    private static final int SIZE = 1 << 31 - 1;
    /**
     * 这里存正数
     */
    BitSet aSet = new BitSet(SIZE);
    /**
     * 这里存负数
     */
    BitSet bSet = new BitSet(SIZE);

    public static void main(String[] args) {
        String ip = "192.168.1.1";
        BitIp bitIp = new BitIp();
        System.out.println(ip + "是否在列表中: " + bitIp.contains(ip));
        bitIp.add(ip);
        System.out.println(ip + "是否在列表中: " + bitIp.contains(ip));
        bitIp.delete(ip);
        System.out.println(ip + "是否在列表中: " + bitIp.contains(ip));
        ip = "192.168.1.2";
        System.out.println(ip + "是否在列表中: " + bitIp.contains(ip));

    }

    public void add(String ip) {
        int i = ip2Int(ip);
        BitSet tempSet = i >= 0 ? aSet : bSet;
        tempSet.set(i >= 0 ? i : -(i + 1), true);
    }


    public void delete(String ip) {
        int i = ip2Int(ip);
        BitSet tempSet = i >= 0 ? aSet : bSet;
        tempSet.set(i >= 0 ? i : -(i + 1), false);
    }

    public boolean contains(String ip) {
        int i = ip2Int(ip);
        BitSet tempSet = i >= 0 ? aSet : bSet;
        return tempSet.get(i >= 0 ? i : -(i + 1));
    }

    public static int ip2Int(String ip) {
        String[] split = ip.split("\\.");
        int result = 0;
        for (String s : split) {
            int i = Integer.parseInt(s);
            result = (result << 8) + i;
        }
        return result;
    }

}


优点,可以做增删ip。不需要太多的运算。
缺点,占用了比布隆过滤器更多的内存。(ip分散小,不多的话差不太多,可以看看bitset的设计方案。)
最多内存占用量是2^32 b
转化byte是2^29 byte
转化kb是2^19 kb
转化mb是2^9 mb
也就是512mb,其实是可以接受的。

代码 https://github.com/jlhuang9/iptest

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: IP池技术是一种可以用于网络代理或者爬虫等场景下的技术。它可以模拟多个IP地址来访问目标站点,从而达到绕过访问限制的效果。具体来说,IP池技术是通过建立一个IP地址池,然后随机从其中选择一个IP地址来进行访问的方式。这样的好处是可以在一定程度上隐藏用户的真实IP地址,避免被封禁或者限制访问。同时,也可以提高爬虫的效率,因为可以通过IP池来避免访问频率过快而被封禁的问题。 ### 回答2: IP池技术是一种动态管理和分配IP地址的技术。它允许网络管理员有效地管理和分配大量IP地址,并且可用于实现网络地址转换(NAT)和负载平衡等功能。 IP池技术的主要功能包括以下几个方面: 1. IP地址管理:IP池技术可以帮助网络管理员有效地管理IP地址资源。它可以自动分配和释放IP地址,避免IP地址的浪费和冲突。管理员可以根据需求创建IP地址池,并灵活地分配给不同的网络设备或用户。 2. NAT功能:IP池技术可以与网络地址转换(NAT)结合使用,实现多个内部设备共享一个公网IP地址的功能。通过IP池技术,可以将内部设备的私有IP地址映射到公网IP地址,从而实现对外部网络的访问。 3. 负载平衡:通过IP池技术,可以将大量的服务器或设备组织成一个IP池,实现负载平衡功能。当用户请求到达时,IP池技术可以自动选择一个空闲的服务器或设备来处理请求,从而提高系统的负载均衡能力和可靠性。 4. 安全控制:IP池技术可以与防火墙等安全设备结合使用,实现对特定IP地址或IP地址范围的访问控制。管理员可以根据需要设置特定的策略,限制或允许某些IP地址的访问,提高网络的安全性。 总之,IP池技术是一种非常重要的网络技术,它可以帮助管理员管理和分配IP地址,实现NAT和负载平衡等功能。通过合理使用IP池技术,可以提高网络的可用性、安全性和效率。 ### 回答3: IP池技术,也称为IP地址池技术,是指利用一组统一管理的IP地址资源进行分配和管理的技术。它在网络领域中起到了重要作用。 首先,IP池技术可以用于网络访问控制。通过分配不同的IP地址给不同的用户或设备,可以实现对其访问网络资源的控制和管理。比如,可以根据IP地址来实现黑白名单过滤,只允许特定的IP地址访问某些敏感的网络资源。 其次,IP池技术还可以用于网络负载均衡。在一个高并发的网络环境中,为了使网络流量更加均衡地分布到各个服务器上,可以将一组IP地址放入IP池中,然后通过负载均衡设备按照一定的算法将网络请求分发到不同的IP地址上,从而实现负载均衡。 此外,IP池技术还可以用于网络安全防护。通过动态分配和更新IP地址,可以有效防止恶意攻击者对网络进行攻击和入侵。当网络检测到某个IP地址存在异常行为时,可以将该IP地址从IP池中移除或标记为不可信,并且将其流量引导到安全设备进行进一步分析和防护。 总之,IP池技术在网络管理和安全方面发挥着重要作用,它能够有效地提高网络资源的利用率和安全性。通过合理的分配和管理IP地址,可以更好地满足用户和网络的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值