Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让客户端等待javajax-RS服务以防止DOS_Java_Web Services_Rest_Jax Rs_Ddos - Fatal编程技术网

如何让客户端等待javajax-RS服务以防止DOS

如何让客户端等待javajax-RS服务以防止DOS,java,web-services,rest,jax-rs,ddos,Java,Web Services,Rest,Jax Rs,Ddos,我遇到了一个web服务问题,用户试图通过在随机ID上循环来猜测应用程序ID 坏的请求来自随机IP,所以我不能仅仅禁止它们的IP(除非我动态地这样做,但我还没有研究) 目前,当我检测到一个客户端进行了10次错误的应用程序ID尝试时,我将其放在我的应用程序的阻止列表中,并拒绝该IP的进一步请求 我希望尽可能减少服务器所需的工作量,因为坏客户端将继续发送1000个请求,即使它们被拒绝。我知道有动态防火墙解决方案,但现在我想在我的应用程序中实现一些简单的解决方案。目前我正在睡眠5秒钟以减少呼叫,但我想做

我遇到了一个web服务问题,用户试图通过在随机ID上循环来猜测应用程序ID

坏的请求来自随机IP,所以我不能仅仅禁止它们的IP(除非我动态地这样做,但我还没有研究)

目前,当我检测到一个客户端进行了10次错误的应用程序ID尝试时,我将其放在我的应用程序的阻止列表中,并拒绝该IP的进一步请求

我希望尽可能减少服务器所需的工作量,因为坏客户端将继续发送1000个请求,即使它们被拒绝。我知道有动态防火墙解决方案,但现在我想在我的应用程序中实现一些简单的解决方案。目前我正在睡眠5秒钟以减少呼叫,但我想做的只是不向客户端发送响应,因此它必须超时

有人知道如何在Java和JAX-RS中做到这一点吗

我的服务就像

@Path("/api")
public class MyServer {

@GET
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Path("/my-request")
public String myRequest(String type,
    @Context HttpServletRequest requestContext,
    @Context HttpServletResponse response) {
...
}
见:

有许多可能的解决方案,我想到了您给出的两种可能的解决方案:

1) 使用已支持限制请求的转发代理。我个人已经使用过,并且可以推荐它,部分原因是它设置简单。相关速率限制配置:


2) 用于让检测到的恶意请求超时。可以直接处理Sane请求。但是要小心后果,无论哪种方式,这种方法都会消耗服务器上的资源

我没有试过这个。。。。这只是在黑暗中拍摄的一张照片,所以要谨慎对待。因此,问题是,一旦您检测到可疑的内容并将IP置于块模式,您就不想在该请求上浪费更多资源,也不想让它们浪费时间超时。但如果抛出异常,框架将做出响应。中断当前线程怎么样?您可以通过
Thread.currentThread().interrupt()实现这一点。希望处理请求的Java容器能够检查中断状态。它可能不会那样做。我知道我看到过IO相关类没有处理请求,因为设置了中断标志


编辑:如果中断线程不起作用,也可以尝试抛出InterruptedException。就我所知,在Servlet规范中没有这样的机制。由于JAX-RS实现使用servlet(至少是Jersey和Resteasy),所以在Java中没有实现这一点的标准方法

使用aynchronous JAX-RS的想法比Thread.sleep(5000)
要好,但它仍然会使用一些资源,只是以后处理请求的一种方式,而不是忽略对always的请求。

您正在查找JAX-RS支持的请求。包含一些如何实现对请求的异步响应的示例

对于异步响应,负责响应请求的线程将被释放,以便在请求完成之前处理另一个请求。此功能通过添加带有
@Suspended
注释的参数激活。此外,您还需要注册一个专门的服务器,该服务器负责在给定的超时后唤醒您的请求,如本例所示:

@Path("/api")
public class MyServer {

  private ScheduledExecutorService scheduler = ...;

  @GET
  @Consumes(MediaType.APPLICATION_XML)
  @Produces(MediaType.APPLICATION_XML)
  @Path("/my-request")
  public String myRequest(String type,
                          @Context HttpServletRequest requestContext,
                          @Context HttpServletResponse response,
                          @Suspended AsyncResponse asyncResponse) {
    scheduler.schedule(new Runnable() {
      @Override
      public void run() {
        asyncResponse.resume(...)
      }
    }, 5, TimeUnit.SECOND);
  }
}
这样,线程就不会在5秒钟的等待时间内被阻塞,从而有机会同时处理其他请求

JAX-RS不提供一种在没有应答的情况下完全丢弃请求的方法。您需要保持连接打开以产生超时,如果您终止连接,将通知用户终止。最好不要回答异步请求,但这仍然会消耗一些资源。如果要避免这种情况,就必须在JAX-RS之外解决这个问题,例如,通过将请求代理给另一台服务器


一种方法是,您可以使用错误代码回答代理的恶意请求,并为此类请求设置非常大的重试限制。

我建议将IP拒绝逻辑从REST移动到普通HTTP筛选器:

@WebFilter(urlPatterns = "/*", asyncSupported = true)
@WebListener
public class HttpFilter implements Filter {

    @Override
   public void init(FilterConfig filterConfig) throws ServletException {   }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if(denyIP(servletRequest.getRemoteAddr())) {
            AsyncContext asyncContext = servletRequest.startAsync();
            asyncContext.setTimeout(100000);
        }else{
           filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {   }

    private boolean denyIP(String address){
         //todo
         return true;
    }

}
对于应用服务器来说更便宜:无需XML/JSON反序列化,无需调用REST类。您可能还注意到,我从未调用
asyncContext.start
。我检查了Wildfly 8.2服务器。在这种情况下,Wildfly不会对每个请求使用线程。我发送了很多请求,但线程数量是恒定的

PS

尝试通过在随机ID上循环来猜测应用程序ID


这不是DOS攻击。这是暴力攻击

您可以尝试Tomcat 3.0支持的asyncContext。 此功能将web请求处理程序和处理器解耦。在您的情况下,接受请求的线程必须等待/睡眠超过配置的超时时间。让同一个线程睡眠如此长的时间将使它们挨饿,并将极大地影响服务器的性能。因此,异步处理是正确的方法

我将asyncContext与Java单线程执行器一起使用 这对我很有效。我有类似的商业案例,我不得不模仿我的申请

请参阅此文件以了解实施情况


单线程执行器不会占用资源,它是这个用例的理想选择。

我曾经通过创建TCP/IP隧道应用程序解决了类似的问题。

它是一个小型应用程序,侦听外部端口(例如http端口80)。在正常情况下,所有接收到的呼叫都会被接受,从而创建专用的套接字对象这些单独的套接字然后调用真正的(隐藏的)Web服务器,它运行在同一个物理服务器上,或者本地网络中的任何服务器上

隧道本身类似于调度器,但也可以充当负载平衡器。它可以是多功能的

事情是这样的