JVM 使用下划线“_"作为 SNI 服务器名称的一部分崩溃 [英] JVM crashes using underline '_' as part of SNI server name

查看:89
本文介绍了JVM 使用下划线“_"作为 SNI 服务器名称的一部分崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Netty 4.1.14.Final 用于我的应用程序框架.我想实现服务器可以在客户端使用 netty-tcnative-boringssl-static 请求时检查 SNI 信息.

I'm using Netty 4.1.14.Final for my application's framework. I want to implement that the server can check the SNI information when the clients request using netty-tcnative-boringssl-static.

但是当我将 -servername 指定为 svc.v1 时,我的应用程序崩溃了一次,我收到了这条消息:

But my application crashes once as I specify the -servername as svc.v1, and I got this message:

java: ../ssl/handshake_server.c:541: negotiate_version: Assertion `!ssl->s3->have_version' failed.

使用 OpenSSL 命令:

with the OpenSSL command:

openssl s_client -cert service.crt -key service.key -CAfile root_ca.pem -connect 127.0.0.1:8080 -servername svc.v1_1
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 210 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1532336403
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

但是,如果我将 -servername 指定为 svc.v1,而没有下划线 _,则效果很好.

However, it works well if I specify the -servername as svc.v1, without the underline _.

// define ssl provider
private static final SslProvider SSL_PROVIDER = SslProvider.OPENSSL;

// factory method for creating ssl context
public SslContext serverCtx(InputStream certificate, InputStream privateKey) {
        try {
            return SslContextBuilder.forServer(certificate, privateKey)
                                    .sslProvider(SSL_PROVIDER)                                         
                                    .clientAuth(ClientAuth.REQUIRE)
                               .trustManager(TwoWayTrustManagerFactory.INSTANCE)
                                    .build();
        } catch (Exception e) {
            throw new RuntimeException("failed to create ssl context", e);
        }
}

// SNI Matcher implementation
@Slf4j
public class MySNIMatcher extends SNIMatcher {

    private final byte[] hostIdentifier;

    public MySNIMatcher(Identifier hostIdentifier) {
        super(0);
        this.hostIdentifier = hostIdentifier.idDistKey().getBytes(StandardCharsets.US_ASCII);
    }

    @Override
    public boolean matches(SNIServerName sniServerName) {
        return Arrays.equals(sniServerName.getEncoded(), hostIdentifier);
    }
}

// Netty bootstrap
bootstrap.childHandler(new ChannelInitializer<Channel>() {
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (conf.logEnable())
            pipeline.addLast("logging", new LoggingHandler());

        if (conf.sslEnable()) {
            // conf.sslCtx() will actually use serverCtx() to create context
            SSLEngine engine = conf.sslCtx().newEngine(ch.alloc());
            SSLParameters s = engine.getSSLParameters();
            s.setSNIMatchers(new MySNIMatcher(...));
            s.setEndpointIdentificationAlgorithm("HTTPS");
            engine.setSSLParameters(s);
            pipeline.addLast("ssl", new SslHandler(engine, true));
        }

        codec(pipeline);

        int idleTimeout = (int) TimeUnit.MILLISECONDS.toSeconds(conf.idleTimeout());
        if (0 < idleTimeout)
            pipeline.addLast("idle", new IdleStateHandler(0, 0, idleTimeout));

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

版本:netty -> 4.1.14.Finalnetty-tcnative-boringssl-static -> 2.0.5.Final

Version: netty -> 4.1.14.Final netty-tcnative-boringssl-static -> 2.0.5.Final

推荐答案

主机名不允许包含下划线字符,根据原始 RFC 952,并由 RFC 1123 修改.以下来自 Wikipedia page for 主机名.

Hostnames are not allowed to contain an underscore character, per the original RFC 952, and modified by RFC 1123. The following is from the Wikipedia page for Hostname.

协议的 Internet 标准(征求意见)要求组件主机名标签只能包含 ASCII 字母a"到z"(不区分大小写)、数字0"到9",和减号 ('-').RFC 952 中主机名的原始规范,要求标签不能以数字开头或以减号,并且不得以减号结尾.但是,随后的规范(RFC 1123)允许主机名标签以数字开头.不允许使用其他符号、标点符号或空格.

The Internet standards (Requests for Comments) for protocols mandate that component hostname labels may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9', and the minus sign ('-'). The original specification of hostnames in RFC 952, mandated that labels could not start with a digit or with a minus sign, and must not end with a minus sign. However, a subsequent specification (RFC 1123) permitted hostname labels to start with digits. No other symbols, punctuation characters, or white space are permitted.

这篇关于JVM 使用下划线“_"作为 SNI 服务器名称的一部分崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆