2016-10-25 10 views
0

Netty 4.2ソケット通信コードをssl(自己署名証明書)で実行しています。SSLを使用したNettyサーバー接続の呼び出し後のクライアント接続の破棄

問題: クライアントがSSLを使用してサーバーに接続しようとすると、サーバーはすぐに接続を切断します。サーバーはすぐにchannelUnregistered()メソッドをトリガーします。

私が気づいたのは、サーバーが始動した後、クライアントの接続が維持され、うまく動作することです。しかし、クライアントが切断され、サーバーに再び接続しようとすると、すぐに接続が切断されます。

SSLを使用しないと、問題なく正常に動作します。

クライアントコード:

public Channel initializeNettySocket() 
{ 
    group = new NioEventLoopGroup(); 
    try 
    { 
     ClientAdapterInitializer clientAdapterInitializer = null; 
     if (ServerSettings.isUseSSL()) 
     { 
      //    SSLEngine engine = SSLContextFactory.getClientContext().createSSLEngine(); 
      SSLEngine engine = SSLContext.getDefault().createSSLEngine(host,port); 
      engine.setUseClientMode(true); 
      clientAdapterInitializer = new ClientAdapterInitializer(engine); 
     } 
     else 
     { 
      clientAdapterInitializer = new ClientAdapterInitializer(); 
     } 

     Bootstrap bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(clientAdapterInitializer); 

     channel = bootstrap.connect(host,port).sync().channel(); 
     Thread.sleep(3000); 

     setChannel(channel); 
    } 
    catch (Exception e) 
    { 
     System.out.println(e.getMessage()); 
     e.printStackTrace(); 
    } 
    return channel; 
} 

    public class ClientAdapterInitializer extends ChannelInitializer<SocketChannel> 

{

private SSLEngine sslCtx = null; 

public ClientAdapterInitializer(SSLEngine sslCtx) 
{ 
    this.sslCtx = sslCtx; 
} 

public ClientAdapterInitializer() 
{ 
} 

@Override 
protected void initChannel(SocketChannel channel) throws Exception 
{ 
    ChannelPipeline pipeline = channel.pipeline(); 

    if (ServerSettings.isUseSSL()) 
    { 
     // Add SSL handler first to encrypt and decrypt everything. 
     // In this example, we use a bogus certificate in the server side 
     // and accept any invalid certificates in the client side. 
     // You will need something more complicated to identify both 
     // and server in the real world. 
     //pipeline.addLast(sslCtx.newHandler(ch.alloc(), SecureChatClient.HOST, SecureChatClient.PORT)); 
     pipeline.addLast(new SslHandler(sslCtx)); 
    } 
    pipeline.addLast("decoder", new StringDecoder()); 
    pipeline.addLast("encoder", new StringEncoder()); 
    pipeline.addLast("handler", new ClientAdapterHandler()); 

} 

サーバ側コード

public class ServerAdapterInitializer extends ChannelInitializer<SocketChannel> 

{

private SSLEngine sslEngine; 

public ServerAdapterInitializer(SSLEngine sslEngine) 
{ 
    this.sslEngine = sslEngine; 
} 

public ServerAdapterInitializer() 
{ 
} 

@Override 
protected void initChannel(SocketChannel channel) throws Exception 
{ 
    ChannelPipeline pipeline = channel.pipeline(); 
    if (sslEngine != null) 
    { 
     pipeline.addLast(new SslHandler(sslEngine)); 
    } 
    Listeners.getInstance().getAllListeners().size(); 
    RTReceiverAdapterHandler rtReceiverAdapterHandler = new RTReceiverAdapterHandler(); 
    pipeline.addLast("idleStateHandler", new IdleStateHandler(0, 0, 10)); // add 
                      // with 
                      // name 
    pipeline.addLast("decoder", new MyStringDecoder(rtReceiverAdapterHandler)); 
    pipeline.addLast("encoder", new StringEncoder()); 

    pipeline.addLast("handler", rtReceiverAdapterHandler); 
} 

}

public class RTReceiverAdapterHandler extends ChannelInboundHandlerAdapter 
{ 
@Override 
public void channelActive(ChannelHandlerContext ctx) throws Exception 
{ 
    if (ServerSettings.isUseSSL()) 
    { 
     // Once session is secured, send a greeting and register the channel 
     // to the global channel 
     // list so the channel received the messages from others. 
     ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() 
     { 
      @Override 
      public void operationComplete(Future<Channel> future) throws Exception 
      { 
       ctx.writeAndFlush("Welcome!\n"); 
       ctx.writeAndFlush("Your session is protected by " + ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite() 
         + " cipher suite.\n"); 
       channels.add(ctx.channel()); 
      } 
     }); 
    } 
    else 
    { 
     super.channelActive(ctx); 
    } 
} 

}

+0

次のオプションを使用してデバッグをログに記録できます。System.setProperty( "javax.net.debug"、 "ssl"); System.setProperty( "ssl.debug"、 "true"); –

+0

OK、これを試します –

+0

有効なプロトコルと暗号を有効にしました。私が得ていた問題はなくなった。しかし、今度は、クライアントと接続したサーバーは数秒待って接続を閉じ、クライアントで例外 - > _nioEventLoopGroup-2-1、致命的なエラー:80:ピアのclose_notifyを受信する前に受信を閉じた:切り捨ての可能性がある_ –

答えて

0

問題は、すべてのコードではなかったです。私たちはアプリケーションの前にSSLで設定されたnginx Webサーバーを持っています。 nginxのssl_ciphers AES256 + EECDHのこのエントリ:AES256 + EDH:!aNULL; ' Nettyサーバーへのアクセスを許可していない犯人でした。

私は上記のngnixのエントリにコメントしましたが、私の問題は解決しました。

関連する問題