chhsiao90 / nitmproxy

Proxy server based on netty
MIT License
151 stars 67 forks source link

Proxy does not warn on a certificate error at https://nitreb-forms.theismailiusa.org #103

Open abbasvalliani opened 2 years ago

abbasvalliani commented 2 years ago

Proxy is unable to process https://nitreb-forms.theismailiusa.org. The certificate looks okay but the issue is broader than NITMProxy. But the hope was the proxy should issue the same "ignore warning" that it does for e.g. with an expired certificate.

chhsiao90 commented 2 years ago

It looks like a network issue. I'm not able to connect the website with my Taiwan ip, but I can connect the website with an US ip.

abbasvalliani commented 2 years ago

Even when in the US, I am getting the following error.

14:29:51.213 [nioEventLoopGroup-3-5] DEBUG c.g.c.nitmproxy.NitmProxyInitializer - [Client (kubernetes.docker.internal:65079)] <=> [PROXY] : connection init
14:29:51.214 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - [Client (kubernetes.docker.internal:65079)] <=> [PROXY] : handlerAdded
14:29:51.214 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - [Client (kubernetes.docker.internal:65079)] <=> [PROXY] : handlerRemoved
14:29:51.218 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - SSL detection with true
14:29:51.218 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - Client SNI lookup with nitreb-forms.theismailiusa.org
14:29:51.219 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsBackendHandler - [Client (kubernetes.docker.internal:65079)] <=> [Server (nitreb-forms.theismailiusa.org:443)] : handlerAdded
14:29:51.220 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - Client ALPN lookup with [h2, http/1.1]
14:29:51.316 [nioEventLoopGroup-3-5] WARN  i.n.h.s.ApplicationProtocolNegotiationHandler - [id: 0x06da64c0, L:0.0.0.0/0.0.0.0:65080] TLS handshake failed:
javax.net.ssl.SSLHandshakeException: received handshake warning: unrecognized_name
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:337)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:293)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:284)
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:272)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
    at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:681)
    at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:636)
    at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:454)
    at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:433)
    at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:637)
    at io.netty.handler.ssl.JdkSslEngine.unwrap(JdkSslEngine.java:92)
    at io.netty.handler.ssl.JdkAlpnSslEngine.unwrap(JdkAlpnSslEngine.java:143)
    at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:282)
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1387)
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1282)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1329)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)
14:29:51.316 [nioEventLoopGroup-3-5] DEBUG c.g.c.n.h.p.tls.TlsFrontendHandler - ALPN negotiate failed with javax.net.ssl.SSLHandshakeException: received handshake warning: unrecognized_name
abbasvalliani commented 2 years ago

The website has some certificate related error. See below when replicated via JAVA directly.

import java.net.*;
import java.io.*;
import javax.net.ssl.*;

/*
 * This example demostrates how to use a SSLSocket as client to
 * send a HTTP request and get response from an HTTPS server.
 * It assumes that the client is not behind a firewall
 */

public class SSLSocketClient {

    public static void main(String[] args) throws Exception {
    try {
        SSLSocketFactory factory =
                      (SSLSocketFactory)SSLSocketFactory.getDefault();
        SSLSocket socket =
                  (SSLSocket)factory.createSocket("nitreb-forms.theismailiusa.org", 443);

        /*
             * send http request
             *
             * Before any application data is sent or received, the
             * SSL socket will do SSL handshaking first to set up
             * the security attributes.
             *
             * SSL handshaking can be initiated by either flushing data
             * down the pipe, or by starting the handshaking by hand.
             *
             * Handshaking is started manually in this example because
             * PrintWriter catches all IOExceptions (including
             * SSLExceptions), sets an internal error flag, and then
             * returns without rethrowing the exception.
             *
             * Unfortunately, this means any error messages are lost,
             * which caused lots of confusion for others using this
             * code.  The only way to tell there was an error is to call
             * PrintWriter.checkError().
             */
        socket.startHandshake();

        PrintWriter out = new PrintWriter(
                          new BufferedWriter(
        new OutputStreamWriter(
                       socket.getOutputStream())));

        out.println("GET / HTTP/1.0");
        out.println();
        out.flush();

        /*
             * Make sure there were no surprises
             */
        if (out.checkError())
        System.out.println(
                   "SSLSocketClient:  java.io.PrintWriter error");

        /* read response */
        BufferedReader in = new BufferedReader(
        new InputStreamReader(
                      socket.getInputStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null)
        System.out.println(inputLine);

        in.close();
        out.close();
        socket.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}
abbasvalliani commented 2 years ago
java SSLSocketClient
javax.net.ssl.SSLHandshakeException: received handshake warning: unrecognized_name
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:337)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:293)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:284)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:272)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1408)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1314)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
        at SSLSocketClient.main(SSLSocketClient.java:40)
abbasvalliani commented 2 years ago

@chhsiao90 would appreciate your feedback on this. Thanks.

chhsiao90 commented 2 years ago

I can connect the website with nitmproxy running 1.8.0_292.

Can you provide the java version you are running?

abbasvalliani commented 2 years ago

I am using Java 11.

Sent from my handheld device

On Oct 13, 2021, at 9:17 PM, Chun-Han, Hsiao @.***> wrote:

 I can connect the website with nitmproxy running 1.8.0_292.

Can you provide the java version you are running?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

chhsiao90 commented 2 years ago

I think the issue was caused by the SNI extension.

It looks like you are using the JDS built-in SSL library instead of openssl, which is not supporting SNI extension and cause the failure.

The netty-tcnative must be included as a dependency while deploying the ntimproxy.

abbasvalliani commented 2 years ago

I believe the link below summarizes it well. The server is misconfigured and SNIExtension caused the failure. I believe we need SNI for transparent proxy and I am assuming it is okay to leave this for now. But rather than just closing the connection, perhaps the ability to show an error page would have been preferable. Perhaps the same approach as unsafe sites with an error template the user can configure?

SSL handshake alert: unrecognized_name error since upgrade to Java 1.7.0

chhsiao90 commented 2 years ago

Sounds good to provide an error page, I will check if it's possible to have one.

Netty supports SNI extension by including the netty-tcnative in the classpath, so netty will use different SSLEngine implementation instead of JDK one.