netty实战入门——安全保证

rpc 安全保证

空闲检测(应用层keep alive)

server端超过10s没收到client信息,连接断开
client超过5s没有写事件发生时,则发送 keep alive,防止连接被断开

sever:

@Slf4j
public class ServerIdleCheckHandler extends IdleStateHandler {
    public ServerIdleCheckHandler() {
        super(10, 0, 0, TimeUnit.SECONDS);
    }

    @Override
    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
        if (IdleStateEvent.READER_IDLE_STATE_EVENT.equals(evt)) {
            log.info(" No reading for more than 10 seconds, connection closed");
            ctx.close();
        }
        super.channelIdle(ctx, evt);
    }
}

client:

触发writeIdleEvent

public class ClientIdleCheckHandler extends IdleStateHandler {
    public ClientIdleCheckHandler() {
        super(0, 5, 0);
    }
}

处理writeIdleEvent,发送keepalive

@Sharable
@Slf4j
public class KeepaliveHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (IdleStateEvent.WRITER_IDLE_STATE_EVENT.equals(evt)) {
            log.info("write idle happen, so need to send keepalive");
            KeepaliveOperation keepaliveOperation = new KeepaliveOperation();
            RequestMessage requestMessage = new RequestMessage(IdUtil.nextId(), keepaliveOperation);
            ctx.writeAndFlush(requestMessage);
        }
        super.userEventTriggered(ctx, evt);
    }
}

添加到pipeLine

pipeline.addLast("idleChecker", new ClientIdleCheckHandler()); // 顺序不能变
pipeline.addLast("keepaliveHandler", keepaliveHandler);        // 保证ClientIdleCheckHandler触发的事件能被keepaliveHandler捕获

黑白名单

IpSubnetFilterRule ipSubnetFilterRule = new IpSubnetFilterRule("127.0.0.1", 8, IpFilterRuleType.REJECT);
IpSubnetFilter ipSubnetFilter = new IpSubnetFilter(ipSubnetFilterRule);

自定义授权

@Slf4j
@Sharable
public class AuthHandler extends SimpleChannelInboundHandler<RequestMessage> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RequestMessage msg) throws Exception {
        Operation messageBody = msg.getMessageBody();
        try {
            if (messageBody instanceof AuthOperation) {
                AuthOperation authOperation = AuthOperation.class.cast(messageBody);
                AuthOperationResult result = authOperation.execute();
                if (result.isPassAuth()) {
                    log.info("successfully pass auth");
                } else {
                    log.error("fail to pass auth");
                    ctx.close();
                }
            }
        } finally {
            ctx.pipeline().remove(this);
        }
    }
}

SSL

生成证书

SelfSignedCertificate certificate = new SelfSignedCertificate();
SslContext sslContext = SslContextBuilder.forServer(certificate.certificate(), certificate.privateKey()).build();

添加sslHandler到pipline

SslHandler sslHandler = sslContext.newHandler(ch.alloc());
pipeline.addLast("sslHandler", sslHandler);

版权声明:本文为PBomb原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。