Netty-如何生存DDO



我正在使用Netty 4.1作为MMORPG游戏的Nio套接字服务器。多年来,它运行良好,但最近我们遭受了DDOS攻击。我已经战斗了很长时间,但是目前,我对如何改进它没有任何想法。Ddoser正在启动来自世界各地成千上万IP的新联系。在网络级别上将其切割很难,因为攻击看起来与普通玩家非常相似。与对HTTP服务器的攻击相比,攻击不是很大,但足以使我们的游戏崩溃。

我如何使用Netty:

public void startServer() {
    bossGroup = new NioEventLoopGroup(1);
    workerGroup = new NioEventLoopGroup();
    try {
        int timeout = (Settings.SOCKET_TIMEOUT*1000);
        bootstrap = new ServerBootstrap();
        int bufferSize = 65536;
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.SO_TIMEOUT, timeout)
                .childOption(ChannelOption.SO_RCVBUF, bufferSize)
                .childOption(ChannelOption.SO_SNDBUF, bufferSize)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new CustomInitalizer(sslCtx));

        ChannelFuture bind = bootstrap.bind(DrServerAdmin.port);
        bossChannel = bind.sync();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

Intalizer:

public class CustomInitalizer extends ChannelInitializer<SocketChannel> {
    public static  DefaultEventExecutorGroup normalGroup = new DefaultEventExecutorGroup(16);
    public static  DefaultEventExecutorGroup loginGroup = new DefaultEventExecutorGroup(8);
    public static  DefaultEventExecutorGroup commandsGroup = new DefaultEventExecutorGroup(4);
    private final SslContext sslCtx;
    public CustomInitalizer(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (sslCtx != null) {
            pipeline.addLast(sslCtx.newHandler(ch.alloc()));
        }
        pipeline.addLast(new CustomFirewall()); //it is AbstractRemoteAddressFilter<InetSocketAddress>
        int limit = 32768;        
        pipeline.addLast(new DelimiterBasedFrameDecoder(limit, Delimiters.nulDelimiter()));
        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new CustomReadTimeoutHandler(Settings.SOCKET_TIMEOUT));
        int id = DrServerNetty.getDrServer().getIdClient();
        CustomHandler normalHandler = new CustomHandler();
        FlashClientNetty client = new FlashClientNetty(normalHandler,id);
        normalHandler.setClient(client);
        pipeline.addLast(normalGroup,"normalHandler",normalHandler);
        CustomLoginHandler loginHandler = new CustomLoginHandler(client);
        pipeline.addLast(loginGroup,"loginHandler",loginHandler);

        CustomCommandsHandler commandsHandler = new CustomCommandsHandler(loginHandler.client);
        pipeline.addLast(commandsGroup, "commandsHandler", commandsHandler);
    }
}

我正在使用5组:

  • Bootstrap BossGroup-对于新连接
  • Bootstrap WorkerGroup-用于传递消息
  • 常规组 - 对于大多数消息
  • 弹圈 - 用于重登录过程
  • 命令组 - 对于某些重型逻辑

我正在监视新连接和消息的数量,因此我可以立即找出是否有攻击。在攻击期间,我不再接受新的连接:我在自定义防火墙(ApptractremoteadDressfilter)中返回False。

protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) throws Exception {
    if(ddosDetected())
       return false;
    else
        return true;
}

,但即使那样,我马上就会放弃新的连接,我的工作组被超载。为工人组(所有其他组都很好)的pendingTask正在增长,这会导致普通玩家的沟通越来越长,最后,他们被Socket_Timeouts踢了。我不确定为什么会发生。在普通服务器使用期间,最繁忙的组是登录和普通组。在网络级别的服务器很好 - 它仅使用其带宽限制的约10%。在攻击期间,CPU和RAM使用情况也不是很高。但是经过几分钟的攻击,我所有的球员都被踢出了比赛,无法再连接了。

有什么更好的方法可以立即删除所有传入的连接并保护已连接的Aready连接的用户?

我认为您需要通过iptables在内核级别"修复此操作"。否则,您只能在这种情况下接受它听起来不够好后关闭连接。

相关内容

  • 没有找到相关文章

最新更新