Search in sources :

Example 6 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.

the class Http2MultiplexTransportTest method testFireChannelReadAfterHandshakeSuccess.

private void testFireChannelReadAfterHandshakeSuccess(SslProvider provider) throws Exception {
    SelfSignedCertificate ssc = null;
    try {
        ssc = new SelfSignedCertificate();
        final SslContext serverCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(eventLoopGroup);
        sb.channel(NioServerSocketChannel.class);
        sb.childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(serverCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_1_1) {

                    @Override
                    protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
                        ctx.pipeline().addLast(new Http2FrameCodecBuilder(true).build());
                        ctx.pipeline().addLast(new Http2MultiplexHandler(new ChannelInboundHandlerAdapter() {

                            @Override
                            public void channelRead(final ChannelHandlerContext ctx, Object msg) {
                                if (msg instanceof Http2HeadersFrame && ((Http2HeadersFrame) msg).isEndStream()) {
                                    ctx.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false)).addListener(new ChannelFutureListener() {

                                        @Override
                                        public void operationComplete(ChannelFuture future) {
                                            ctx.writeAndFlush(new DefaultHttp2DataFrame(Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII), true));
                                        }
                                    });
                                }
                                ReferenceCountUtil.release(msg);
                            }
                        }));
                    }
                });
            }
        });
        serverChannel = sb.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
        final SslContext clientCtx = SslContextBuilder.forClient().sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
        final CountDownLatch latch = new CountDownLatch(1);
        Bootstrap bs = new Bootstrap();
        bs.group(eventLoopGroup);
        bs.channel(NioSocketChannel.class);
        bs.handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(clientCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new Http2FrameCodecBuilder(false).build());
                ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                    @Override
                    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                        if (evt instanceof SslHandshakeCompletionEvent) {
                            SslHandshakeCompletionEvent handshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
                            if (handshakeCompletionEvent.isSuccess()) {
                                Http2StreamChannelBootstrap h2Bootstrap = new Http2StreamChannelBootstrap(clientChannel);
                                h2Bootstrap.handler(new ChannelInboundHandlerAdapter() {

                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) {
                                        if (msg instanceof Http2DataFrame && ((Http2DataFrame) msg).isEndStream()) {
                                            latch.countDown();
                                        }
                                        ReferenceCountUtil.release(msg);
                                    }
                                });
                                h2Bootstrap.open().addListener(new FutureListener<Channel>() {

                                    @Override
                                    public void operationComplete(Future<Channel> future) {
                                        if (future.isSuccess()) {
                                            future.getNow().writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), true));
                                        }
                                    }
                                });
                            }
                        }
                    }
                });
            }
        });
        clientChannel = bs.connect(serverChannel.localAddress()).sync().channel();
        latch.await();
    } finally {
        if (ssc != null) {
            ssc.delete();
        }
    }
}
Also used : SelfSignedCertificate(io.netty.handler.ssl.util.SelfSignedCertificate) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) InetSocketAddress(java.net.InetSocketAddress) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ApplicationProtocolConfig(io.netty.handler.ssl.ApplicationProtocolConfig) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) SslContext(io.netty.handler.ssl.SslContext) ChannelFuture(io.netty.channel.ChannelFuture) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Example 7 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.

the class NettyBlockHoundIntegrationTest method testHandshake.

private static void testHandshake(SslContext sslClientCtx, SslHandler clientSslHandler, SslHandler serverSslHandler) throws Exception {
    EventLoopGroup group = new NioEventLoopGroup();
    Channel sc = null;
    Channel cc = null;
    try {
        sc = new ServerBootstrap().group(group).channel(NioServerSocketChannel.class).childHandler(serverSslHandler).bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
        ChannelFuture future = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(clientSslHandler).addLast(new ChannelInboundHandlerAdapter() {

                    @Override
                    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                        if (evt instanceof SslHandshakeCompletionEvent && ((SslHandshakeCompletionEvent) evt).cause() != null) {
                            ((SslHandshakeCompletionEvent) evt).cause().printStackTrace();
                        }
                        ctx.fireUserEventTriggered(evt);
                    }
                });
            }
        }).connect(sc.localAddress());
        cc = future.syncUninterruptibly().channel();
        clientSslHandler.handshakeFuture().await().sync();
        serverSslHandler.handshakeFuture().await().sync();
    } finally {
        if (cc != null) {
            cc.close().syncUninterruptibly();
        }
        if (sc != null) {
            sc.close().syncUninterruptibly();
        }
        group.shutdownGracefully();
        ReferenceCountUtil.release(sslClientCtx);
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) InetSocketAddress(java.net.InetSocketAddress) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) NioDatagramChannel(io.netty.channel.socket.nio.NioDatagramChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ChannelInitializer(io.netty.channel.ChannelInitializer) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Example 8 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.

the class NettyBlockHoundIntegrationTest method testSslHandlerWrapAllowsBlockingCalls.

@Test
public void testSslHandlerWrapAllowsBlockingCalls() throws Exception {
    final SslContext sslClientCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).sslProvider(SslProvider.JDK).build();
    final SslHandler sslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT);
    final EventLoopGroup group = new NioEventLoopGroup();
    final CountDownLatch activeLatch = new CountDownLatch(1);
    final AtomicReference<Throwable> error = new AtomicReference<>();
    Channel sc = null;
    Channel cc = null;
    try {
        sc = new ServerBootstrap().group(group).channel(NioServerSocketChannel.class).childHandler(new ChannelInboundHandlerAdapter()).bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
        cc = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(sslHandler);
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                    @Override
                    public void channelActive(ChannelHandlerContext ctx) {
                        activeLatch.countDown();
                    }

                    @Override
                    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                        if (evt instanceof SslHandshakeCompletionEvent && ((SslHandshakeCompletionEvent) evt).cause() != null) {
                            Throwable cause = ((SslHandshakeCompletionEvent) evt).cause();
                            cause.printStackTrace();
                            error.set(cause);
                        }
                        ctx.fireUserEventTriggered(evt);
                    }
                });
            }
        }).connect(sc.localAddress()).addListener((ChannelFutureListener) future -> future.channel().writeAndFlush(wrappedBuffer(new byte[] { 1, 2, 3, 4 }))).syncUninterruptibly().channel();
        assertTrue(activeLatch.await(5, TimeUnit.SECONDS));
        assertNull(error.get());
    } finally {
        if (cc != null) {
            cc.close().syncUninterruptibly();
        }
        if (sc != null) {
            sc.close().syncUninterruptibly();
        }
        group.shutdownGracefully();
        ReferenceCountUtil.release(sslClientCtx);
    }
}
Also used : NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) InetSocketAddress(java.net.InetSocketAddress) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) NioDatagramChannel(io.netty.channel.socket.nio.NioDatagramChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) SslHandler(io.netty.handler.ssl.SslHandler) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ChannelInitializer(io.netty.channel.ChannelInitializer) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) SslContext(io.netty.handler.ssl.SslContext) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 9 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project zuul by Netflix.

the class OriginResponseReceiver method userEventTriggered.

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    if (evt instanceof CompleteEvent) {
        final CompleteReason reason = ((CompleteEvent) evt).getReason();
        if ((reason != SESSION_COMPLETE) && (edgeProxy != null)) {
            LOG.error("Origin request completed with reason other than COMPLETE: {}, {}", reason.name(), ChannelUtils.channelInfoForLogging(ctx.channel()));
            final ZuulException ze = new ZuulException("CompleteEvent", reason.name(), true);
            edgeProxy.errorFromOrigin(ze);
        }
        // See channelWrite() where these vars are first set onto the channel.
        try {
            super.userEventTriggered(ctx, evt);
        } finally {
            postCompleteHook(ctx, evt);
        }
    } else if (evt instanceof SslHandshakeCompletionEvent && !((SslHandshakeCompletionEvent) evt).isSuccess()) {
        Throwable cause = ((SslHandshakeCompletionEvent) evt).cause();
        ctx.channel().attr(SSL_HANDSHAKE_UNSUCCESS_FROM_ORIGIN_THROWABLE).set(cause);
    } else if (evt instanceof IdleStateEvent) {
        if (edgeProxy != null) {
            LOG.error("Origin request received IDLE event: {}", ChannelUtils.channelInfoForLogging(ctx.channel()));
            edgeProxy.errorFromOrigin(new OutboundException(READ_TIMEOUT, edgeProxy.getRequestAttempts()));
        }
        super.userEventTriggered(ctx, evt);
    } else {
        super.userEventTriggered(ctx, evt);
    }
}
Also used : IdleStateEvent(io.netty.handler.timeout.IdleStateEvent) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) CompleteEvent(com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteEvent) ZuulException(com.netflix.zuul.exception.ZuulException) CompleteReason(com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteReason) OutboundException(com.netflix.zuul.exception.OutboundException)

Example 10 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project zuul by Netflix.

the class SslHandshakeInfoHandler method userEventTriggered.

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    if (evt instanceof SslHandshakeCompletionEvent) {
        try {
            SslHandshakeCompletionEvent sslEvent = (SslHandshakeCompletionEvent) evt;
            if (sslEvent.isSuccess()) {
                CurrentPassport.fromChannel(ctx.channel()).add(PassportState.SERVER_CH_SSL_HANDSHAKE_COMPLETE);
                SslHandler sslhandler = ctx.channel().pipeline().get(SslHandler.class);
                SSLSession session = sslhandler.engine().getSession();
                ClientAuth clientAuth = whichClientAuthEnum(sslhandler);
                Certificate serverCert = null;
                X509Certificate peerCert = null;
                if ((clientAuth == ClientAuth.REQUIRE || clientAuth == ClientAuth.OPTIONAL) && session.getPeerCertificates() != null && session.getPeerCertificates().length > 0) {
                    peerCert = (X509Certificate) session.getPeerCertificates()[0];
                }
                if (session.getLocalCertificates() != null && session.getLocalCertificates().length > 0) {
                    serverCert = session.getLocalCertificates()[0];
                }
                SslHandshakeInfo info = new SslHandshakeInfo(isSSlFromIntermediary, session.getProtocol(), session.getCipherSuite(), clientAuth, serverCert, peerCert);
                ctx.channel().attr(ATTR_SSL_INFO).set(info);
                // Metrics.
                incrementCounters(sslEvent, info);
                logger.debug("Successful SSL Handshake: {}", info);
            } else {
                String clientIP = ctx.channel().attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).get();
                Throwable cause = sslEvent.cause();
                PassportState passportState = CurrentPassport.fromChannel(ctx.channel()).getState();
                if (cause instanceof ClosedChannelException && (PassportState.SERVER_CH_INACTIVE.equals(passportState) || PassportState.SERVER_CH_IDLE_TIMEOUT.equals(passportState))) {
                    // Either client closed the connection without/before having completed a handshake, or
                    // the connection idle timed-out before handshake.
                    // NOTE: we were seeing a lot of these in prod and can repro by just telnetting to port and then closing terminal
                    // without sending anything.
                    // So don't treat these as SSL handshake failures.
                    logger.debug("Client closed connection or it idle timed-out without doing an ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else if (cause instanceof SSLException && cause.getMessage().contains("handshake timed out")) {
                    logger.debug("Client timed-out doing the ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else if (cause instanceof SSLException && cause.getMessage().contains("failure when writing TLS control frames")) {
                    // This can happen if the ClientHello is sent followed  by a RST packet, before we can respond.
                    logger.debug("Client terminated handshake early." + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else {
                    String msg = "Unsuccessful SSL Handshake: " + sslEvent + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()) + ", error = " + cause;
                    if (cause instanceof ClosedChannelException) {
                        logger.debug(msg);
                    } else {
                        logger.debug(msg, cause);
                    }
                    incrementCounters(sslEvent, null);
                }
            }
        } catch (Throwable e) {
            logger.warn("Error getting the SSL handshake info.", e);
        } finally {
            // Now remove this handler from the pipeline as no longer needed once the ssl handshake has completed.
            ctx.pipeline().remove(this);
        }
    } else if (evt instanceof SslCloseCompletionEvent) {
    // TODO - increment a separate metric for this event?
    } else if (evt instanceof SniCompletionEvent) {
        logger.debug("SNI Parsing Complete: {}", evt);
        SniCompletionEvent sniCompletionEvent = (SniCompletionEvent) evt;
        if (sniCompletionEvent.isSuccess()) {
            spectatorRegistry.counter("zuul.sni.parse.success").increment();
        } else {
            Throwable cause = sniCompletionEvent.cause();
            spectatorRegistry.counter("zuul.sni.parse.failure", "cause", cause != null ? cause.getMessage() : "UNKNOWN").increment();
        }
    }
    super.userEventTriggered(ctx, evt);
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SniCompletionEvent(io.netty.handler.ssl.SniCompletionEvent) SSLSession(javax.net.ssl.SSLSession) ClientAuth(io.netty.handler.ssl.ClientAuth) SSLException(javax.net.ssl.SSLException) SslHandler(io.netty.handler.ssl.SslHandler) X509Certificate(java.security.cert.X509Certificate) PassportState(com.netflix.zuul.passport.PassportState) SslHandshakeInfo(com.netflix.netty.common.ssl.SslHandshakeInfo) SslCloseCompletionEvent(io.netty.handler.ssl.SslCloseCompletionEvent) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Aggregations

SslHandshakeCompletionEvent (io.netty.handler.ssl.SslHandshakeCompletionEvent)16 SslHandler (io.netty.handler.ssl.SslHandler)8 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)7 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)7 Channel (io.netty.channel.Channel)5 Bootstrap (io.netty.bootstrap.Bootstrap)4 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)4 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)4 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)4 SslContext (io.netty.handler.ssl.SslContext)4 InetSocketAddress (java.net.InetSocketAddress)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ChannelFuture (io.netty.channel.ChannelFuture)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)2 ChannelInitializer (io.netty.channel.ChannelInitializer)2 EventLoopGroup (io.netty.channel.EventLoopGroup)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2 NioDatagramChannel (io.netty.channel.socket.nio.NioDatagramChannel)2 ApplicationProtocolConfig (io.netty.handler.ssl.ApplicationProtocolConfig)2 SniCompletionEvent (io.netty.handler.ssl.SniCompletionEvent)2