I have a simple DOS attack implementation that opens ssl connections, keeps them opened forever and sends a lot of data through them. My Spring app RAM was consumed very fast. I implemented this protection:
@Bean
public NettyServerCustomizer floodProtectionServerCustomizer() {
return httpServer -> httpServer
.option(ChannelOption.SO_RCVBUF, BYTES)
.option(ChannelOption.SO_SNDBUF, BYTES)
.doOnConnection(conn -> {
conn.channel()
.pipeline()
.addFirst(new ReadTimeoutHandler(5, TimeUnit.SECONDS));
conn.channel()
.pipeline()
.addFirst(new FloodDetector());
});
}
@ChannelHandler.Sharable
static class FloodDetector extends ChannelInboundHandlerAdapter {
private final LongAdder bytesRead = new LongAdder();
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof ByteBuf buf) {
bytesRead.add(buf.readableBytes());
if (bytesRead.sum() > BYTES) {
ctx.channel().close();
ReferenceCountUtil.release(msg);
return;
}
}
ctx.fireChannelRead(msg);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
bytesRead.reset();
ctx.fireChannelInactive();
}
}
It worked, but I'm not sure this is a very good approach. Is it a good solution?