将HTTP请求重定向到netty中的HTTPS

时间:2019-03-21 05:42:05

标签: elasticsearch netty

我正在修改elasticsearch代码以配置没有x-pack和反向代理的HTTPS。 我在netty4HttpServerTransport文件中修改了initchannel()方法,https工作正常,但我想将http重定向到https。 代码是

char[] password = "your5663".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(new FileInputStream("C:/OpenSSL-Win64/bin/keystore1.jks"),password);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, password);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sslContext  = SSLContext.getInstance("TLSv1.3");
        sslContext .init( kmf.getKeyManagers(), tm, null);
        SSLEngine sslengine = sslContext .createSSLEngine();

        sslengine.setUseClientMode(false);

        String[] DEFAULT_PROTOCOLS = { "TLSv1", "TLSv1.1", "TLSv1.2","TLSv1.3" };
        String[] DEFAULT_CIPHERS = {"TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA"};

        sslengine.setEnabledProtocols(DEFAULT_PROTOCOLS);
        sslengine.setEnabledCipherSuites(DEFAULT_CIPHERS);

        SslHandler sslHandler = new SslHandler(sslengine);
        ch.pipeline().addLast("ssl", sslHandler);      
        ch.pipeline().addAfter("ssl","handshake",new StringEventHandler());

如何在此代码中使http重定向到https。

2 个答案:

答案 0 :(得分:1)

重定向在有效负载(http)级别上起作用,而不在ssl传输级别上起作用。您将需要同时监听协议(http和https)以及在http通道上使用重定向状态代码进行响应。长话短说-您可以在代码中没有直接的位置。

通常,代理服务器用于此任务。我不确定您是否可以在elasticsearch中做到这一点,可以尝试配置过滤器Servlet来检查协议重定向的响应。这可能会有所帮助https://github.com/elastic/elasticsearch-transport-wares

另一个事实-如果重定向是针对服务客户端(而不是基于浏览器的ui),则客户端可能/将认为重定向响应是错误响应。根据您的环境-也许您仅可以公开ssl端点(无需重定向),客户端就必须遵守

答案 1 :(得分:0)

Netty为此内置了一个处理程序OptionalSslHandler

将其放在管道的最前面,它将检测消息是否已加密。如果是这样,则该消息将被发送到普通SSL管道,否则,您可以指定其他地方发送该消息,例如301重定向到https。

您可以使用此Netty版本,也可以制作自己的处理程序来执行类似的操作。

但是,要使用Netty版本,您将需要稍微重构以产生 Netty SslContext io.netty.handler.ssl.SslContext而不是SSLEngine。

类似这样的东西:

char[] password = "your5663".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("C:/OpenSSL-Win64/bin/keystore1.jks"),password);

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);

SslContext sslContext = SslContextBuilder.forServer(keyManagerFactory).build();

ch.pipeline().addLast("ssl", sslHandler);

// this is an imaginary handler you create that sends HTTP a 301 to HTTPS
// non-SSL can be detected easily because there is no SslHandler on this channel
ch.pipeline().addLast("redirectHandler", new RedirectHandler()); 

ch.pipeline().addLast("handshake",new StringEventHandler());