精华内容
下载资源
问答
  • 前言 限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,...如何防止恶意IP攻击某些暴露的接口呢(比如某些场景下短信验证码服务)?本文介绍一种本地缓存和分布式缓存集成方式判断远程IP是否为...

    一、前言

    限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,使用Guava RateLimiter就可以满足。但是Guava RateLimiter只能应用于单进程,多进程间协同控制便无能为力。本文介绍一种简单的处理方式,用于分布式环境下接口调用频次管控。

    如何防止恶意IP攻击某些暴露的接口呢(比如某些场景下短信验证码服务)?本文介绍一种本地缓存和分布式缓存集成方式判断远程IP是否为恶意调用接口的IP。

    二、分布式IP限流

    思路是使用redis incr命令,完成一段时间内接口请求次数的统计,以此来完成限流相关逻辑。

    private static final String LIMIT_LUA =
        "local my_limit = redis.call('incr', KEYS[1])\n" +
                " if tonumber(my_limit) == 1 then\n" +
                "   redis.call('expire', KEYS[1], ARGV[1])\n" +
                "   return 1\n" +
                " elseif tonumber(my_limit) > tonumber(ARGV[2]) then\n" +
                "   return 0\n" +
                " else\n" +
                "   return 1\n" +
                " end\n";

    这里为啥时候用lua脚本来实现呢?因为要保证incr命令和expire命令的原子性操作。KEYS[1]代表自增key值, ARGV[1]代表过期时间,ARGV[2]代表最大频次,明白了这些参数的含义,整个lua脚本逻辑也就不言而喻了。

    /**
     * @param limitKey 限制Key值
     * @param maxRate  最大速率
     * @param expire   Key过期时间
     */
    public boolean access(String limitKey, int maxRate, int expire) {
        if (StringUtils.isBlank(limitKey)) {
            return true;
        }
    
        String cacheKey = LIMIT_KEY_PREFIX + limitKey;
    
        return REDIS_SUCCESS_STATUS.equals(
                this.cacheService.eval(
                        LIMIT_LUA
                        , Arrays.asList(cacheKey)
                        , Arrays.asList(String.valueOf(expire), String.valueOf(maxRate))
                ).toString()
        );
    }
    
    public void unlimit(String limitKey) {
        if (StringUtils.isBlank(limitKey)) {
            return;
        }
        String cacheKey = LIMIT_KEY_PREFIX + limitKey;
        this.cacheService.decr(cacheKey);
    }

    access方法用来判断 limitKey 是否超过了最大访问频次。缓存服务对象(cacheService)的eval方法参数分别是lua脚本、key list、value list。

    unlimit方法其实就是执行redis decr操作,在某些业务场景可以回退访问频次统计。

    三、防止恶意IP攻击

    由于某些对外暴露的接口很容易被恶意用户攻击,必须做好防范措施。最近我就遇到了这么一种情况,我们一个快应用产品,短信验证码服务被恶意调用了。通过后台的日志发现,IP固定,接口调用时间间隔固定,明显是被人利用了。虽然我们针对每个手机号每天发送短信验证码的次数限制在5次以内。但是短信验证码服务每天这样被重复调用,会打扰用户并产生投诉。针对这种现象,简单的做了一个方案,可以自动识别恶意攻击的IP并加入黑名单。

    思路是这样的,针对某些业务场景,约定在一段时间内同一个IP访问最大频次,如果超过了这个最大频次,那么就认为是非法IP。识别了非法IP后,把IP同时放入本地缓存和分布式缓存中。非法IP再次访问的时候,拦截器发现本地缓存(没有则去分布式缓存)有记录这个IP,直接返回异常状态,不会继续执行正常业务逻辑。

    Guava本地缓存集成Redis分布式缓存

    public abstract class AbstractCombineCache<K, V> {
        private static Logger LOGGER = LoggerFactory.getLogger(AbstractCombineCache.class);
    
        protected Cache<K, V> localCache;
    
        protected ICacheService cacheService;
    
        public AbstractCombineCache(Cache<K, V> localCache, ICacheService cacheService) {
            this.localCache = localCache;
            this.cacheService = cacheService;
        }
    
        public Cache<K, V> getLocalCache() {
            return localCache;
        }
    
        public ICacheService getCacheService() {
            return cacheService;
        }
    
        public V get(K key) {
           //只有LoadingCache对象才有get方法,如果本地缓存不存在key值, 会执行CacheLoader的load方法,从分布式缓存中加载。
            if (localCache instanceof LoadingCache) {
                try {
                    return ((LoadingCache<K, V>) localCache).get(key);
                } catch (ExecutionException e) {
                    LOGGER.error(String.format("cache key=%s loading error...", key), e);
                    return null;
                } catch (CacheLoader.InvalidCacheLoadException e) {
                    //分布式缓存中不存在这个key
                    LOGGER.error(String.format("cache key=%s loading fail...", key));
                    return null;
                }
            } else {
                return localCache.getIfPresent(key);
            }
        }
    
        public void put(K key, V value, int expire) {
            this.localCache.put(key, value);
            String cacheKey = key instanceof String ? (String) key : key.toString();
            if (value instanceof String) {
                this.cacheService.setex(cacheKey, (String) value, expire);
            } else {
                this.cacheService.setexObject(cacheKey, value, expire);
            }
        }
    }

    AbstractCombineCache这个抽象类封装了guava本地缓存和redis分布式缓存操作,可以降低分布式缓存压力。

    防止恶意IP攻击缓存服务

    public class IPBlackCache extends AbstractCombineCache<String, Object> {
        private static Logger LOGGER = LoggerFactory.getLogger(IPBlackCache.class);
    
        private static final String IP_BLACK_KEY_PREFIX = "wmhipblack_";
    
        private static final String REDIS_SUCCESS_STATUS = "1";
    
        private static final String IP_RATE_LUA =
                "local ip_rate = redis.call('incr', KEYS[1])\n" +
                        " if tonumber(ip_rate) == 1 then\n" +
                        "   redis.call('expire', KEYS[1], ARGV[1])\n" +
                        "   return 1\n" +
                        " elseif tonumber(ip_rate) > tonumber(ARGV[2]) then\n" +
                        "   return 0\n" +
                        " else\n" +
                        "   return 1\n" +
                        " end\n";
    
        public IPBlackCache(Cache<String, Object> localCache, ICacheService cacheService) {
            super(localCache, cacheService);
        }
    
        /**
         * @param ipKey   IP
         * @param maxRate 最大速率
         * @param expire  过期时间
         */
        public boolean ipAccess(String ipKey, int maxRate, int expire) {
            if (StringUtils.isBlank(ipKey)) {
                return true;
            }
    
            String cacheKey = IP_BLACK_KEY_PREFIX + ipKey;
    
            return REDIS_SUCCESS_STATUS.equals(
                    this.cacheService.eval(
                            IP_RATE_LUA
                            , Arrays.asList(cacheKey)
                            , Arrays.asList(String.valueOf(expire), String.valueOf(maxRate))
                    ).toString()
            );
        }
    
        /**
         * @param ipKey IP
         */
        public void removeIpAccess(String ipKey) {
            if (StringUtils.isBlank(ipKey)) {
                return;
            }
            String cacheKey = IP_BLACK_KEY_PREFIX + ipKey;
            try {
                this.cacheService.del(cacheKey);
            } catch (Exception e) {
                LOGGER.error(String.format("%s, ip access remove error...", ipKey), e);
            }
        }
    }

    没有错,IP_RATE_LUA 这个lua脚本和上面说的限流方案对应的lua脚本是一样的。

    IPBlackCache继承了AbstractCombineCache,构造函数需要guava的本地Cache对象和redis分布式缓存服务ICacheService 对象。

    ipAccess方法用来判断当前ip访问次数是否在一定时间内已经达到了最大访问频次。

    removeIpAccess方法是直接移除当前ip访问频次统计的key值。

    防止恶意IP攻击缓存配置类

    @Configuration
    public class IPBlackCacheConfig {
        private static final String IPBLACK_LOCAL_CACHE_NAME = "ip-black-cache";
        private static Logger LOGGER = LoggerFactory.getLogger(IPBlackCacheConfig.class);
    
        @Autowired
        private LimitConstants limitConstants;
    
        @Bean
        public IPBlackCache ipBlackCache(@Autowired ICacheService cacheService) {
            GuavaCacheBuilder cacheBuilder = new GuavaCacheBuilder<String, Object>(IPBLACK_LOCAL_CACHE_NAME);
            cacheBuilder.setCacheBuilder(
                    CacheBuilder.newBuilder()
                            .initialCapacity(100)
                            .maximumSize(10000)
                            .concurrencyLevel(10)
                            .expireAfterWrite(limitConstants.getIpBlackExpire(), TimeUnit.SECONDS)
                            .removalListener((RemovalListener<String, Object>) notification -> {
                                String curTime = LocalDateTime.now().toString();
                                LOGGER.info(notification.getKey() + " 本地缓存移除时间:" + curTime);
                                try {
                                    cacheService.del(notification.getKey());
                                    LOGGER.info(notification.getKey() + " 分布式缓存移除时间:" + curTime);
                                } catch (Exception e) {
                                    LOGGER.error(notification.getKey() + " 分布式缓存移除异常...", e);
                                }
                            })
            );
            cacheBuilder.setCacheLoader(new CacheLoader<String, Object>() {
                @Override
                public Object load(String key) {
                    try {
                        Object obj = cacheService.getString(key);
                        LOGGER.info(String.format("从分布式缓存中加载key=%s, value=%s", key, obj));
                        return obj;
                    } catch (Exception e) {
                        LOGGER.error(key + " 从分布式缓存加载异常...", e);
                        return null;
                    }
                }
            });
    
            Cache<String, Object> localCache = cacheBuilder.build();
            IPBlackCache ipBlackCache = new IPBlackCache(localCache, cacheService);
            return ipBlackCache;
        }
    }

    注入redis分布式缓存服务ICacheService对象。

    通过GuavaCacheBuilder构建guava本地Cache对象,指定初始容量(initialCapacity)、最大容量(maximumSize)、并发级别、key过期时间、key移除监听器。最终要的是CacheLoader这个参数,是干什么用的呢?如果GuavaCacheBuilder指定了CacheLoader对象,那么最终创建的guava本地Cache对象是LoadingCache类型(参考AbstractCombineCache类的get方法),LoadingCache对象的get方法首先从内存中获取key对应的value,如果内存中不存在这个key则调用CacheLoader对象的load方法加载key对应的value值,加载成功后放入内存中。

    最后通过ICacheService对象和guava本地Cache对象创建IPBlackCache(防止恶意IP攻击缓存服务)对象。

    拦截器里恶意IP校验

    定义一个注解,标注在指定方法上,拦截器里会识别这个注解。

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface IPBlackLimit {
        //统计时间内最大速率
        int maxRate();
    
        //频次统计时间
        int duration();
    
        //方法名称
        String method() default StringUtils.EMPTY;
    }

    拦截器里加入ipAccess方法,校验远程IP是否为恶意攻击的IP。

    /**
    * @param method 需要校验的方法
    * @param remoteAddr 远程IP
    */
    private boolean ipAccess(Method method, String remoteAddr) {
        if (StringUtils.isBlank(remoteAddr) || !AnnotatedElementUtils.isAnnotated(method, IPBlackLimit.class)) {
            return true;
        }
        IPBlackLimit ipBlackLimit = AnnotatedElementUtils.getMergedAnnotation(method, IPBlackLimit.class);
        try {
            String ip = remoteAddr.split(",")[0].trim();
            String cacheKey = "cipb_" + (StringUtils.isBlank(ipBlackLimit.method()) ? ip : String.format("%s_%s", ip, ipBlackLimit.method()));
    
            String beginAccessTime = (String) ipBlackCache.get(cacheKey);
            if (StringUtils.isNotBlank(beginAccessTime)) {
                LocalDateTime beginTime = LocalDateTime.parse(beginAccessTime, DateTimeFormatter.ISO_LOCAL_DATE_TIME), endTime = LocalDateTime.now();
                Duration duration = Duration.between(beginTime, endTime);
                if (duration.getSeconds() >= limitConstants.getIpBlackExpire()) {
                    ipBlackCache.getLocalCache().invalidate(cacheKey);
                    return true;
                } else {
                    return false;
                }
            }
    
            boolean access = ipBlackCache.ipAccess(cacheKey, ipBlackLimit.maxRate(), ipBlackLimit.duration());
            if (!access) {
                ipBlackCache.removeIpAccess(cacheKey);
                String curTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                ipBlackCache.put(cacheKey, curTime, limitConstants.getIpBlackExpire());
            }
            return access;
        } catch (Exception e) {
            LOGGER.error(String.format("method=%sï¼remoteAddr=%s, ip access check error.", method.getName(), remoteAddr), e);
            return true;
        }
    }

    remoteAddr取的是X-Forwarded-For对应的值。利用remoteAddr构造cacheKey参数,通过IPBlackCache判断cacheKey是否存在。

    如果是cacheKey存在的请求,判断黑名单IP限制是否已经到达有效期,如果已经超过有效期则清除本地缓存和分布式缓存的cacheKey,请求合法;如果没有超过有效期则请求非法。

    否则是cacheKey不存在的请求,使用IPBlackCache对象的ipAccess方法统计一定时间内的访问频次,如果频次超过最大限制,表明是非法请求IP,需要往IPBlackCache对象写入“cacheKey=当前时间”。

    四、总结

    本文的两种方案都使用redis incr命令,如果不是特殊业务场景,redis的key要指定过期时间,严格来讲需要保证incr和expire两个命令的原子性,所以使用lua脚本方式。如果没有那么严格,完全可以先setex(设置key,value,过期时间),然后再incr(注:incr不会更新key的有效期)。本文的设计方案仅供参考,并不能应用于所有的业务场景。

    底部签名.png

     

    展开全文
  • 大概就是感觉某些web应用在某些场合下要求一定的安全措施,这也算是安全审计的一种方法,可能是在应用运行过程中检测到某些IP被高访问服务器,或者经过某种手段(如大数据分析)得知,这些IP有可能再恶意攻击,...

    JavaWeb项目限制IP访问

    这其实是一个类似IP地址的黑白名单问题,客户端IP地址在黑名单的就禁止访问,不在的就正常访问;

    提出这样一个问题,大概就是感觉某些web应用在某些场合下要求一定的安全措施,这也算是安全审计的一种方法,可能是在应用运行过程中检测到某些IP被高访问服务器,或者经过某种手段(如大数据分析)得知,这些IP有可能再恶意攻击,so最简单的方法就是禁止这些IP访问,因此也就提出这样一个问题来了。

    有两种方式解决这个问题,第一就是配置tomcat服务器,将非法地址拒绝掉,第二就是再程序中引入黑名单;
    第一种方法,简单只需配置几步即可,不过灵活性很差,第二种就需要编码了,但是可操作的自由度大。

    Tomcat配置IP访问限制与允许(server.xml)

    server.xml配置文件,在

    <Engine name="Catalina" defaultHost="localhost">
    <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="" deny="10.50.200.38,10.50.100.49"/>
    

    注: 拒绝10.50.200.38与10.50.100.49IP地址对Tomcat服务器的访问,其它允许.
    其功用类似于 Apache httpd中基于目录的Allow/Deny指令。

    属性:className 意义:Java类名;必须是org.apache.catalina.valves.RemoteHostValveorg.apache.catalina.valves.RemoteAddrValve

    属性:allow 意义:以逗号分隔的IP地址。这些字符串返回为常规表达式样式,因此,如果录入IP地址,一定要确信把“.”用反斜线(“\”)进行转义,如127\.0\.0\.1

    属性:deny 意义:以逗号分隔的IP地址。如allow属性那样,这些字符串由常规表达式组成

    如果未指定allow模式,则会拒绝符合deny属性的模式,但允许其他模式。类似地,如果未指定deny模式,则会允许符合allow属性的模式,但会拒绝其他样式。

    JavaWeb—过滤器的使用–禁止IP登陆

    在实际的应用中,我们会遇到这样的情况,需要对某些Ip进行访问限制,不让非法的Ip访问应用系统。只有合法的Ip才能可以继续访问!

    1. 定义一个过滤器,专门用户过滤指定的ip地址禁止或者允许访问
    package filter;
    
    /**
     * 过滤IP的过滤器
     */
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class FilterIP implements Filter {
    
    	 protected String fip = "";// 要过滤的IP
    	 protected FilterConfig fcon = null;// 过滤器配置对象
    
    	 @Override
    	 public void destroy() {
    		System.out.println("FilterIP 过滤器销毁");
    		this.fcon = null;
    	 }
    
    	 /**
    	  * 执行过滤方法
    	  * 
    	  * @author admin
    	  * @param request
    	  *            请求对象
    	  * @param response
    	  *            响应对象
    	  * @param chain
    	  *            过滤器对象
    	  */
    	 @Override
    	 public void doFilter(ServletRequest request, ServletResponse response,
    	   FilterChain chain) throws IOException, ServletException {
    		System.out.println("FilterIP 过滤器执行过滤方法");
    		response.setContentType("text/html");
    		response.setCharacterEncoding("gb2312");
    		// 得到请求的IP地址 和要过滤的Ip地址进行对比
    		String ip = request.getRemoteAddr();
    		if (fip.equals(ip)) {
    			// 对方就是要过滤的对象 不能访问
    			String path = "error.jsp";
    			RequestDispatcher desc = request.getRequestDispatcher(path);
    			desc.forward(request, response);
    		} else {
    			// 不是 就将过滤器加到过滤链
    			chain.doFilter(request, response);
    		}
    	 }
    
    	@Override//初始化
    	public void init(FilterConfig config) throws ServletException {
    		System.out.println("FilterIP 过滤器初始化");
    		this.fcon = config;
    		fip = fcon.getInitParameter("FilteredIP");//[^1]
    		if (fip == null) {
    			fip = "";
    		}
    		System.out.println("要过滤的IP地址为:" + fip);
    	}
    
    }
    
    1. 定义成功访问jsp页面和失败页面

    success.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    <html>  
        <head>  
            <title>欢迎登陆</title>  
        </head>  
        <body>  
            <center>  
                <font size = 4>欢迎登陆javaWeb服务器</font><!-- 成功访问输出语句 -->  
            </center>  
        </body>  
    </html>  
    

    error.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    <html>  
        <head>  
            <title>错误报告</title>  
        </head>  
        <body>  
            <%  
                out.print("<center><font size = 4>对不起,您的IP不能登陆本网站!</font></center>");//被拒绝服务器Ip显示信息  
            %>  
        </body>  
    </html> 
    
    1. 配置过滤器的web.xml
    <!-- 配置过滤器 尽可能把过滤器配置到web.xml最上面 -->  
      <filter>  
        <filter-name>FilterIP</filter-name>  
        <filter-class>filter.FilterIP</filter-class>  
        <init-param>  
        <param-name>FilteredIP</param-name>   
        <param-value>127.0.0.1</param-value><!-- 要过滤的Ip  127.0.0.1为本地 -->  
        </init-param>  
      </filter>  
      <filter-mapping>  
        <filter-name>FilterIP</filter-name>  
        <url-pattern>/*</url-pattern>  
      </filter-mapping>  
    

    展开全文
  • java web项目如何限制ip访问地址

    千次阅读 2018-12-21 09:28:13
    大概就是感觉某些web应用在某些场合下要求一定的安全措施,这也算是安全审计的一种方法,可能是在应用运行过程中检测到某些IP被高访问服务器,或者经过某种手段(如大数据分析)得知,这些IP有可能再恶意攻击,...

    JavaWeb项目限制IP访问
    这其实是一个类似IP地址的黑白名单问题,客户端IP地址在黑名单的就禁止访问,不在的就正常访问;

    提出这样一个问题,大概就是感觉某些web应用在某些场合下要求一定的安全措施,这也算是安全审计的一种方法,可能是在应用运行过程中检测到某些IP被高访问服务器,或者经过某种手段(如大数据分析)得知,这些IP有可能再恶意攻击,so最简单的方法就是禁止这些IP访问,因此也就提出这样一个问题来了。

    有两种方式解决这个问题,第一就是配置tomcat服务器,将非法地址拒绝掉,第二就是再程序中引入黑名单;
    第一种方法,简单只需配置几步即可,不过灵活性很差,第二种就需要编码了,但是可操作的自由度大。


    Tomcat配置IP访问限制与允许(server.xml)


    <Engine name="Catalina" defaultHost="localhost">
    <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="" deny="10.50.200.38,10.50.100.49"/>
    
    

    注: 拒绝10.50.200.38与10.50.100.49IP地址对Tomcat服务器的访问,其它允许.
    其功用类似于 Apache httpd中基于目录的Allow/Deny指令。

    属性:className 意义:Java类名;必须是org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve

    属性:allow 意义:以逗号分隔的IP地址。这些字符串返回为常规表达式样式,因此,如果录入IP地址,一定要确信把“.”用反斜线(“\”)进行转义,如127.0.0.1

    属性:deny 意义:以逗号分隔的IP地址。如allow属性那样,这些字符串由常规表达式组成

    如果未指定allow模式,则会拒绝符合deny属性的模式,但允许其他模式。类似地,如果未指定deny模式,则会允许符合allow属性的模式,但会拒绝其他样式。

    JavaWeb—过滤器的使用–禁止IP登陆

    在实际的应用中,我们会遇到这样的情况,需要对某些Ip进行访问限制,不让非法的Ip访问应用系统。只有合法的Ip才能可以继续访问!

    定义一个过滤器,专门用户过滤指定的ip地址禁止或者允许访问

    package filter;
    
    /**
     * 过滤IP的过滤器
     */
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class FilterIP implements Filter {
    
         protected String fip = "";// 要过滤的IP
         protected FilterConfig fcon = null;// 过滤器配置对象
    
         @Override
         public void destroy() {
            System.out.println("FilterIP 过滤器销毁");
            this.fcon = null;
         }
    
         /**
          * 执行过滤方法
          * 
          * @author admin
          * @param request
          *            请求对象
          * @param response
          *            响应对象
          * @param chain
          *            过滤器对象
          */
         @Override
         public void doFilter(ServletRequest request, ServletResponse response,
           FilterChain chain) throws IOException, ServletException {
            System.out.println("FilterIP 过滤器执行过滤方法");
            response.setContentType("text/html");
            response.setCharacterEncoding("gb2312");
            // 得到请求的IP地址 和要过滤的Ip地址进行对比
            String ip = request.getRemoteAddr();
            if (fip.equals(ip)) {
                // 对方就是要过滤的对象 不能访问
                String path = "error.jsp";
                RequestDispatcher desc = request.getRequestDispatcher(path);
                desc.forward(request, response);
            } else {
                // 不是 就将过滤器加到过滤链
                chain.doFilter(request, response);
            }
         }
    
        @Override//初始化
        public void init(FilterConfig config) throws ServletException {
            System.out.println("FilterIP 过滤器初始化");
            this.fcon = config;
            fip = fcon.getInitParameter("fip");
            if (fip == null) {
                fip = "";
            }
            System.out.println("要过滤的IP地址为:" + fip);
        }
    
    }
    
    
    配置过滤器的web.xml
    
    <!-- 配置过滤器 尽可能把过滤器配置到web.xml最上面 -->  
      <filter>  
        <filter-name>FilterIP</filter-name>  
        <filter-class>filter.FilterIP</filter-class>  
        <init-param>  
        <param-name>FilteredIP</param-name>   
        <param-value>127.0.0.1</param-value><!-- 要过滤的Ip  127.0.0.1为本地 -->  
        </init-param>  
      </filter>  
      <filter-mapping>  
        <filter-name>FilterIP</filter-name>  
        <url-pattern>/*</url-pattern>  
      </filter-mapping>  
    
    
    
    
    
    
    
    
    //获取用户ip
    
    
    
    /**
    	 * 获得用户远程地址
    	 */
    	public static String getRemoteAddr(HttpServletRequest request){
    		String remoteAddr = request.getHeader("X-Real-IP");
            if (isNotBlank(remoteAddr)) {
            	remoteAddr = request.getHeader("X-Forwarded-For");
            }else if (isNotBlank(remoteAddr)) {
            	remoteAddr = request.getHeader("Proxy-Client-IP");
            }else if (isNotBlank(remoteAddr)) {
            	remoteAddr = request.getHeader("WL-Proxy-Client-IP");
            }
            return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
    	}
    
    
    
    展开全文
  • 1.攻击者可以通过直接访问IP绕过CDN、云WAF等云防护措施 2. 攻击者可以将恶意域名解析至服务器IP地址进行仿站,或导致服务器IP因解析恶意域名被查封。 3. 攻击者可以通过修改host头注入恶意代码至页面当中。 方案:...

    不禁用风险:
    1.攻击者可以通过直接访问IP绕过CDN、云WAF等云防护措施
    2. 攻击者可以将恶意域名解析至服务器IP地址进行仿站,或导致服务器IP因解析恶意域名被查封。
    3. 攻击者可以通过修改host头注入恶意代码至页面当中。

    方案:

    配置WEB服务器,限制只能通过本地服务器解析的域名访问服务器。

    方案一 apache:(亲测)

    修改\conf\httpd.conf文件,将如下配置放置在httpd.conf的最后

    <VirtualHost *:80>  #(*:80 匹配所有)
            ServerName 192.168.0.1 #(网站公网IP)    
            <Location />
            	Order Allow,Deny  
            	Deny from all
            </Location>
    </VirtualHost>
    <VirtualHost *:80>
            DocumentRoot "/www/chuai" #(资源所在位置)    
            ServerName www.chuai.com #(网站首页) 
    </VirtualHost>
    
    

    重启Apache即可

    方案二 nginx:

    修改nginx.conf 在目标server添加检测规则,参考以下配置:
    (if部分)

    server {        
    		server_name  192.168.0.1;(网站公网IP)        
    		listen       8888;          
    		if ($http_Host !~*^192.168.0.1:8888$){         
    			return 403;         
    		}        
    		include /etc/nginx/default.d/*.conf;         
    		location / {        
    			root /www/chuai;        	
    			index index.php index.html index.htm;        
    		} 
    	} 
    
    展开全文
  • 实现:iptables+ipset,只允许中国IP访问本机,也就实现了封禁国外IP的效果。 优点:匹配迅速,免去iptables单链匹配。 具体操作如下: #安装ipset: RedHat:yum install ipset Debian:apt-ge...
  • 1.攻击者可以通过直接访问IP绕过CDN、云WAF等云防护措施 2. 攻击者可以将恶意域名解析至服务器IP地址进行仿站,或导致服务器IP因解析恶意域名被查封。 3. 攻击者可以通过修改host头注入恶意代码至页面当中。 检测...
  • 今天有蝉知建站系统的客户反映,他的站点在用谷歌浏览器访问时提示“您要访问的网站包含恶意软件”,而是用其他的浏览器访问显示正常,红通通的页面并未让用户感到一丝喜庆。 问题原因: 出现这个问题的原因有很...
  • SpringBoot 防止接口恶意多次请求

    千次阅读 2019-11-14 17:07:22
    刚写代码不就,还不能做深层次安全措施,今天研究了一下基本的防止接口多次恶意请求的方法。 思路 1:设置同一IP,一个时间段内允许访问的最大次数 2:记录所有IP单位时间内访问的次数 3:将所有被限制IP存到...
  • 本文主要分享作阿里云搭建LNMP环境及实现PHP自定义网站IP访问,同时详细介绍走过的坑,还发了朋友圈求助大家,再次感谢。本来想重新设置一个专栏分享基于阿里云的PHP网站搭建,但考虑到搞安全的也会面临各种靶场及...
  • 开放API 防止恶意调用纪实 简介:我们公司网站属于知识产权+...刚开始发现是我们采取的应对措施是:将该请求IP加入到黑名单,禁止该用户继续访问我们的系统。半天之后我们发现用户更换了一个ip又继续刷。很明显,...
  • 通过独立ip访问 ,那么虚拟主机绑定域名与不绑定是没有什么区别的, 任何一个人就可以用他的域名恶意解析到你的站点 。比如你正在做优化的一个网站,并且排名不错,如果遇到恶意竞争者,他可能会用几个域名甚至更多...
  • 恶意代码分析实战

    千次阅读 2014-05-28 13:29:14
    恶意代码分析实战(最权威的恶意代码分析指南,理论实践分析并重,业内人手一册的宝典) 【美】Michael Sikorski(迈克尔.斯科尔斯基), Andrew Honig(安德鲁.哈尼克)著  诸葛建伟 姜辉 张光凯 译 ISBN 978-7-...
  • htaccess屏蔽ip访问 。 当你再次用镜像网址访问你的网站的时候就会报403错误了,现在百度即使收录了这个网址对你的网站也不会产生任何影响. 3.反制措施 为了给这个镜像网站小小的“反击”,我决定把...
  • 问题: 网址:...hl=zh-Hans&rd=1 谷歌官方的解决办法: ...让您的网站不再显示此消息 ...除非此类网站的网站站长采取相应措施,否则我们不会移除“此网站可能会损害您...
  • 前文分享了传统的恶意代码检测技术,包括恶意代码检测的对象和策略、特征值检测技术、校验和检测技术、启发式扫描技术、虚拟机检测技术和主动防御技术。这篇文章将介绍基于机器学习的恶意代码检测技术,主要参考郑...
  • 第十四章 恶意代码的网络特征 1.网络应对措施。 网络行为的基本属性包括IP地址,TCP端口,以及流量内容等,网络和安全 设备可以利用它们,来提供网络应对措施。根据IP地址和端口,防火墙和路由器可以限制对 网络的...
  • 本篇文章,作者将分享两篇论文,机器学习是如何运用到恶意代码攻击中的,并谈谈自己的理解,后续深入研究尝试分享相关实验,目前还是小白一只。基础性文章,希望对初学者有帮助,大神请飘过,谢谢各位看官!
  • 在使用Python进行爬虫处理时,会遇到网站拥有反爬机制,在频繁的访问同一个网站时,网站服务器会防止网站遭到恶意攻击导致服务器崩溃而进行保护措施,也就是所谓我们常见的封IP手段,所以我们在进行爬虫过程中可以...
  • IP-Guard功能介绍

    千次阅读 2019-01-28 10:23:28
    IP-guard基于系统管理思想和安全实践经验,全面考虑可能造成信息破坏及外泄的各个方面,保护企业信息不被人为外泄、非法盗取、恶意篡改,帮助企业对信息安全进行系统规划及管理。IP-guard 通过灵活有力的管理,在...
  • 本文主要结合作者的《系统安全前沿》作业,相关论文及绿盟李东宏老师的博客,从产业界和学术界分别详细讲解恶意代码攻击溯源的相关知识。在学术界方面,用类似于综述来介绍攻击追踪溯源的不同方法;在产业界方面,...
  • 刚写代码不就,还不能做深层次安全措施,今天研究了一下基本的防止接口多次恶意请求的方法。 思路 1:设置同一IP,一个时间段内允许访问的最大次数 2:记录所有IP单位时间内访问的次数 3:将所有被限制IP存到...
  • 这篇文章将带大家学习安天科技集团首席架构师肖新光老师(Seak)的分享,介绍恶意代码与APT攻击中的武器,包括A2PT的攻击武器、普通APT组织的自研恶意代码、商用恶意代码、无恶意代码作业、开源和免费工具等。...
  • TCP/IP层次安全性

    千次阅读 2019-09-25 14:22:53
    在不同层次,可增加不同安全策略和措施。如在传输层提供安全套接层服务SSL和其继任者传输层安全TLS,是为网络通信提供安全及数据完整性的一种安全协议,在网络层提供虚拟专用网VPN技术等。TCP/IP网络安全技术层次...
  • 一个半月之前,广州易虎发布过一篇《悲惨,网站被恶意刷流量》,介绍了易虎互联遭遇到恶意同行的恶意刷流量时的一些... 从恶意刷流量的类型来分,大概可以分为两种,一种是少IP多PV,另一种是多IP多PV.  一、少IP多PV
  • IP地址申请

    千次阅读 2019-02-28 09:04:32
    大学校园网IP 地址由网络中心统一负责总体规划、分配和管理,网络中心负责校园网IP地址的日常维护工作,包括用户申请IP地址的审批、IP地址和网卡地址的绑定、IP地址的监管和网络故障检测、IP地址池的维护等。...
  • 应用题(送分题) ...采用一种设备能够对服务器提供以下保护措施:发送到服务器群的数据包将被进行过滤检测,如果检测到恶意数据包时,系统发出警报并阻断攻击,这种设施是:IPS 探测一台主机到另一台主机数据包
  • 从CNCERT主页上抠下来的恶意...并通过与境外域名注册商和国际安全组织的协作机制,对 155 个境内外参与传播网络病毒或仿冒网站的恶意域名或服务器主机 IP 采取了处置措施。” 这里只是收集 版权什么的还是归它CNCERT吧
  • 分析恶意Windows程序

    2019-03-24 16:24:36
    多数恶意代码运行在Windows上,因此对Windows变成概念的深刻理解会帮助我们识别出恶意代码在主机上感染的迹象,本章会介绍一些恶意代码使用Windows功能的独特方式,并且会讨论恶意代码是如何使用内核模式来实现额外...
  • 服务与质量保障措施 一 网站运行安全保障措施 1网站服务器和其他计算机之间设置防火墙 硬件防火墙正在采购中 , 做好安全策略 , 拒绝外来的恶意攻击保障网站正常运行 2在网站的服务器及工作站上均安装了相应的防病毒...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,474
精华内容 4,989
关键字:

恶意ip访问措施